Blindspot

Methodology

How the Hidden Concentration Score is computed.

Methodology — coming with full transparency at launch.

Blindspot is built on the Fama-French 3-factor model + Momentum + Quality, with GICS sector and region overlays. Detailed methodology, including factor definitions, finding-threshold logic, and version history, will be published here before public launch.

Questions? methodology@blindspot.fyi

Home · Privacy · Security · Contact

Factor basis — raw OLS vs residualized

Every analyze run computes a portfolio’s macro tilt — six numbers that describe how your portfolio leans across the major market forces. This section explains how those numbers are computed in v1, what they mean, and what limitation to keep in mind when reading them.

The six macro factors

We regress your portfolio’s daily total returns against six macro-factor return series:

  • SPY — broad US equity (S&P 500)
  • QQQ — large-cap US tech (Nasdaq-100)
  • TLT — long Treasuries (interest-rate / duration exposure)
  • UUP — US dollar (DXY proxy)
  • BTC-USD — crypto markets (Bitcoin spot)
  • DBC — broad commodities (Bloomberg Commodity Index proxy)

We picked these six because together they span the macro forces that move most retail portfolios: equity risk, tech-style risk, rate risk, currency risk, crypto-market risk, and commodity/inflation risk. They’re not the only factors that matter — but they’re the ones most relevant to the holdings retail users actually own.

The regression

For each portfolio, we estimate:

r_p = β_SPY · r_SPY
    + β_QQQ · r_QQQ
    + β_TLT · r_TLT
    + β_UUP · r_UUP
    + β_BTC · r_BTC
    + β_DBC · r_DBC
    + ε

Where r_p is your portfolio’s daily total return over the lookback window (90 trading days by default), each r_x is the daily total return of the corresponding factor over the same window, and ε is the unexplained residual. We fit the coefficients by ordinary least squares (OLS) — minimizing the sum of squared residuals — and report each beta as the portfolio’s exposure to that factor.

Why we call this “raw OLS”

The six factors are not statistically independent. The S&P 500 and the Nasdaq-100 share roughly 85% of their daily variance. The Bloomberg Commodity Index and TLT are weakly negatively correlated through inflation expectations. When inputs are correlated, OLS does what statistics tells it to: it splits a single underlying exposure across whichever correlated factors fit the data best.

In practice, this means a portfolio that is functionally one bet on US tech might come back with both β_SPY = 0.6 and β_QQQ = 0.4 — not because there are two distinct exposures, but because OLS distributes the shared variance across both factors. Reading those betas as if they were two separate exposures will overstate the portfolio’s total market exposure.

We call this “raw OLS” because we report the coefficients exactly as OLS produces them — no orthogonalization, no residualization, no Gram-Schmidt cleanup. What you see is what the regression said.

How to read raw-OLS betas

Directional, not additive. Use the betas to understand which factors your portfolio is exposed to and in which direction — but don’t sum them and treat the sum as “total exposure.” Two correlated factors with β = 0.5 each don’t mean a combined β = 1.0; they likely mean a single underlying beta that OLS split.

Sign matters more than magnitude when factors are correlated. A negative β_TLT tells you something true (your portfolio moves opposite long Treasuries). A specific number like β_TLT = -0.32 is less precise than the sign because the rate factor borrows variance with equity factors that share the same underlying macro story.

The macro-tilt descriptor on the analyze page uses these betas. When you see “Less US stock market exposure, more dollar exposure,” that’s the direction-of-change in the dominant raw-OLS betas — not a literal sum.

Regression diagnostics

Every analyze response includes a few diagnostic numbers alongside the betas:

  • — how much of your portfolio’s daily-return variance the regression explained. R² above ~0.85 means the six factors capture most of what moved your portfolio; below ~0.5 means there’s a lot of variance the model isn’t picking up (often: international exposure, factor combinations we don’t currently track, or low data history).
  • Residual volatility — the daily standard deviation of the part the regression couldn’t explain. Useful as a sanity check.
  • n_obs — number of daily observations the regression used. Below ~30, treat betas with skepticism; below ~10 we suppress them entirely.

What changes in v1.1

v1.1 will introduce a residualized basis: before reporting each factor’s beta, we’ll first orthogonalize the factor inputs so that each factor’s coefficient reflects only its independent contribution. With residualization, β_SPY would capture broad-market exposure and β_QQQ would capture only the tech-specificexposure on top of that — additive in the way users expect.

Residualization is a meaningful methodology improvement that will change the numbers. When v1.1 ships, scores and component breakdowns may shift not because your portfolio changed but because the math became more accurate. We’ll communicate that change explicitly when it lands.

Until then, the live raw OLS indicator on each analyze run displays the basis that produced the numbers you’re reading.

Questions

Email methodology@blindspot.fyi for methodology questions specifically. The macro-tilt math is documented above; the choice of factors is a design decision we’re happy to defend or revise based on user feedback.

Look-through — how we see inside your ETFs

When a holding in your portfolio is itself a fund (an ETF or mutual fund), Blindspot tries to look through the wrapper and analyze the underlying securities the fund holds. This is the technical heart of the “different tickers, same risk” wedge: if you hold 25% AAPL directly and 25% SPY, your effectiveAAPL exposure isn’t 25% — it’s roughly 27%, because AAPL is around 7% of SPY. Without look-through, that hidden concentration is invisible to a ticker-level view of your portfolio.

How it works

For each fund holding in our registry, we read the fund’s most-recent published holdings, multiply each underlying position by your ETF weight × that holding’s weight in the ETF, and aggregate the result alongside your direct stock positions. If the same underlying security appears inside multiple ETFs you own (for example, AAPL in both SPY and QQQ), we sum the contributions so your effective AAPL weight reflects the full overlap.

The look-through math feeds every downstream surface that computes effective concentration: the Hidden Concentration Score, the Primary Exposure card, the Correlation Snapshot, the Portfolio Holdings table (when you hover “effective weight”), and the per-ticker contributors surfaced on each Stress Preview card.

What v1 covers

v1 covers 21 ETFs in our look-through registry. The list is deliberately constrained — coverage will only expand when we’ve verified holdings data quality for each issuer. Today’s coverage:

  • Broad US equity: SPY, VOO, IVV, VTI, QQQ
  • US sector + factor ETFs: XLK, XLF, XLE, VTV, SCHD, VYM, VDE
  • Thematic sector ETFs: PPA (aerospace & defense), IHE (US pharma), EINC (energy infrastructure income)
  • Bond + commodity wrappers (treated as single sleeves, not security-level look-through): TLT, BND, BIL, GLD
  • Inverse / short-the-market wrappers (treated as single sleeves): PSQ, SH

Status labels you may see on a holding

  • Direct security — the holding is a single stock or other non-composite security. No look-through operation applies; the security IS the underlying. This is the default and appears on no UI affordance.
  • Looked through — the holding is an ETF in our registry with fresh holdings data; the analysis decomposes the ETF into its underlying securities.
  • Not looked through — the holding is an ETF or fund that is outside our current registry. The analysis treats it as a single opaque line item at its direct weight. The pie chart and concentration math still include the holding, but the “different tickers, same risk” overlap check cannot fire against an opaque sleeve. Tagged with the inline ⓘ Not looked through indicator on the holdings table so you know to read the rest of the analysis with that caveat in mind.
  • Holdings out of date — the holding is in our registry but its underlying holdings file is more than 5 business days old. Rather than silently use stale data, we hard-fail the analysis with a clear surface that tells you which holdings are stale, when the next scrape is scheduled, and an explicit opt-in to proceed with the stale data carrying a disclosure banner.

What v1 does not cover (and why)

  • International equity ETFs (VEA, VWO, EFA, EEM, VXUS, etc.). Decomposing them is mechanically possible, but our current six-factor macro model (SPY/QQQ/TLT/UUP/BTC-USD/DBC) is US-equity-centric. Surfacing the holdings without a matching factor attribution would degrade the rest of the analytics. International coverage lands in Phase 2 with a parallel factor-model expansion.
  • Most sector ETFs beyond XLK / XLF / XLE / VDE (XLV, XLI, XLY, XLP, XLU, XLB, XLRE, XLC). Same Phase 2 story; coverage expansion alongside the factor-model expansion.
  • Most bond ETFs beyond BND / BIL / TLT (LQD, HYG, IEF, TIP, etc.). Bond ETFs require a duration + credit + sector decomposition layer that doesn’t exist today — we treat the four wrappers we do cover as single sleeves rather than synthesizing bond-level math the engine can’t yet do honestly.
  • Commodity-futures ETFs beyond GLD (USO, UNG, DBC, PDBC, SLV). Their “holdings” are derivative contracts, not securities — the look-through math doesn’t apply. We treat the GLD wrapper as a single gold-sleeve proxy and leave the rest for Phase 2 with a distinct treatment.
  • Leveraged and inverse ETFs beyond PSQ / SH (TQQQ, SQQQ, SPXL, SOXL, TMF, etc.). Daily-reset compounding makes the holdings-level decomposition mathematically meaningless over our 90-day analysis window. These are treated as opaque by design rather than decomposed.
  • Funds of funds (target-date funds, allocation ETFs that hold other ETFs). We look through one level only and document the residual. Multi-level chained look-through is on the v1.1 backlog.
  • Options, futures, and structured products — out of v1 entirely. Documented exclusion; the analysis surface flags any of these you hold so you can read the rest of the output with the exclusion in mind.

Data freshness

Holdings for the 21 covered ETFs refresh on a scheduled run that pulls each issuer’s published holdings file. If any covered holding’s data is more than five business days old at the moment you run an analysis, the analyze surface tells you which holdings are stale, when the next scheduled refresh is, and gives you the option to proceed with the stale data while carrying a disclosure banner on the rest of the analysis.

This is deliberate. The previous version of this engine silently fell back to stale holdings when a refresh failed, which meant a user could read “your tech exposure is X%” from a snapshot taken several weeks earlier without knowing the underlying composition had drifted. The staleness gate exists to prevent that silent failure mode at the cost of an extra click when staleness occurs.

What’s coming in Phase 2

Phase 2 expands look-through coverage to international equities, additional sector ETFs, bond ETFs (with a proper duration + credit + sector decomposition layer), commodity futures wrappers (with a distinct treatment that acknowledges their derivative nature), and the long tail of top retail-AUM ETFs. The factor model expands alongside the coverage so that the rest of the analytics (Macro tilt, Factor Overlap, Macro Sensitivity) remain methodologically consistent with the new holdings universe. Andrea’s Phase 1 expansion spec documents the full scope and sequencing.