4 Factor Catalog
A comprehensive, self-contained reference covering every factor in the canonical research set — including the economic rationale, stylistic guidance, platform implementation details, and empirical performance results for each factor, organized by factor family.
Scope note — factors, not strategies. A factor is a measured, predictive characteristic of an instrument (this chapter); a strategy is a downstream (factor_id, mechanic, params) triple that trades one — see the Strategy Catalog. Several factors below are traded by more than one strategy, and a couple of entries exist only because a downstream strategy needs a distinct evaluation path (funnel-exempt entries, flagged where they occur). This chapter deliberately stops at the factor boundary: mechanic, universe, sizing, and backtest/promotion detail all live in the Strategy Catalog, not here.
4.1 Provenance
- Theory fields (economic justification, style, anchor citation, hypothesis class, expected sign, source table/column, lifecycle status) are pulled directly from
config/factors/*.yamlin SBFoundation as of 2026-08-03. - Empirical fields (IC-IR, MCPT) come from the diagnostic run
260526_6ddcd9(2026-05-26), synthesized inplatform/factors.md. That run predates three fixes that materially change these numbers — F-136 (MCPT nightly permutations 100 → 1000, corrected null construction), F-137 (Alphalens forward-return winsorization), F-138 (composite contribution rescaling). Treat every MCPT figure below as provisional pending a rerun. - Two columns — naive t-stat and HAC (Newey–West) t-stat — are specified but not yet computed. No sidecar currently produces them; see Method below for exactly how to fill them in. They are marked
PENDINGthroughout rather than guessed. - Re-grounding against live config surfaced a correction to the run narrative:
bb_lower_20,ma_50d,ma_200d, andvwap_20dwere described in the260526_6ddcd9synthesis as the four factors with “real” pre-fix MCPT significance — but all four were subsequently deprecated for cause on 2026-07-20 (F-289/LH-25, run260718_31a51e): they’re raw price-level source columns with a CF-1 look-ahead issue, not a validated edge.bb_lower_20’s entry below reflects this;bb_pct(§13) is its scale-free replacement. - Known duplicates — resolved 2026-08-05.
beta↔︎market_beta_252dandmomentum_12_1↔︎momentum_12m_1mare numerically identical to 14 digits per the run synthesis; neither pair has ever had two independentconfig/factors/*.yamlfiles (nobeta.yamlormomentum_12_1.yamlexists — both are stale legacy ids with no config of their own).betaandmomentum_12_1are retired;market_beta_252dandmomentum_12m_1mare the canonical survivors and are the only ones counted in the platform’s family-wise trial count (F-321).
4.2 Method: the pending t-stat columns
Every factor entry below has two PENDING fields. Both are specified the same way, stated once here rather than repeated 24 times:
- Naive t-stat — the classic Fama–MacBeth / Fama–French second-pass report. Take the daily factor-return series
F_tfor thefactor_idfromops.risk_factor_return(factor-models-and-benchmarks.md §2.2), and computet_naive = mean(F) / (std(F) / sqrt(T)). - HAC (Newey–West) t-stat — regress the same series on a constant only (
X = [1]) using the platform’s existing HAC estimator,sbattribution.ols.ols_hac(src/sbattribution/ols.py:79-125) — the identical kernel already used for CAPM/attribution alpha (Bartlett weights, lagL = floor(4·(n/100)^(2/9)), Newey–West 1994). The intercept is the mean factor return; its HAC standard error replaces the naivestd(F)/sqrt(T)denominator. - Why both: daily factor returns built on slow-moving or overlapping-window characteristics (12-1 momentum, vol-scaling, TSMOM) are serially correlated by construction, so the naive t-stat overstates significance. The gap between the two is itself diagnostic.
- Neither is a promotion gate. Per research-platform/08-validation-and-anti-overfitting.md, a t-stat — naive or HAC — is exactly the single-test statistic the Harvey–Liu–Zhu multiple-testing critique targets. The platform’s actual promotion gate is IC-IR + MCPT permutation p-value against an honest trial count; these two columns are diagnostic context, not a second gate.
- Not yet wired:
ols_hactoday only runs against strategy NAV streams (beta_attribution_service.py), not the per-factor return panel — computing these columns requires a small new script, not a config change.
4.3 1. Market
Compensation for bearing undiversifiable market risk — the one factor everyone must hold; the CAPM premium. Sharpe 1964 [#116], Lintner 1965 [#117].
4.3.1 market_beta_252d
- Style:
beta - Source:
fact_eod.market_beta_252d_f— trailing 252-day rolling OLS slope vs. SPY - Equation: \(\beta_{i,t} = \dfrac{\mathrm{Cov}_{252d}(r_i,\, r_{SPY})}{\mathrm{Var}_{252d}(r_{SPY})}\)
- Hypothesis class / expected sign: not set in config
- Lifecycle:
experimental— canonical survivor of thebeta/market_beta_252dduplicate pair (resolved 2026-08-05);betais retired - IC-IR @21d: not itemized in the run synthesis
- MCPT (pre-fix): p=1.000 (ceiling),
unbiased_ic_ir≈ −6.8 - t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily; diagnostics “healthy” quadrant (stationary, entropy ≥3)
- Notes:
betaandmarket_beta_252dare numerically identical to 14 digits;betawas a legacy id with no independentconfig/factors/beta.yamland is now retired.
4.4 2. Size
Small caps earn a premium for illiquidity, distress, and limited analyst coverage; partly compensation, partly a limits-to-arbitrage effect. Banz 1981 [#125], Fama–French 1992 [#55].
4.4.1 market_cap
- Style:
size - Source:
fact_valuation_annual.market_cap_f—year_end_close × shares_outstanding - Equation: \(\text{MktCap}_{i,t} = P^{YE}_{i,t} \times \text{SharesOut}_{i,t}\)
- Hypothesis class / expected sign: not set in config
- Lifecycle:
experimental - IC-IR @21d: ≈ −0.5 (inverted — part of the low-vol/size cluster; trade short)
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual — short-T caveat applies (ADF/entropy diagnostics have little power at n≈12)
- Notes: —
4.5 3. Value
Cheap (high E/P, B/M, FCF-yield) stocks out-earn expensive ones — risk premium for distressed/low-growth firms and mispricing from extrapolation. Fama–French 1992/1993 [#55][#44].
4.5.1 value_composite
- Style:
value - Source:
fact_fundamental_annual.value_composite_f— multi-ratio value z-score blend (earnings, book, sales, cash-flow yields) - Equation: \(\text{ValueComposite}_{i,t} = \dfrac{1}{4}\displaystyle\sum_{k \,\in\, \{EY,\; B/M,\; S/P,\; FCF/P\}} z\!\left(x_{k,i,t}\right)\) — config specifies the four component yields and calls it a “blend”; the equal weighting shown here is the simplest reading and is not independently confirmed by a documented weight vector.
- Hypothesis class / expected sign:
risk_premium, positive - Lifecycle:
experimental, promotion candidate - IC-IR @21d: +0.75 — highest in the run
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: sign-flips at h=1 (don’t trade intraday) — classic value-investor pattern, right direction only at a month+ horizon
4.5.2 earnings_yield
- Style:
value - Source:
fact_valuation_annual.earnings_yield_f—eps_diluted / year_end_close - Equation: \(EY_{i,t} = \dfrac{EPS^{diluted}_{i,t}}{P^{YE}_{i,t}}\) (inverse of
pe_ratio) - Hypothesis class / expected sign:
risk_premium, positive - Lifecycle:
experimental - IC-IR @21d: sign-flip — negative at h=1, positive at h≥21
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.5.3 pe_ratio
- Style:
value - Source:
fact_valuation_annual.pe_ratio_f—year_end_close / eps_diluted - Equation: \(PE_{i,t} = \dfrac{P^{YE}_{i,t}}{EPS^{diluted}_{i,t}}\)
- Hypothesis class / expected sign:
risk_premium, negative - Lifecycle:
experimental - IC-IR @21d: −0.5 to −0.7 (inverted group, with
volatility_*/market_cap/amihud) - MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.5.4 pb_ratio
- Style:
value - Source:
fact_valuation_annual.pb_ratio_f—market_cap / total_stockholders_equity - Equation: \(PB_{i,t} = \dfrac{P^{YE}_{i,t} \times \overline{Shs}^{diluted}_{i,t}}{\text{StockholdersEquity}_{i,t}}\)
- Hypothesis class / expected sign:
risk_premium, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): raw Alphalens top-minus-bottom spread +37.40 at h=21 — a pre-F-137 artifact (un-winsorized cross-section outlier dominance), not a real spread; bounded post-fix
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.5.5 ps_ratio
- Style:
value - Source:
fact_valuation_annual.ps_ratio_f—market_cap / revenue - Equation: \(PS_{i,t} = \dfrac{P^{YE}_{i,t} \times \overline{Shs}^{diluted}_{i,t}}{\text{Revenue}_{i,t}}\)
- Hypothesis class / expected sign:
risk_premium, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): raw Alphalens spread +44.78 at h=21 — pre-F-137 artifact, bounded post-fix
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.5.6 pfcf_ratio
- Style:
value - Source:
fact_valuation_annual.pfcf_ratio_f—market_cap / free_cash_flow - Equation: \(PFCF_{i,t} = \dfrac{P^{YE}_{i,t} \times \overline{Shs}^{diluted}_{i,t}}{\text{FCF}_{i,t}}\) (inverse of
fcf_yield) - Hypothesis class / expected sign:
risk_premium, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): raw Alphalens spread −36.78 at h=21 — pre-F-137 artifact, bounded post-fix
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.6 4. Momentum
Past 12-1 winners keep winning — under-reaction to news and delayed information diffusion (behavioral). Jegadeesh–Titman 1993 [#49], Carhart 1997 [#57].
4.6.1 momentum_12m_1m
- Style:
momentum - Source:
fact_eod.momentum_12_1_f - Equation: \(\text{Mom}_{i,t} = \dfrac{P_{i,t-21}}{P_{i,t-252}} - 1\) (12-month cumulative return, skipping the most recent month)
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental— canonical survivor of themomentum_12_1/momentum_12m_1mduplicate pair (resolved 2026-08-05);momentum_12_1is retired - IC-IR @21d: +0.586
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes:
momentum_12_1andmomentum_12m_1mare numerically identical to 14 digits;momentum_12_1was a legacy id (still used as a raw bundle/feature column name insbbacktest, but with no independentconfig/factors/momentum_12_1.yaml) and is now retired as a factor id.
4.6.2 momentum_12_1_vol_scaled
- Style:
momentum - Source:
fact_eod.momentum_12_1_vol_scaled_f— the 12-1 trend divided by trailing realized volatility (worked example: factor-models-and-benchmarks.md §6) - Equation: \(\text{Mom}^{vol}_{i,t} = \dfrac{\text{Mom}_{i,t}}{\sigma^{126d}_{i,t}\sqrt{252}}\), where \(\text{Mom}_{i,t}\) is the §4 12-1 return above and \(\sigma^{126d}_{i,t}\) is the trailing 126-day daily-return standard deviation
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental, promotion candidate - IC-IR @21d: +0.629
- MCPT (pre-fix): ceiling-pinned pre-fix; vol-scaling is expected to help it survive overlap correction post-F-136
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes: same source column also backs the distinct factor entity
tsmom_12_1_vol_scaled(§12) — identical value, different evaluation path (this factor is scored cross-sectionally; §12 is funnel-exempt). The strategies that trade each —classic-momentum/classic-momentum-long-only/classic-momentum-dollar-neutralfor this one,etf-trendfor §12 — are documented in the Strategy Catalog.
4.6.3 residual_momentum_252d_eod (not in the original 13-row citation table — added here because it has the strongest result in the run)
- Style:
momentum - Source:
fact_eod.residual_momentum_252d_f— market-neutral momentum: residual of a 252-day rolling OLS of return vs. an equal-weighted benchmark, summed over[-252:-21]and z-scaled - Equation: \(\varepsilon_{i,\tau} = r_{i,\tau} - \big(\hat\alpha_i + \hat\beta_i\, r_{EW,\tau}\big)\) from a 252-day rolling OLS, then \(\text{ResMom}_{i,t} = z\!\left(\displaystyle\sum_{\tau=t-252}^{t-21}\varepsilon_{i,\tau}\right)\)
- Hypothesis class / expected sign: not set in config
- Lifecycle:
experimental— atomic sibling of the deprecated compositeresidual_momentum_252d(status: deprecated, B-F-108.1/TASK-907; noFactorCompositionServiceexists to compute the composite recipe, so it carries zero rows). Consumers should use this atomic id, not the composite. - IC-IR @21d: +0.724 — highest in the entire run
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily; diagnostics “healthy” quadrant
- Notes: candidate for a 14th row in the citation table given this result — anchor citation would be Blitz–Huij–Martens (residual momentum) [#50]. Traded by the
residual-momentumstrategy — see Strategy Catalog §4.
4.7 5. Profitability / Quality
Profitable, safe, well-managed firms (high gross-profitability, ROIC, QMJ) out-earn junk — a premium for quality that markets under-price. Novy-Marx 2013 [#92], Fama–French 2015 [#56], Asness–Frazzini–Pedersen 2019 [#113].
4.7.1 qmj_composite
- Style:
quality - Source:
fact_fundamental_annual.qmj_composite_f— Asness–Frazzini–Pedersen Quality-Minus-Junk blend across profitability, growth, safety, and payout - Equation: \(QMJ_{i,t} = z(\text{Profitability}_{i,t}) + z(\text{Growth}_{i,t}) + z(\text{Safety}_{i,t}) + z(\text{Payout}_{i,t})\)
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental.kind: atomic by design— despite the name, it’s a single pre-blended z-score column computed upstream, not a true composite; will always land assingle_inputin the factor-contribution sidecar (F-138). - IC-IR @21d: not itemized
- MCPT (pre-fix): floor bucket (
null_mean_ic_ir≈ 0, degenerate permutation null — typical of slow-moving annual fundamentals) - t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual — short-T caveat applies
- Notes: —
4.7.2 roic_spread
- Style:
quality - Source:
fact_moat_annual.roic_spread_f— current-year ROIC minus WACC, winsorized and industry-z-scored to [0,1] - Equation: \(\text{ROICSpread}_{i,t} = \text{clip}_{[0,1]}\Big(z_{industry}\big(\text{ROIC}_{i,t} - \text{WACC}_{i,t}\big)\Big)\), where \(\text{ROIC} = \text{NOPAT}/\text{InvestedCapital}\)
- Hypothesis class / expected sign:
risk_premium, positive - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual — short-T caveat applies
- Notes: —
4.7.3 gross_profitability
- Style:
quality - Source:
fact_moat_annual.gross_profitability_f—gross_profit / total_assets(Novy-Marx 2013) - Equation: \(GP_{i,t} = \dfrac{\text{GrossProfit}_{i,t}}{\text{TotalAssets}_{i,t}}\)
- Hypothesis class / expected sign:
risk_premium, positive - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual — short-T caveat applies
- Notes: —
4.7.4 piotroski
- Style:
quality - Source:
fact_fundamental_annual.piotroski_f— 9-criterion financial-strength score - Equation: \(F_{i,t} = \displaystyle\sum_{k=1}^{9} \mathbb{1}[\text{criterion}_k \text{ met}] \in [0,9]\)
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental - IC-IR @21d: sign-flip — negative at h=1, positive at h≥21
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual
- Notes: —
4.8 6. Investment / Accruals
Firms that invest conservatively and have low accruals out-earn aggressive investors — over-investment and earnings-quality mispricing. Sloan 1996 [#83], Cooper–Gulen–Schill 2008 [#103], Fama–French 2015 [#56].
4.8.1 accruals
- Style:
quality - Source:
fact_moat_annual.accruals_f— Sloan (1996) Total-Accruals-to-Total-Assets - Equation: \(\text{Accruals}_{i,t} = \dfrac{\text{NetIncome}_{i,t} - \text{CFO}_{i,t}}{\text{TotalAssets}_{i,t}}\)
- Hypothesis class / expected sign:
behavioral, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: annual — short-T caveat applies
- Notes: §10’s original mapping also names
earnings_growth_qoqfor this family; no config file for that id was found under this exact name — needs reconciling against whatever earnings-growth id is actually registered.
4.9 7. Low volatility / Defensive
Low-risk stocks earn higher risk-adjusted returns — leverage constraints and lottery-preference bid up high-vol names (the low-vol anomaly / BAB). Ang et al. 2006 [#108], Frazzini–Pedersen 2014 [#93], Novy-Marx 2014 [#10].
4.9.1 volatility_30d
- Style:
volatility - Source:
fact_eod.volatility_30d_f— STDDEV of daily log returns over 30 sessions × √252 - Equation: \(\sigma^{30d}_{i,t} = \text{STDDEV}_{30d}\big(\ln(P_{i,\tau}/P_{i,\tau-1})\big) \times \sqrt{252}\)
- Hypothesis class / expected sign:
behavioral, negative - Lifecycle:
experimental; strong signal — invert sign on promotion - IC-IR @21d: −0.5 to −0.7, alongside
volatility_60/126/252d— part of the low-vol/size inverted cluster - MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes: —
4.10 8. Liquidity / Illiquidity
Illiquid stocks (high Amihud price-impact, low $ADV) require a return premium for the cost and risk of trading them. Amihud 2002 [#48].
4.10.1 amihud
- Style:
liquidity - Source:
fact_eod.amihud_f— mean of|daily_return| / dollar_volumeover a trailing window - Equation: \(\text{Amihud}_{i,t} = \dfrac{1}{N}\displaystyle\sum_{\tau=t-N+1}^{t} \dfrac{|r_{i,\tau}|}{\$\text{Vol}_{i,\tau}}\)
- Hypothesis class / expected sign: not set in config
- Lifecycle:
experimental - IC-IR @21d: inverted group (with
pe_ratio,volatility_*,market_cap) - MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily; diagnostics “healthy” quadrant
- Notes: —
4.10.2 adv_dollar_20d
- Style:
liquidity - Source:
fact_eod.adv_dollar_20d_f— mean ofadj_close × volumeover the trailing 20 sessions - Equation: \(\text{ADV\$}^{20d}_{i,t} = \dfrac{1}{20}\displaystyle\sum_{\tau=t-19}^{t} P_{i,\tau} \times V_{i,\tau}\)
- Hypothesis class / expected sign: not set in config
- Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes: don’t confuse with
adv_20d(undiscounted volume, no dollar scaling) — that id sits in the “drift” diagnostics quadrant (non-stationary, high entropy), a distinct factor.
4.11 9. Short interest / Positioning
Heavily-shorted / high-days-to-cover names underperform — informed short sellers and short-sale-constraint overvaluation (divergence of opinion). Boehmer–Jones–Zhang 2008 [#101], Rapach–Ringgenberg–Zhou 2016 [#100], Miller 1977 [#111].
4.11.1 days_to_cover
- Style:
positioning - Source:
fact_short_interest.days_to_cover_f— FINRA’sdaysToCoverQuantity, trusted verbatim from the vendor (no platform recompute from ADV) - Equation: \(\text{DTC}_{i,t} = \dfrac{\text{ShortInterest}_{i,t}}{\text{ADV}_{i,t}}\)
- Hypothesis class / expected sign:
behavioral, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: FINRA disclosure-lag snap applies (18 calendar days)
- Notes: —
4.11.2 short_pct_float
- Style:
positioning - Source:
fact_short_interest.short_pct_float_f— short interest / diluted shares outstanding (a float proxy) - Equation: \(\text{ShortPctFloat}_{i,t} = \dfrac{\text{ShortInterest}_{i,t}}{\text{DilutedSharesOut}_{i,t}}\)
- Hypothesis class / expected sign:
behavioral, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: FINRA disclosure-lag snap applies (18 calendar days)
- Notes: —
4.12 10. Seasonality
Same-calendar-month historical returns recur — persistent cross-sectional seasonalities from mood, liquidity, and information cycles. Heston–Sadka 2008 [#37], Hirshleifer et al. 2020 [#40].
4.12.1 seasonality_same_month
- Style:
momentum - Source:
fact_eod.seasonality_same_month_f— mean, over the prior ≤20 years (≥5 required), of the instrument’s monthly return in the same calendar month (Heston–Sadka - Equation: \(\text{Seas}_{i,t} = \dfrac{1}{K}\displaystyle\sum_{y=1}^{K} r^{month}_{i,\,\text{same-month}(t),\,y}\), \(5 \le K \le 20\)
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes: —
4.13 11. Earnings momentum / PEAD
Prices under-react to earnings surprises (SUE), drifting for weeks after the announcement — the post-earnings-announcement drift. Bernard–Thomas 1989 [#75].
4.13.1 sue
- Style:
growth - Source:
fact_earnings_momentum.sue_f—eps_surprise_pct / STDDEV(eps_surprise_pct)over the strictly-prior 8 announcements - Equation: \(\text{SUE}_{i,q} = \dfrac{\Delta EPS\%_{i,q}}{\text{STDDEV}_8\big(\Delta EPS\%_{i,\,q-1:q-8}\big)}\)
- Hypothesis class / expected sign:
behavioral, positive - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: not itemized
- Notes: traded by the
sue-earnings-momentumstrategy — see Strategy Catalog §5.
4.14 12. Time-series momentum / Trend
An asset’s own past 12-1 return predicts its next-month return across asset classes — trend-following / slow-diffusion premium. Moskowitz–Ooi–Pedersen 2012 [#115], Hurst–Ooi–Pedersen 2017 [#95].
4.14.1 tsmom_12_1_vol_scaled
- Style:
momentum - Source:
fact_eod.momentum_12_1_vol_scaled_f— same source column asmomentum_12_1_vol_scaled(§4), but registered as its own factor entity because it has its own evaluation path:funnel_exempt: truein config, so it is never scored by the cross-sectional IC/MCPT/Alphalens funnel. Its only evidence comes from the strategy that trades it — see Strategy Catalog §3 for thelong_flat_trendmechanic (own-trend-sign selection) and its walk-forward backtest. - Equation: \(\text{TSMom}_{i,t} = \text{Mom}^{vol}_{i,t}\) — identical formula to §4’s
momentum_12_1_vol_scaled(same source column); thelong_flat_trendmechanic consumes \(\text{sign}(\text{TSMom}_{i,t})\), not its cross-sectional rank - Hypothesis class / expected sign:
risk_premium, positive - Lifecycle:
experimental - IC-IR @21d: not itemized (funnel-exempt — not scored by cross-sectional IC)
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily
- Notes: —
4.15 13. Short-horizon reversal
Very-short-horizon losers bounce (and winners fade) — liquidity provision / over-reaction correction (contrarian). Lehmann 1990 [#96].
4.15.1 bb_pct
- Style:
volatility - Source:
fact_eod.bb_pct_f—(adj_close - bb_lower_20_f) / (bb_upper_20_f - bb_lower_20_f) - Equation: \(\%B_{i,t} = \dfrac{P_{i,t} - L^{20}_{i,t}}{U^{20}_{i,t} - L^{20}_{i,t}}\), where \(U^{20} = \text{SMA}^{20d} + 2\sigma^{20d}\) and \(L^{20} = \text{SMA}^{20d} - 2\sigma^{20d}\) (0 at the lower band, 1 at the upper band) — a ratio of price differences, so a future split scales numerator and denominator identically and cancels (scale-free, PIT-clean w.r.t. corporate actions; F-289/LH-25)
- Hypothesis class / expected sign:
behavioral, negative - Lifecycle:
experimental - IC-IR @21d: not itemized
- MCPT (pre-fix): not itemized
- t-stat (naive):
PENDING - t-stat (HAC, Newey–West):
PENDING - n_obs / cadence: daily; diagnostics “healthy” quadrant
- Notes: —
4.15.2 bb_lower_20 (superseded predecessor — not in the original 13-row table, included for the correction it forces)
- Style:
volatility - Source:
fact_eod.bb_lower_20_f— 20-day SMA ofadj_close− 2×20-day stddev - Equation: \(L^{20}_{i,t} = \text{SMA}^{20d}_{i,t} - 2\,\sigma^{20d}_{i,t}\) — a raw price level (not scale-free), which is precisely the CF-1 look-ahead defect that got it deprecated (see Lifecycle below)
- Hypothesis class / expected sign:
behavioral, positive — short-horizon mean-reversion (Lehmann 1990 contrarian reversal) - Lifecycle:
deprecatedfor cause (F-289/LH-25, 2026-07-20, run260718_31a51e) — raw price-level source column with a CF-1 look-ahead defect. Replaced bybb_pct(scale-free). - IC-IR @21d: not itemized
- MCPT (pre-fix, run
260526_6ddcd9): one of only four factors with a non-collapsed permutation null and positiveunbiased_ic_ir(0.21–1.35) at the time — this result is now known to be contaminated by the CF-1 look-ahead, not evidence of a real edge. The other three factors in that same “real significance” group at the time —ma_50d,ma_200d,vwap_20d— were deprecated for the identical reason on the same date and are not part of this catalog’s 13 families. - t-stat (naive):
PENDING(moot — factor is deprecated) - t-stat (HAC, Newey–West):
PENDING(moot — factor is deprecated) - n_obs / cadence: daily
- Notes: kept in the catalog specifically as a cautionary entry — the
260526_6ddcd9run synthesis called this factor’s MCPT result the cleanest in the library; two months later it was found to be a look-ahead artifact. A clean permutation p-value is necessary evidence, not sufficient.
4.16 Next steps
- Write the query/script computing
t_naiveandt_HACperfactor_idagainstops.risk_factor_return, and fill in everyPENDINGfield above. Resolve the two duplicate pairs— done 2026-08-05:market_beta_252dandmomentum_12m_1mare the canonical survivors;betaandmomentum_12_1are retired. Remaining follow-up: if either legacy id has rows inops.factor, flip their status there too (a DB change, out of scope for this doc pass).- Backfill
hypothesis_class/expected_signfor the factors missing it in config (market_beta_252d,market_cap,amihud,adv_dollar_20d). - Reconcile the §6 (Investment/Accruals) mapping —
earnings_growth_qoqhas no matching config file under that id. - Regenerate the empirical fields against the first post-F-136/137/138
NIGHTLY_FULL/RESEARCH_DAYrun. - Consider formally adding
residual_momentum_252d_eod(§4) as a 14th citation row, given its result is the strongest in the run.
4.17 Cross-links
- strategy-catalog.md — the downstream companion to this chapter: every registered
(factor_id, mechanic, params)strategy that trades a factor listed above, with its universe, sizing, promotion gates, and backtest status. - factor-models-and-benchmarks.md — the theory this catalog assumes: factor loadings, factor returns, CAPM decomposition, systematic/idiosyncratic return, benchmark selection.
- experiments/2026-08-03-factor-catalogue-empirical-results — the dated provenance record for the empirical fields above (run id, method, journal link).
- research-platform/04-factor-layer-as-multiplex-layer-1.md — why this catalog matters to the PhD proposal: these factors are its Layer 1.
- research-platform/08-validation-and-anti-overfitting.md — why no single column above (including the t-stats, once filled in) should be read as a standalone verdict.