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:
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:
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:
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:
- Source: Daily returns from Sector SPDR ETFs with at least 756 days (~3 years) of trading history
- Purification: Regressed against all standard factors using the full factor stripping methodology
- 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
- Build Correlation Graph: Compute pairwise return correlations for all common stocks. Create edges between stocks with correlation ≥ 0.50 (base threshold).
- Find Connected Components: Use breadth-first search to identify groups of interconnected stocks.
- 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
- 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.
- 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."
- 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
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:
- Navigate to the Factor History page
- Click on any factor name to view its detail page
- Click the ▼ button next to the live return to expand the equation details
- 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:
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.
AAPL,5000
MSFT,3000
GOOGL,2000
Portfolio Factor Exposure Calculation
Portfolio factor exposures are calculated as the weighted average of individual stock exposures:
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:
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:
- Fetches daily price history for all tickers in the portfolio (up to 10 years of data)
- Calculates daily returns for each holding
- Computes portfolio daily returns as the weighted average of constituent returns
- Compounds returns to show cumulative performance over time
- 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.
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):
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:
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:
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:
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:
- Initialize Market Factor: Set Market = 100% IVV as the foundation
- Process Standard Factors: Calculate all core factors (Market, Size, Value, Momentum, Quality, LowVolatility, CreditRisk, InterestRate, OilPrice, GoldPrice) with fresh regression coefficients
- Process Dependent Factors: Calculate factors that depend on standard factors (Buybacks, USDividends, GlobalDividends)
- Process Sector Factors: Recalculate all broad sector factors from Sector SPDR ETFs (11 GICS sectors)
- Process Industry Factors: Recalculate all granular industry factors from iShares and thematic ETFs (~50 sub-industries)
- Process Country Factors: Recalculate all country ETF-based factors (42 countries)
- Rediscover Custom Factors: Run correlation clustering to find new thematic stock groups
- Process Custom Factors: Calculate factor returns for AI-discovered groups
- 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.