About FactorsToday

A quantitative platform for factor-based stock analysis

About the Creator

FactorsToday was created by Lukasz Tomicki, Founder and Managing Partner of LRT Capital Management, an investment firm based in Austin, Texas. Founded in 2012, LRT Capital employs a proprietary systematic long-short investment strategy focused on companies with durable economic moats.

Lukasz also teaches finance at The University of Texas at Austin's McCombs School of Business and has been featured in Bloomberg, BNN Bloomberg, and Schwab Network discussing quantitative investment strategies and market analysis.

Contact: Lukasz R. Tomicki — ltomicki@lrtcapital.com

Other Projects

The Gemini Report — Investment deep dives and market analysis generated by Google Gemini AI with light human editing, exploring how artificial intelligence can enhance investment research and analysis.

Important Disclaimer

FactorsToday is provided for informational and educational purposes only. The data, analysis, and tools on this site do not constitute investment advice, recommendations, or solicitations to buy or sell any securities. Past performance does not guarantee future results. Factor exposures and model fits are statistical estimates and may not accurately represent future relationships; no guarantee is made regarding the accuracy or reliability of any particular model fit. Always conduct your own research and consult with a qualified financial advisor before making investment decisions. The creators of FactorsToday are not liable for any losses incurred from using this information.

What is Factor Investing?

Factor investing is a systematic approach to understanding and decomposing investment returns. Rather than viewing a stock's return as a single number, factor analysis breaks it down into components attributable to various systematic risk exposures—such as market risk, size, value, momentum, and others.

By understanding a stock's factor exposures, investors can:

  • Attribute Performance: Understand why a stock or portfolio performed the way it did
  • Manage Risk: Identify hidden risk concentrations and diversify more effectively
  • Build Portfolios: Construct portfolios with desired factor tilts
  • Generate Alpha: Identify stocks with attractive characteristics after controlling for known factors

Factor Construction Methodology

FactorsToday uses a rigorous quantitative methodology to construct pure factor returns. Each factor is designed to isolate a specific risk premium or market characteristic while removing exposure to other known factors. This "purification" process ensures that when you see exposure to the Value factor, it represents pure value exposure—not value mixed with market beta or size effects.

The Problem with Raw Factor Returns

Consider a simple "Value" factor constructed by going long value stocks and short growth stocks. This raw return stream will contain contamination from other factors: value stocks tend to be smaller (size effect), may have different market betas, and may have sector tilts. Without purification, you cannot cleanly attribute returns to the "value" characteristic alone.

Core Methodology: Factor Purification

Our factors undergo a rigorous multi-step purification process:

Step 1: Raw Return Calculation

We start with ETF returns or equal-weighted baskets of stocks that represent the target exposure. For example, the raw "Value" factor uses the spread between RPV (S&P 500 Pure Value ETF) and RPG (S&P 500 Pure Growth ETF). For custom factors, we create equal-weighted baskets of correlated stocks, where each stock contributes equally to the basket return.

Step 2: Weekly Resampling

Daily returns are resampled to weekly frequency (Friday close-to-close). This serves multiple purposes: it reduces microstructure noise, improves regression stability, and aligns with the typical rebalancing frequency of institutional investors. Weekly returns are computed as compounded daily returns: Rweekly = (1 + r1)(1 + r2)...(1 + r5) - 1

Step 3: Rolling Multivariate Regression

A 156-week (3-year) rolling OLS regression strips out exposure to existing factors. The regression model is:

Rbasket = α + β1RMarket + β2RSize + β3RValue + ... + ε

The rolling window allows beta estimates to adapt to changing market conditions. We use statsmodels' RollingOLS implementation for computational efficiency. If insufficient history exists (less than 156 weeks), we fall back to static OLS using all available data.

Step 4: Beta Upsampling

Weekly regression coefficients (betas) are upsampled to daily frequency using forward-fill. Friday's beta estimates are applied to the following Monday through Friday. This maintains consistency while providing daily factor returns. The betas are also backfilled at the start of the series to ensure complete coverage.

Step 5: Residual Extraction

Pure factor returns are the regression residuals—the portion of returns unexplained by other factors:

Rpure = Rbasket - (β1RMarket + β2RSize + ...)

By construction, these residuals have zero correlation with the stripping factors over the calibration window. This is the "pure" factor return that isolates the specific characteristic we're trying to measure.

Step 6: Volatility Scaling

Returns are scaled to target 10% annualized volatility. This normalization serves two purposes:

  • Comparability: All factors are on the same volatility scale, making beta coefficients directly comparable
  • Risk Management: Prevents any single factor from dominating due to inherently higher volatility

The scaling formula uses prior-day volatility to avoid look-ahead bias:

Lt = min(Target_Vol / Volt-1, 3.0)
Rscaled,t = Lt × Rpure,t

The leverage scalar L is capped at 3.0x to prevent extreme positions during low-volatility periods. Volatility is estimated using a 60-day rolling standard deviation, annualized by multiplying by √252.

Key Hyperparameters Summary

Parameter Value Rationale
Calibration Window 156 weeks 3 years captures multiple market cycles and regime changes
Target Volatility 10% annualized Standard institutional benchmark
Volatility Lookback 60 trading days ~3 months, balances responsiveness and stability
Maximum Leverage 3.0x Prevents extreme scaling in calm markets
Min Sector/Industry History 756 days ~3 years of trading data required for factor inclusion
Trading Days/Year 252 Standard market convention

Factor Types

FactorsToday constructs six categories of factors, each serving different analytical purposes. Factors are computed in a specific order to ensure proper dependency resolution—standard factors first, then dependent factors that use the standard factors for stripping, followed by sector, industry, country, and custom factors.

1. Standard Factors

Core risk factors constructed from liquid ETFs. These form the foundation of the factor model and are used to strip other factors. Each factor captures a well-documented risk premium:

Factor Construction Economic Rationale
Market IVV (S&P 500 ETF) returns Equity risk premium—compensation for bearing systematic market risk
SmallSize IJR - IVV, market-hedged Size premium—small caps historically outperform large caps
Value RPV - RPG spread Value premium—cheap stocks outperform expensive stocks
Momentum MTUM - IVV (52-week window) Momentum effect—recent winners continue winning
Quality QUAL - SPHB, hedged for market & size Quality premium—profitable, stable companies outperform
LowVolatility USMV - IVV, market-hedged Low-vol anomaly—low-risk stocks deliver higher risk-adjusted returns
CreditRisk JNK - IEF spread Credit premium—compensation for default risk
InterestRate -TLT (inverse), vol-scaled Duration risk—sensitivity to interest rate changes
OilPrice USO, vol-scaled Energy price exposure—impacts costs and revenues across sectors
GoldPrice GLD, vol-scaled Safe haven/inflation hedge exposure
VIX VIXY, vol-scaled Volatility exposure—defensive stocks have positive exposure, risk-on assets negative

2. Dependent Factors

These factors are computed after standard factors and are fully orthogonalized against all of them. This means their returns represent pure exposure to the named characteristic with zero correlation to Market, Size, Value, etc.

  • Buybacks: Buyback premium (DIVB - VYM), stripped of all standard factors. Captures the return attributable to share repurchases after controlling for other factors.
  • USDividends: US dividend exposure (VYM), fully orthogonalized. Pure dividend yield exposure independent of value, quality, or other characteristics.
  • GlobalDividends: Global dividend exposure (SDIV), fully orthogonalized. International high-yield equity exposure, purified of US factor effects.

3. Sector Factors

Broad sector-level factors derived from Select Sector SPDR ETFs (XLF, XLK, XLE, XLV, XLB, XLI, XLY, XLP, XLU, XLRE, XLC). These capture exposure to the 11 GICS sectors. The construction process:

  1. Source: Daily returns from Sector SPDR ETFs with at least 756 days (~3 years) of trading history
  2. Purification: Regressed against all standard factors using the full factor stripping methodology
  3. Result: Pure sector-specific return—the portion of sector performance not explained by broad market factors like beta, size, or value

For example, the "Sector: Technology" factor captures pure tech sector exposure at the broadest level. A stock with high exposure to this factor moves with the overall tech sector in ways not explained by its market beta or other characteristics.

Sector Factors (11 GICS Sectors)

Technology (XLK), Financial (XLF), Health Care (XLV), Consumer Discretionary (XLY), Consumer Staples (XLP), Energy (XLE), Materials (XLB), Industrial (XLI), Utilities (XLU), Real Estate (XLRE), Communication Services (XLC)

4. Industry Factors

Granular industry-level factors derived from specialized iShares and other thematic ETFs. These provide more targeted exposure than broad sector factors, capturing specific sub-industries and investment themes. The construction process is identical to sector factors: daily returns are purified against all standard factors.

Industry factors require at least 504 trading days (~2 years) of history. The full list of industry factors includes:

Technology Industries

Semiconductors (SOXX), Software (IGV), Expanded Tech (IGM), Tech Networking (IGN), Technology (IYW), Self-Driving EV Tech (IDRV), Robotics & AI (IRBO, BOTZ), Cybersecurity (HACK), Cloud Computing (SKYY, CLOU)

Healthcare Industries

Biotechnology (IBB), Medical Devices (IHI), Healthcare Providers (IHF), Healthcare (IYH), Genomics (ARKG)

Financial Industries

Broker-Dealers (IAI), Insurance (IAK, KIE), Regional Banks (IAT), Financials (IYF), Financial Services (IYG), Regional Banking (KRE), Banks (KBE), Fintech (FINX), Fintech Innovation (ARKF)

Energy & Materials Industries

Oil & Gas E&P (IEO), Oil Equipment & Services (IEZ), Energy (IYE), Clean Energy (ICLN), Basic Materials (IYM), Timber & Forestry (WOOD), Gold Miners (RING), Silver (SLV), Mining (PICK), Lithium & Battery (LIT)

Consumer Industries

Consumer Discretionary (IYC), Consumer Staples (IYK), Home Construction (ITB), Retail (XRT), Online Retail (IBUY), Food & Beverage (PBJ)

Industrial & Infrastructure

Industrials (IYJ), Transportation (IYT), Aerospace & Defense (ITA), Infrastructure (IFRA)

Real Estate, Utilities & Communications

Real Estate (IYR), Mortgage Real Estate (REM), Global REIT (REET), Telecommunications (IYZ), Utilities (IDU)

Thematic & Innovation

Innovation (ARKK), Autonomous Tech (ARKQ), Internet (ARKW)

The distinction between Sector and Industry factors is important: Sector factors capture broad exposure to major economic sectors, while Industry factors capture more specific sub-industry themes. For example, a semiconductor company will have exposure to both "Sector: Technology" (broad tech sector) and "Industry: Semiconductors" (specific chip industry).

5. Country Factors

Geographic factors derived from iShares and other country-specific ETFs. Each country factor captures pure country-specific exposure after removing all standard factor exposures (Market, Size, Value, etc.) as well as sector and industry factor exposures. This isolates the true geographic risk premium. Country factors require at least 756 trading days (~3 years) of history. Supported countries include:

42 Country Factors

Americas: Argentina (ARGT), Brazil (EWZ), Canada (EWC), Chile (ECH), Colombia (GXG), Mexico (EWW), Peru (EPU)

Europe: Austria (EWO), Belgium (EWK), Denmark (EDEN), Finland (EFNL), France (EWQ), Germany (EWG), Greece (GREK), Ireland (EIRL), Italy (EWI), Netherlands (EWN), Norway (ENOR), Poland (EPOL), Spain (EWP), Sweden (EWD), Switzerland (EWL), Turkey (TUR), United Kingdom (EWU)

Asia-Pacific: Australia (EWA), China (MCHI), India (INDA), Indonesia (EIDO), Japan (EWJ), Malaysia (EWM), New Zealand (ENZL), Philippines (EPHE), Singapore (EWS), South Korea (EWY), Taiwan (EWT), Thailand (THD), Vietnam (VNM)

Middle East: Israel (EIS), Qatar (QAT), Saudi Arabia (KSA), United Arab Emirates (UAE)

Africa: South Africa (EZA)

Each country factor captures the idiosyncratic return component specific to that nation's equity market—things like local economic conditions, political risk, currency effects, and domestic market sentiment that cannot be explained by global factors. This allows investors to understand and manage geographic risk concentrations in their portfolios. For example, a US multinational with significant operations in Brazil will show exposure to the "Country: Brazil" factor even if traded on US exchanges.

6. Custom Factors (AI-Discovered)

Thematic factors automatically discovered through correlation analysis. This innovative approach identifies groups of stocks that move together for reasons not captured by traditional factors—often representing emerging themes, supply chain relationships, or shared business characteristics.

Discovery Algorithm: Recursive Correlation Clustering

  1. Build Correlation Graph: Compute pairwise return correlations for all common stocks. Create edges between stocks with correlation ≥ 0.50 (base threshold).
  2. Find Connected Components: Use breadth-first search to identify groups of interconnected stocks.
  3. Evaluate Group Size:
    • If group has 8-30 stocks: Accept as valid custom factor
    • If group has < 8 stocks: Discard (too small for meaningful diversification)
    • If group has > 30 stocks: Recursively split at higher correlation threshold
  4. Recursive Refinement: For oversized groups, increment correlation threshold by 0.01 and repeat clustering. Continue until all groups are 8-30 stocks or threshold reaches 0.99.
  5. AI Naming: Send each group's tickers to Google's Gemini AI with the prompt: "Analyze their common industry, sector, or theme. Generate a short, catchy name (max 6 words) for this investment basket."
  6. Factor Construction: Create an equal-weighted basket of group members and apply the full factor purification methodology.

Custom Factor Discovery Parameters

Base Correlation Threshold 0.50
Maximum Correlation Threshold 0.99
Threshold Step Size 0.01
Minimum Group Size 8 stocks
Maximum Group Size 30 stocks

Example discoveries: The algorithm might identify groups like "Semiconductor Equipment" (ASML, LRCX, AMAT, KLAC...), "Streaming Media" (NFLX, SPOT, ROKU...), or "EV Supply Chain" (TSLA, LI, RIVN, LCID...). These represent thematic exposures that transcend traditional sector classifications.

Factor Equations & Replication

A key feature of our methodology is that every factor's returns can be expressed as a linear combination of tradeable instruments. The system stores "factor equations" that represent the current weights needed to replicate each factor.

The Factor Equation

Rfactor = L × Rbasket - L × β1 × RFactor1 - L × β2 × RFactor2 - ...

Where:

  • L = Leverage scalar for volatility targeting (from most recent calculation)
  • Rbasket = Return of the underlying basket (ETF or equal-weighted stocks)
  • βi = Regression coefficients from the most recent calibration window
  • RFactori = Returns of the factors being stripped out

Example: Quality Factor Equation

Quality = 1.42 × QUAL - 1.42 × SPHB - 0.28 × Market - 0.15 × SmallSize

This equation shows that to replicate the Quality factor, you would go long QUAL at 1.42x, short SPHB at 1.42x, and maintain small short positions in the Market and SmallSize factors to neutralize those exposures.

Dependency Resolution

Factor equations can reference other factors, creating dependencies. The system uses topological sorting (Kahn's algorithm) to determine the correct calculation order. Factors that only depend on tickers are computed first, followed by factors that depend on those, and so on. This ensures that when a factor equation references another factor, that factor's returns are already available.

Finding Factor Equations

The complete equation for any factor can be found on that factor's dedicated page:

  1. Navigate to the Factor History page
  2. Click on any factor name to view its detail page
  3. Click the button next to the live return to expand the equation details
  4. View the full equation with all component weights and live contribution breakdowns

Alternatively, use the /api/factor-equation/:factorNameEncoded endpoint to programmatically fetch the equation data. See the API Documentation for details.

Stock Factor Analysis

For individual stocks, FactorsToday computes factor exposures (betas) using ElasticNet regression with cross-validation. For each stock, the system also calculates R² and Adjusted R² to measure how well the factor model explains that stock's returns. This approach provides several advantages over ordinary least squares:

  • Regularization: Prevents overfitting when many factors are considered
  • Sparsity: L1 penalty encourages sparse solutions, setting weak exposures to exactly zero
  • Stability: More robust estimates when factors are correlated

Four Nested Factor Models

Each stock is analyzed against four progressively more comprehensive factor models:

1. Base

Includes only standard macro factors: Market, SmallSize, Value, Momentum, Quality, LowVolatility, CreditRisk, InterestRate, OilPrice, GoldPrice, plus dependent factors (Buybacks, USDividends, GlobalDividends). This model answers: "How much of this stock's return is explained by well-known risk premiums?"

2. Base + Sector

Adds the 11 GICS sector factors (Technology, Financial, Healthcare, etc.) to the base model. This captures broad sector-specific exposures and shows how much of the stock's return is explained by its sector membership beyond the standard risk factors.

3. Base + Sector + Industry

Adds ~50 granular industry factors (Semiconductors, Biotechnology, Regional Banks, etc.) to the previous model. This provides more targeted exposure analysis, distinguishing between broad sector effects and specific sub-industry dynamics. For example, a semiconductor company may have different industry exposure than a software company, even though both are in the Technology sector.

4. All Factors

The most comprehensive model, adding country factors (42 countries) and AI-discovered custom factors representing thematic groups of correlated stocks. This captures geographic exposures and themes that don't fit neatly into traditional classifications—things like "EV Supply Chain", "Streaming Media", or "Work From Home Beneficiaries". Often provides the highest R-squared, revealing hidden thematic exposures in a stock.

Return Decomposition

On each stock's detail page, you can view a live return decomposition that breaks down the stock's intraday return into factor contributions. This shows exactly how much of today's move is attributable to:

  • Factor Contributions: Beta × Factor Return for each factor in the model
  • Idiosyncratic Return: The unexplained portion (stock-specific news, earnings, etc.)
  • Total Stock Return: Sum of all factor contributions plus idiosyncratic

You can switch between the four models to see how the decomposition changes. A high idiosyncratic return suggests stock-specific news; a return dominated by factor contributions suggests the stock is simply moving with the market.

Model Quality Metrics: R² and Adjusted R²

To measure how well the factor model explains a stock's returns, FactorsToday calculates two key metrics for each stock:

R² (Coefficient of Determination)

R² measures the proportion of variance in the stock's returns that is explained by the factor model. It ranges from 0 to 1:

  • R² = 0.30 (30%): The model explains 30% of the stock's return variance
  • R² = 0.70 (70%): The model explains 70% of the stock's return variance
  • Higher R²: More of the stock's movement is due to systematic factors
  • Lower R²: More of the stock's movement is idiosyncratic (stock-specific)

Calculated as: R² = model.score(X, Y), where X is the factor return matrix and Y is the stock's returns.

Adjusted R²

Adjusted R² corrects for the number of predictors in the model. Standard R² always increases when adding more factors, even if they don't improve the model. Adjusted R² penalizes model complexity:

Adjusted R² = 1 - (1 - R²) × (n - 1) / (n - p - 1)

Where n = number of observations (trading days) and p = number of active (non-zero) factor exposures. This metric is particularly useful when comparing the "All Factors" model (which has many potential factors) against simpler models—if Adjusted R² increases significantly, the additional factors provide genuine explanatory power rather than just overfitting.

Interpreting R² Values

R² < 10% Poor fit—stock moves largely independently of factors
R² 10-30% Fair fit—some factor exposure but significant idiosyncratic risk
R² > 30% Good fit—stock's returns are well-explained by factor exposures

Both R² and Adjusted R² are displayed on each stock's detail page as badges next to the model name. They are also available in the Stock Screener, where you can filter and sort stocks by model fit quality. This is useful for:

  • Finding Factor-Driven Stocks: High R² stocks move predictably with factors—useful for factor-based strategies
  • Finding Alpha Opportunities: Low R² stocks have more idiosyncratic risk—potentially under-researched or with unique catalysts
  • Model Comparison: See which model best explains a stock's behavior by comparing Adjusted R² across the four models

Portfolio Analysis

The Portfolio Analysis tool allows you to analyze the factor exposures and risk characteristics of a custom portfolio of stocks. This powerful feature helps you understand what's really driving your portfolio's returns and identify hidden risk concentrations that may not be apparent from sector classifications alone.

How to Use Portfolio Analysis

To analyze a portfolio, navigate to the Portfolio page and enter your holdings using one of three methods:

1. Equal-Weighted Portfolio

Enter a list of ticker symbols (e.g., "AAPL, MSFT, GOOGL"). The system assumes each position has equal weight. This is the simplest approach and works well for understanding the collective factor exposures of a group of stocks.

Example: "NVDA, AMD, AVGO, TSM" creates a 25% allocation to each semiconductor stock.

2. Weighted Portfolio

Enter ticker:weight pairs (e.g., "AAPL:40, MSFT:30, GOOGL:30"). Weights can be percentages (sum to 100) or dollar amounts (system automatically normalizes). This allows precise control over portfolio composition.

Example: "SPY:60, TLT:40" creates a 60/40 stock/bond portfolio.

3. CSV Upload

Upload a CSV file with two columns: ticker, weight. This is convenient for analyzing brokerage exports or large portfolios. The file should have a header row, and weights will be automatically normalized if they don't sum to 100.

ticker,weight
AAPL,5000
MSFT,3000
GOOGL,2000

Portfolio Factor Exposure Calculation

Portfolio factor exposures are calculated as the weighted average of individual stock exposures:

βportfolio,factor = Σ (wi × βi,factor)

Where wi is the weight of stock i in the portfolio and βi,factor is that stock's exposure to the given factor. This aggregation reveals the portfolio's net exposure to each systematic risk factor, accounting for offsetting positions and diversification effects.

Four Model Views

Portfolio analysis uses the same four nested factor models as stock analysis:

  • Base: Core macro factors only - reveals fundamental risk exposures (market, size, value, momentum, quality, etc.)
  • Base + Sector: Adds 11 GICS sector exposures - shows broad sector tilts in the portfolio
  • Base + Sector + Industry: Adds ~50 industry factors - reveals granular industry concentrations
  • All Factors: Adds country and custom thematic factors - uncovers geographic risks and thematic exposures

You can switch between models using the tab selector to see how factor exposures change as more factors are included. Generally, as you move to more comprehensive models, absolute beta values for individual factors decrease (as variance is explained by additional factors), but R² increases (as the model captures more of the portfolio's behavior).

Key Portfolio Metrics

Annualized Alpha

The regression intercept, annualized and expressed as a percentage. Represents the portfolio's excess return above what would be expected from its factor exposures. Positive alpha suggests skill or favorable stock selection; negative alpha suggests underperformance relative to the factor model. Alpha is calculated separately for each model - a high alpha in the "Base" model that disappears in "All Factors" suggests the outperformance was due to thematic or geographic exposures rather than true stock-picking skill.

R² (R-Squared)

Proportion of portfolio variance explained by the factor model, ranging from 0 to 1. For example, R² = 0.75 means 75% of the portfolio's return variance is explained by systematic factor exposures, with 25% being idiosyncratic (stock-specific) risk. High R² suggests a portfolio whose returns are largely driven by known factors; low R² suggests unique exposures or concentrated positions in stocks with significant idiosyncratic risk.

Adjusted R²

R² adjusted for the number of factors in the model. Penalizes model complexity to prevent overfitting:

Adjusted R² = 1 - (1 - R²) × (n - 1) / (n - p - 1)

Where n = number of observations and p = number of active (non-zero) factor exposures. Use Adjusted R² to compare models with different numbers of factors. If "All Factors" has much higher Adjusted R² than "Base", the additional factors genuinely improve explanatory power. If Adjusted R² stays flat or decreases, the extra factors are just fitting noise.

Active Factor Count

Number of factors with non-zero exposure (|beta| > 0.001). Due to ElasticNet regularization, most portfolios will have sparse exposures - only factors with meaningful explanatory power are included. A high active factor count suggests a diversified portfolio with exposures across many risk dimensions; a low count suggests concentration in a few key factors.

Historical Performance Chart

The portfolio page displays a cumulative return chart showing your portfolio's historical performance. This chart requires historical returns data for each holding. The system:

  1. Fetches daily price history for all tickers in the portfolio (up to 10 years of data)
  2. Calculates daily returns for each holding
  3. Computes portfolio daily returns as the weighted average of constituent returns
  4. Compounds returns to show cumulative performance over time
  5. Optionally overlays SPY (S&P 500) for comparison if the checkbox is enabled

You can use the timeframe buttons (1M, 3M, 6M, 1Y, 3Y, 5Y, 10Y, ALL) to zoom into different periods, and the chart supports pan and zoom interactions for detailed examination of specific time windows. The chart also displays key metrics like total return, annualized return, max drawdown, and Sharpe ratio (if sufficient history is available).

Practical Applications

Portfolio factor analysis enables several powerful use cases:

  • Risk Management: Identify unintended concentrations (e.g., high exposure to "Industry: Semiconductors" despite diversification across sectors)
  • Factor Tilts: Verify that your portfolio has the intended factor exposures (e.g., value, momentum, quality tilts)
  • Geographic Exposure: Using the "All Factors" model, see hidden country risk (e.g., multinational US stocks with high "Country: China" exposure)
  • Thematic Analysis: Discover unexpected thematic exposures through AI-discovered custom factors
  • Diversification Diagnostics: Low active factor count suggests potential concentration risk; high R² with few factors suggests you could achieve similar exposure more efficiently
  • Alpha Attribution: Compare alpha across models to determine if outperformance is true skill (persists in "All Factors") or just exposure to overlooked factors

Example Interpretation

Suppose you analyze a portfolio and observe:

  • Base Model: Alpha = 8% annualized, R² = 45%, Strong positive Quality and LowVolatility exposures
  • Base + Sector + Industry Model: Alpha = 5% annualized, R² = 68%, High exposure to "Industry: Semiconductors" and "Industry: Software"
  • All Factors Model: Alpha = 2% annualized, R² = 82%, Additional exposure to "Country: Taiwan" and "Custom: AI Infrastructure"

Interpretation: Much of what appeared as alpha in the Base model was actually exposure to semiconductors, software, Taiwan, and AI infrastructure themes. The portfolio has significant geographic concentration in Taiwan (likely through TSM, NVDA suppliers, etc.) and thematic concentration in AI. Only 2% annualized alpha remains after accounting for all factors, suggesting limited stock-picking skill - most outperformance came from riding tech/AI trends. The portfolio is well-explained by factors (82% R²), making it relatively predictable based on factor performance.

Performance Attribution Analysis

The Attribution page provides sophisticated performance attribution analysis for individual stocks or custom return streams using a rolling-window regression methodology. Unlike the static factor exposures shown on stock detail pages, attribution analysis decomposes historical returns into factor contributions using time-varying betas that adapt to changing market conditions.

What is Performance Attribution?

Performance attribution answers the question: "Why did this asset generate the return it did?" Rather than simply showing factor exposures (betas), attribution breaks down realized returns into contributions from each factor, allowing you to see exactly how much of your total return came from market exposure, size effects, sector tilts, and idiosyncratic (stock-specific) performance.

For example, if a stock returned +50% over a year, attribution might reveal that +30% came from market (beta), +10% from the technology sector, +5% from momentum, and +5% was alpha (unexplained by factors). This insight is crucial for understanding whether performance was due to systematic factor exposure (replicable, predictable) or idiosyncratic factors (harder to predict, potentially unsustainable).

How to Use the Attribution Page

You can analyze returns using several input methods:

1. Quick Start via Stock Page

Click "Attribution" on any stock detail page. The page will auto-load that stock's historical returns and populate the ticker in the URL (e.g., /attribution?ticker=AAPL). This is the fastest way to analyze a specific stock.

2. CSV Upload

Upload a CSV file with two columns: date, return. The date column should be in YYYY-MM-DD or MM/DD/YYYY format, and the return column should contain decimal returns (e.g., 0.015 for +1.5% daily return). This method allows you to analyze any return stream - a portfolio, a strategy, or even synthetic data.

date,return
2024-01-02,0.0125
2024-01-03,-0.0083
2024-01-04,0.0195

Important: When uploading a CSV, the start date will automatically be set to the maximum of the file's earliest date or 2010-01-01 (the built-in data limit). This prevents attempting to analyze periods where factor returns are unavailable.

3. Manual Entry

Paste return data directly into the text area using the same date,return format as CSV upload. Each line should contain one date-return pair. This is convenient for quick analysis of small datasets or testing specific scenarios.

Attribution Methodology: Rolling Window OLS Regression

The attribution engine uses a sophisticated rolling-window approach that captures how factor exposures evolve over time:

Step 1: Estimation Window Setup

For each date in the attribution period, the system looks backward to establish an estimation window. The length of this window is controlled by the Lookback Window parameter (default: 252 trading days = 1 year).

For example, to attribute returns on December 31, 2024, the system uses data from December 31, 2023 through December 30, 2024 to estimate factor betas, then applies those betas to December 31's factor returns to compute factor contributions.

Step 2: Regression and Beta Estimation

Within each estimation window, an OLS regression is run to estimate factor loadings (betas):

Rt = α + β1F1,t + β2F2,t + ... + βnFn,t + εt

Where Rt is the asset return on day t, Fi,t are factor returns, βi are the estimated factor exposures, α is the intercept (alpha), and εt is the residual (idiosyncratic return). The regression uses only factors with sufficient history - factors must have non-missing data for at least the full lookback window to be included.

Step 3: Re-estimation Frequency

To balance computational efficiency with beta adaptability, the system re-estimates betas periodically rather than daily. By default, betas are re-estimated every 21 trading days (~1 month). Between re-estimation dates, the most recent betas are used. This approach captures regime changes and evolving exposures while avoiding excessive computation and maintaining smoother attribution results.

Step 4: Daily Attribution Calculation

For each day in the attribution period, factor contributions are calculated using the currently active betas:

Contributionfactor,t = βfactor × Rfactor,t

The sum of all factor contributions plus alpha (intercept) approximates the total observed return. The difference between actual return and fitted return is the residual, representing stock-specific (idiosyncratic) performance not explained by the factor model.

Step 5: Cumulative Return Calculation

To compute total factor contributions over the attribution period, daily factor contributions are geometrically compounded:

Total Contributionfactor = Σtfactor,t × Rfactor,t)

This arithmetic sum of daily contributions represents each factor's total impact on the portfolio's return over the period. Actual and fitted returns are separately compounded to produce cumulative return series shown in the chart.

Return Frequency Selection

The attribution page supports analysis at three different return frequencies:

Daily Returns (Default)

No aggregation - uses returns as provided. Best for analyzing short-term factor timing and daily dynamics. Provides the most granular view but may be noisy for long-term analysis.

Weekly Returns

Daily returns are compounded into weekly periods (Friday-to-Friday). Factor returns are similarly aggregated to weekly frequency. The lookback window is automatically adjusted from days to weeks (252 days ≈ 52 weeks). Weekly analysis reduces noise and is better suited for medium-term factor analysis, matching typical rebalancing frequencies.

Monthly Returns

Daily returns are compounded into monthly periods (month-end to month-end). The lookback window is adjusted to months (252 days ≈ 12 months). Monthly analysis is ideal for long-term factor attribution and aligns with traditional performance reporting periods. Smooths out short-term noise but may miss intra-month dynamics.

Key Attribution Parameters

Factor Model

Select which factor model to use for attribution: Base (standard factors only), Base + Sector (adds sectors), Base + Sector + Industry (adds industries), or All Factors (adds countries and custom factors). More comprehensive models typically produce higher R² but may introduce noise if insufficient data exists for all factors.

Lookback Window

Number of trading days used to estimate factor betas. Range: 126 to 756 days (6 months to 3 years). Key considerations:

  • Shorter windows (126-252 days): More responsive to recent changes in factor exposures, but noisier estimates and more susceptible to overfitting
  • Longer windows (504-756 days): More stable beta estimates, but slower to adapt to regime changes or shifts in company fundamentals
  • Default (252 days): Balances responsiveness and stability, representing ~1 year of factor estimation

Start and End Dates

Define the attribution period. Note that the system requires sufficient historical data before the start date to populate the initial lookback window. For example, with a 252-day lookback and a start date of 2024-01-01, the system will load factor returns from approximately mid-2022 onwards to ensure the first attribution date has a full estimation window.

Attribution Output Metrics

Total Return vs. Factor Return

Total Return: The actual cumulative return of the asset over the attribution period, calculated by compounding daily observed returns.

Factor Return: The fitted cumulative return based on factor exposures and factor performance. This represents the return you would have achieved if the asset moved purely according to its factor betas with no idiosyncratic performance.

Alpha Return: The difference between Total Return and Factor Return, representing cumulative idiosyncratic performance not explained by factors.

Annualized Alpha

The cumulative alpha return, annualized for comparability across different time periods. Calculated as:

Annualized Alpha = [(1 + Total Return)252/n - 1] - [(1 + Factor Return)252/n - 1]

Where n is the number of trading days in the period. This approach correctly accounts for compounding by annualizing total and factor returns separately before taking the difference. Positive annualized alpha indicates consistent outperformance beyond factor exposures; negative alpha indicates underperformance.

R-Squared

Proportion of return variance explained by the factor model. Unlike portfolio analysis (which uses a single regression over the entire period), attribution R² reflects the average explanatory power of the rolling regressions. High R² (>60%) suggests returns are largely driven by systematic factors; low R² (<40%) suggests significant idiosyncratic risk or stock-specific events.

Factor Attribution Table

The attribution results display a sortable table showing each factor's contribution to total return. For each factor:

Beta: Time-weighted average factor exposure over the period
Factor Return: Cumulative return of the factor itself over the period
Contribution: Total contribution of this factor to portfolio return (sum of βt × Rfactor,t across all days)

Factors are sorted by absolute contribution, highlighting the drivers (positive contributors) and detractors (negative contributors) of performance.

Excel Export with Daily Factor Loadings

The attribution page includes a "Download as Excel" feature that exports comprehensive attribution results including:

  • Summary Tab: Total return, factor return, annualized alpha, R², and observation count
  • Factor Attribution Tab: Table of all factors with average beta, factor return, and contribution to portfolio return
  • Daily Returns Tab: Time series of actual vs. fitted returns and cumulative performance
  • Daily Factor Loadings Tab: Complete history of factor betas over time, showing how exposures evolved during the period

The daily factor loadings are particularly valuable for understanding regime changes, examining when factor exposures shifted, and validating the stability of beta estimates. Due to the large size of this data (potentially thousands of rows × dozens of factors), it is stored in a temporary database table rather than being passed via JSON, with automatic cleanup after 24 hours.

Example Use Cases

Understanding Stock Outperformance

A stock returned +80% in 2024. Was this due to the bull market, sector rotation, or genuine alpha? Run attribution with the "All Factors" model. Suppose you find: +40% from Market, +25% from "Industry: Semiconductors", +10% from "Custom: AI Infrastructure", and +5% annualized alpha. Conclusion: Most outperformance was riding broad market and AI/semiconductor trends, not stock-specific merit.

Strategy Validation

You run a long-short equity strategy and want to verify it truly generates alpha rather than just loading on known factors. Export daily P&L as returns and upload to the attribution page. If annualized alpha is near zero after controlling for all factors, your strategy may be synthetically replicating factor exposures without adding unique value. If substantial alpha remains, you have genuine skill.

Time-Varying Risk Analysis

Download the Excel export and examine the "Daily Factor Loadings" tab. Plot a stock's market beta over time - if beta increased significantly during a specific period (e.g., 2022 bear market), this explains why the stock underperformed more than expected. This time-varying analysis is impossible with static beta estimates but critical for understanding regime-dependent behavior.

Update Pipeline

Factor returns are updated through a two-tier system designed to balance freshness with computational efficiency:

Daily Incremental Updates

Each trading day, new factor returns are calculated using saved factor equations. This process:

  • Loads the most recent factor equations from the database
  • Fetches new price data for all underlying tickers
  • Computes returns using the stored weights (no regression required)
  • Appends new returns to the factor_return table

Weekly Full Recalibration

Every 7 days, the entire factor model is rebuilt from scratch:

  1. Initialize Market Factor: Set Market = 100% IVV as the foundation
  2. Process Standard Factors: Calculate all core factors (Market, Size, Value, Momentum, Quality, LowVolatility, CreditRisk, InterestRate, OilPrice, GoldPrice) with fresh regression coefficients
  3. Process Dependent Factors: Calculate factors that depend on standard factors (Buybacks, USDividends, GlobalDividends)
  4. Process Sector Factors: Recalculate all broad sector factors from Sector SPDR ETFs (11 GICS sectors)
  5. Process Industry Factors: Recalculate all granular industry factors from iShares and thematic ETFs (~50 sub-industries)
  6. Process Country Factors: Recalculate all country ETF-based factors (42 countries)
  7. Rediscover Custom Factors: Run correlation clustering to find new thematic stock groups
  8. Process Custom Factors: Calculate factor returns for AI-discovered groups
  9. Store Equations: Save all new factor equations for daily incremental updates

This weekly recalibration allows the model to adapt to changing market regimes, evolving factor correlations, and emerging thematic groups, while daily updates ensure factor returns are always current. The pipeline is carefully ordered to ensure proper dependency resolution—each factor type is stripped against all previously computed factors, creating a hierarchical structure where industry factors are orthogonal to sector factors, which are in turn orthogonal to standard factors.

Factor Diagnostics

FactorsToday runs statistical diagnostics on each factor to characterize its time series properties:

  • Augmented Dickey-Fuller Test: Tests for stationarity (mean reversion vs. random walk)
  • Hurst Exponent: Measures long-term memory (H < 0.5 = mean-reverting, H > 0.5 = trending)
  • Variance Ratio Test: Compares variances at different time scales to detect momentum or mean reversion
  • Runs Test: Detects non-random clustering of up/down moves
  • Ljung-Box Test: Tests for significant autocorrelation in returns
  • Durbin-Watson Statistic: Measures lag-1 autocorrelation in residuals

These diagnostics help identify factors with predictable behavior (momentum or mean reversion) versus those that follow a random walk, informing factor timing and portfolio construction decisions.