exp_1191

Contrarian 52-Week Recovery Quality Regime Momentum Hybrid (Arbitrated Repair Relay, v1191)

← All V2 experiments
Relative return
1.033x
Excess vs bench
3.33%
Benchmark
CAPW_UNIV
Rolling windows
179 · monthly
Mean strategy gain
17.84%
Mean benchmark gain
14.08%
Mean excess gain
3.75%
Dispersion (ref)
5.48%
Win-rate vs bench (ref)
81.01%
Worst / best ratio (ref)
0.975x / 1.096x
Logic variants
4
Updated
Jul 21, 2026
Anchored windows (reference — strategy vs benchmark)
Kept from V1 for continuity; the objective ranks on the full rolling set, not these four.
WindowStrategyBenchmarkRatio
2006-07-03 … 2011-06-30 5.68% 2.22% 1.034x
2011-07-01 … 2016-06-30 19.27% 13.74% 1.049x
2016-07-01 … 2021-06-30 20.06% 20.63% 0.995x
2021-07-01 … 2026-06-26 24.08% 15.48% 1.074x
All rolling windows — the objective set (equal-weighted mean ratio)
Strategy Benchmark (CAPW_UNIV) Excess
2006200720082009201020112012201320142015201620172018201920202021 -5%0%5%10%15%20%25%30%
rolling 5y windows, monthly step — 179 windows · mean ratio 1.033x · beat benchmark in 145/179
#WindowStrategyBenchmarkRatio
1 2006-07-31 … 2011-07-29 5.55% 1.79% 1.037x
2 2006-08-31 … 2011-08-31 4.76% 0.21% 1.045x
3 2006-09-29 … 2011-08-31 4.76% -0.14% 1.049x
4 2006-10-31 … 2011-10-31 5.74% 0.23% 1.055x
5 2006-11-30 … 2011-11-30 5.73% -0.05% 1.058x
6 2006-12-29 … 2011-11-30 5.51% -0.32% 1.058x
7 2007-01-31 … 2012-01-31 6.79% 0.93% 1.058x
8 2007-02-28 … 2012-01-31 7.35% 1.43% 1.058x
9 2007-03-30 … 2012-03-30 10.23% 3.09% 1.069x
10 2007-04-30 … 2012-04-30 10.41% 2.42% 1.078x
11 2007-05-31 … 2012-05-31 8.53% 0.60% 1.079x
12 2007-06-29 … 2012-06-29 9.96% 1.92% 1.079x
13 2007-07-31 … 2012-07-31 10.82% 2.69% 1.079x
14 2007-08-31 … 2012-08-31 10.28% 2.95% 1.071x
15 2007-09-28 … 2012-09-28 10.37% 3.20% 1.070x
16 2007-10-31 … 2012-10-31 9.00% 2.60% 1.062x
17 2007-11-30 … 2012-11-30 10.06% 3.45% 1.064x
18 2007-12-31 … 2012-12-31 10.05% 3.69% 1.061x
19 2008-01-31 … 2013-01-31 13.13% 5.85% 1.069x
20 2008-02-29 … 2013-02-28 14.21% 6.82% 1.069x
21 2008-03-31 … 2013-03-28 15.90% 7.73% 1.076x
22 2008-04-30 … 2013-04-30 15.67% 7.51% 1.076x
23 2008-05-30 … 2013-04-30 15.14% 7.81% 1.068x
24 2008-06-30 … 2013-06-28 13.80% 9.33% 1.041x
25 2008-07-31 … 2013-07-31 17.06% 10.48% 1.060x
26 2008-08-29 … 2013-07-31 18.08% 10.52% 1.068x
27 2008-09-30 … 2013-09-30 19.72% 11.48% 1.074x
28 2008-10-31 … 2013-10-31 22.87% 15.76% 1.061x
29 2008-11-28 … 2013-10-31 23.94% 17.46% 1.055x
30 2008-12-31 … 2013-12-31 25.93% 18.44% 1.063x
31 2009-01-30 … 2013-12-31 27.26% 20.64% 1.055x
32 2009-02-27 … 2014-01-31 28.33% 21.63% 1.055x
33 2009-03-31 … 2014-03-31 26.93% 20.60% 1.052x
34 2009-04-30 … 2014-04-30 24.96% 19.00% 1.050x
35 2009-05-29 … 2014-04-30 25.53% 18.32% 1.061x
36 2009-06-30 … 2014-06-30 27.55% 19.01% 1.072x
37 2009-07-31 … 2014-07-31 25.90% 17.39% 1.072x
38 2009-08-31 … 2014-08-29 26.32% 17.70% 1.073x
39 2009-09-30 … 2014-09-30 24.59% 16.64% 1.068x
40 2009-10-30 … 2014-09-30 25.41% 17.08% 1.071x
41 2009-11-30 … 2014-11-28 24.91% 16.82% 1.069x
42 2009-12-31 … 2014-12-31 23.79% 16.28% 1.065x
43 2010-01-29 … 2014-12-31 25.62% 17.23% 1.072x
44 2010-02-26 … 2015-01-30 25.20% 15.80% 1.081x
45 2010-03-31 … 2015-03-31 24.37% 15.40% 1.078x
46 2010-04-30 … 2015-04-30 23.11% 15.38% 1.067x
47 2010-05-28 … 2015-04-30 24.84% 17.09% 1.066x
48 2010-06-30 … 2015-06-30 25.60% 17.45% 1.069x
49 2010-07-30 … 2015-06-30 25.38% 16.43% 1.077x
50 2010-08-31 … 2015-08-31 22.95% 15.76% 1.062x
51 2010-09-30 … 2015-09-30 21.37% 13.61% 1.068x
52 2010-10-29 … 2015-09-30 20.76% 13.06% 1.068x
53 2010-11-30 … 2015-11-30 21.15% 15.09% 1.053x
54 2010-12-31 … 2015-12-31 19.57% 13.55% 1.053x
55 2011-01-31 … 2016-01-29 18.32% 11.90% 1.057x
56 2011-02-28 … 2016-01-29 17.60% 11.53% 1.054x
57 2011-03-31 … 2016-03-31 18.40% 12.90% 1.049x
58 2011-04-29 … 2016-04-29 17.29% 12.39% 1.044x
59 2011-05-31 … 2016-05-31 18.16% 12.94% 1.046x
60 2011-06-30 … 2016-06-30 19.01% 13.30% 1.050x
61 2011-07-29 … 2016-07-29 18.81% 14.52% 1.038x
62 2011-08-31 … 2016-08-31 17.63% 15.19% 1.021x
63 2011-09-30 … 2016-09-30 18.21% 16.32% 1.016x
64 2011-10-31 … 2016-10-31 15.03% 14.02% 1.009x
65 2011-11-30 … 2016-11-30 14.69% 14.66% 1.000x
66 2011-12-30 … 2016-12-30 13.73% 14.92% 0.990x
67 2012-01-31 … 2017-01-31 13.88% 14.63% 0.994x
68 2012-02-29 … 2017-02-28 12.66% 14.78% 0.982x
69 2012-03-30 … 2017-02-28 11.98% 14.43% 0.979x
70 2012-04-30 … 2017-04-28 11.78% 14.61% 0.975x
71 2012-05-31 … 2017-05-31 14.21% 15.98% 0.985x
72 2012-06-29 … 2017-05-31 13.59% 15.44% 0.984x
73 2012-07-31 … 2017-07-31 14.18% 15.43% 0.989x
74 2012-08-31 … 2017-08-31 14.79% 15.12% 0.997x
75 2012-09-28 … 2017-08-31 14.43% 14.77% 0.997x
76 2012-10-31 … 2017-10-31 17.17% 16.12% 1.009x
77 2012-11-30 … 2017-11-30 17.50% 16.79% 1.006x
78 2012-12-31 … 2017-12-29 17.45% 16.93% 1.004x
79 2013-01-31 … 2018-01-31 17.84% 17.57% 1.002x
80 2013-02-28 … 2018-02-28 17.30% 16.21% 1.009x
81 2013-03-28 … 2018-02-28 16.37% 15.81% 1.005x
82 2013-04-30 … 2018-04-30 14.59% 14.25% 1.003x
83 2013-05-31 … 2018-05-31 16.15% 14.57% 1.014x
84 2013-06-28 … 2018-05-31 17.12% 14.97% 1.019x
85 2013-07-31 … 2018-07-31 15.85% 14.83% 1.009x
86 2013-08-30 … 2018-07-31 16.73% 15.59% 1.010x
87 2013-09-30 … 2018-09-28 16.45% 15.84% 1.005x
88 2013-10-31 … 2018-10-31 13.94% 12.89% 1.009x
89 2013-11-29 … 2018-10-31 13.20% 12.60% 1.005x
90 2013-12-31 … 2018-12-31 10.89% 9.93% 1.009x
91 2014-01-31 … 2019-01-31 11.67% 12.37% 0.994x
92 2014-02-28 … 2019-02-28 11.11% 12.38% 0.989x
93 2014-03-31 … 2019-03-29 12.47% 12.76% 0.997x
94 2014-04-30 … 2019-04-30 13.59% 13.73% 0.999x
95 2014-05-30 … 2019-04-30 12.89% 13.54% 0.994x
96 2014-06-30 … 2019-06-28 11.98% 12.81% 0.993x
97 2014-07-31 … 2019-07-31 12.17% 13.30% 0.990x
98 2014-08-29 … 2019-07-31 11.74% 12.80% 0.991x
99 2014-09-30 … 2019-09-30 12.21% 12.70% 0.996x
100 2014-10-31 … 2019-10-31 11.55% 12.91% 0.988x
101 2014-11-28 … 2019-10-31 11.25% 12.60% 0.988x
102 2014-12-31 … 2019-12-31 12.95% 14.16% 0.989x
103 2015-01-30 … 2019-12-31 12.68% 14.85% 0.981x
104 2015-02-27 … 2020-01-31 12.49% 14.04% 0.986x
105 2015-03-31 … 2020-03-31 8.06% 8.56% 0.995x
106 2015-04-30 … 2020-04-30 11.87% 11.65% 1.002x
107 2015-05-29 … 2020-05-29 12.35% 12.61% 0.998x
108 2015-06-30 … 2020-06-30 13.16% 13.64% 0.996x
109 2015-07-31 … 2020-07-31 15.05% 14.60% 1.004x
110 2015-08-31 … 2020-08-31 17.89% 18.07% 0.999x
111 2015-09-30 … 2020-09-30 16.49% 17.05% 0.995x
112 2015-10-30 … 2020-10-30 14.76% 14.60% 1.001x
113 2015-11-30 … 2020-11-30 15.67% 17.43% 0.985x
114 2015-12-31 … 2020-12-31 17.02% 18.65% 0.986x
115 2016-01-29 … 2021-01-29 17.93% 19.26% 0.989x
116 2016-02-29 … 2021-02-26 20.82% 19.79% 1.009x
117 2016-03-31 … 2021-03-31 19.60% 19.42% 1.002x
118 2016-04-29 … 2021-03-31 20.32% 19.66% 1.006x
119 2016-05-31 … 2021-05-28 20.87% 20.42% 1.004x
120 2016-06-30 … 2021-06-30 19.73% 21.06% 0.989x
121 2016-07-29 … 2021-06-30 20.06% 20.63% 0.995x
122 2016-08-31 … 2021-08-31 23.48% 21.75% 1.014x
123 2016-09-30 … 2021-09-30 21.32% 20.22% 1.009x
124 2016-10-31 … 2021-10-29 24.47% 22.50% 1.016x
125 2016-11-30 … 2021-11-30 23.33% 21.87% 1.012x
126 2016-12-30 … 2021-11-30 23.84% 21.75% 1.017x
127 2017-01-31 … 2022-01-31 20.90% 20.17% 1.006x
128 2017-02-28 … 2022-02-28 20.00% 18.51% 1.013x
129 2017-03-31 … 2022-03-31 21.46% 19.46% 1.017x
130 2017-04-28 … 2022-03-31 21.49% 19.46% 1.017x
131 2017-05-31 … 2022-05-31 19.97% 15.59% 1.038x
132 2017-06-30 … 2022-06-30 17.97% 13.08% 1.043x
133 2017-07-31 … 2022-07-29 17.34% 15.16% 1.019x
134 2017-08-31 … 2022-08-31 17.06% 13.72% 1.029x
135 2017-09-29 … 2022-08-31 16.75% 13.56% 1.028x
136 2017-10-31 … 2022-10-31 19.50% 11.86% 1.068x
137 2017-11-30 … 2022-11-30 19.78% 12.52% 1.064x
138 2017-12-29 … 2022-11-30 20.04% 12.46% 1.067x
139 2018-01-31 … 2023-01-31 17.77% 11.01% 1.061x
140 2018-02-28 … 2023-02-28 15.78% 11.03% 1.043x
141 2018-03-29 … 2023-02-28 16.51% 11.72% 1.043x
142 2018-04-30 … 2023-04-28 16.85% 13.01% 1.034x
143 2018-05-31 … 2023-05-31 16.14% 12.95% 1.028x
144 2018-06-29 … 2023-05-31 16.39% 13.01% 1.030x
145 2018-07-31 … 2023-07-31 18.60% 14.67% 1.034x
146 2018-08-31 … 2023-08-31 16.63% 13.51% 1.028x
147 2018-09-28 … 2023-08-31 17.09% 13.56% 1.031x
148 2018-10-31 … 2023-10-31 15.83% 12.60% 1.029x
149 2018-11-30 … 2023-11-30 17.04% 14.58% 1.021x
150 2018-12-31 … 2023-12-29 19.27% 17.26% 1.017x
151 2019-01-31 … 2024-01-31 20.06% 16.27% 1.033x
152 2019-02-28 … 2024-01-31 20.10% 15.94% 1.036x
153 2019-03-29 … 2024-03-28 22.96% 17.50% 1.046x
154 2019-04-30 … 2024-04-30 21.28% 15.50% 1.050x
155 2019-05-31 … 2024-05-31 23.78% 18.12% 1.048x
156 2019-06-28 … 2024-06-28 22.99% 17.99% 1.042x
157 2019-07-31 … 2024-07-31 22.24% 17.70% 1.039x
158 2019-08-30 … 2024-08-30 23.21% 18.41% 1.041x
159 2019-09-30 … 2024-09-30 23.79% 18.65% 1.043x
160 2019-10-31 … 2024-10-31 23.78% 17.87% 1.050x
161 2019-11-29 … 2024-11-29 25.66% 18.64% 1.059x
162 2019-12-31 … 2024-12-31 23.21% 17.62% 1.048x
163 2020-01-31 … 2025-01-31 24.12% 18.07% 1.051x
164 2020-02-28 … 2025-02-28 25.08% 19.00% 1.051x
165 2020-03-31 … 2025-03-31 24.66% 19.24% 1.045x
166 2020-04-30 … 2025-04-30 21.51% 16.49% 1.043x
167 2020-05-29 … 2025-04-30 21.02% 15.80% 1.045x
168 2020-06-30 … 2025-06-30 20.80% 18.19% 1.022x
169 2020-07-31 … 2025-07-31 19.02% 17.87% 1.010x
170 2020-08-31 … 2025-08-29 18.76% 16.69% 1.018x
171 2020-09-30 … 2025-09-30 22.84% 18.57% 1.036x
172 2020-10-30 … 2025-09-30 23.71% 19.43% 1.036x
173 2020-11-30 … 2025-11-28 24.06% 17.77% 1.053x
174 2020-12-31 … 2025-12-31 23.99% 16.92% 1.060x
175 2021-01-29 … 2025-12-31 23.86% 17.20% 1.057x
176 2021-02-26 … 2026-01-30 24.40% 17.04% 1.063x
177 2021-03-31 … 2026-03-31 22.79% 14.07% 1.076x
178 2021-04-30 … 2026-04-30 27.19% 16.03% 1.096x
179 2021-05-28 … 2026-04-30 27.28% 16.22% 1.095x
Notes
mode=explore; family=contrarian-52w-recovery-quality-regime-momentum-hybrid This variant combines four orthogonal ideas into an explicit arbitration system rather than a static blend: deep-52-week contrarian repair, early recovery confirmation, durable quality support, and trend momentum continuation. The structure is intentionally distinct from the parent relay because the regime branch does not merely reweight sleeves; it changes which conflicts are permitted. In panic and stressed tapes, broken names only score if they show concrete repair plus internal quality support. In neutral tapes, repaired recoveries can outrank pure momentum when extension is limited and durability is better. In risk-on tapes, momentum can dominate, but only if overextension, volatility, and low-quality internals do not trigger crowding taxes. The arbitration is explicit: each stock receives sleeve scores for repair, momentum, and durability, then branch-specific gates decide whether to reward convergence, suppress contradiction, or route capital to the strongest justified sleeve. Deliberate metric coverage this run: momentum uses return_1m_pct, return_3m_pct, return_6m_pct, return_12m_pct, and momentum_12_1_pct; trend/recovery uses from_200d_ma_pct and from_52w_high_pct; volatility uses realized_vol_3m; liquidity uses avg_daily_volume_3m, avg_daily_dollar_volume_3m, and trading_days_3m; income uses dividend_yield_ttm_pct and dividend_ttm as secondary ballast; valuation uses pe, forward_pe, and peg; growth uses eps_growth_pct, revenue_growth_pct, operating_income_growth_pct, free_cash_flow_growth_pct, and forward_eps; quality uses operating_margin_pct and free_cash_flow_margin_pct; size uses market_cap as a crowding/fragility tilt rather than a direct preference. Deliberate weight-0 metrics this run: shares_outstanding, close, adj_close, high_52w, ma_200d, eps_ttm, revenue_ttm, operating_income_ttm, and free_cash_flow_ttm. Correlated momentum features are separated by sleeve role, valuation is only active where quality/growth can justify it, and sparse fundamentals are normalized by present weight so missing fields do not automatically dominate or disqualify a stock.
Lesson notes
#890 · degrade · relative_return Δ -0.3500 · parent exp_1174 · Jul 21, 2026 · auto/explore; benchmark CAPW_UNIV
explore/contrarian-52w-recovery-quality-regime-momentum-hybrid: relative_return 1.0333x (delta -0.3500 vs exp_1174); win-rate 81.0056%, worst-window 0.975284, dispersion 5.4828%.
Monthly picks — top stocks selected each month (whole timeline)
timeline — 240 months · top 15 each
Month 123456789101112131415
2006-07-31 T CPB LH BAC DGX LMT PEP MO WFC PFG FE DIS L PPL PNC
2006-08-31 T LH MRK BXP DGX VNO LMT MO L EQR SLG AVB CPB AIV BAC
2006-09-29 T BAC LMT MRK MS JPM VNO BXP WFC LNC HOG ORCL VZ ALL GILD
2006-10-31 T GS AIV KSS MRK CMCSA VNO HPQ EQR MS HOG INTU SPG APH OKE
2006-11-30 NEE ETR MAT GS MRK MS CMCSA CSCO DDR SPG T VFC LMT OKE MCD
2006-12-29 CMCSA ETR NEE TWX CNP ES MCD GS OKE VNO MAT VFC HPQ T SRE
2007-01-31 HPQ GS MS NEE TWX CMCSA CNP LMT NKE HAS ETR T DIS MCD MAR
2007-02-28 NEE MAT ETR SRE SYK CNP T HAS LMT AEP NKE ABT PRU BAX MCD
2007-03-30 NEE MTCH T AEP DUK MAT ETR MCD SYK AZO LMT BAX PEG SRE MO
2007-04-30 CI ETR NEE MCD AEP PEG BAX MTCH MO SRE CVX T FE ETN ES
2007-05-31 CI CVX MCD HON HPQ T ETR VZ EIX GS PH IBM BAX XOM MO
2007-06-29 MCD HPQ CI CVX HON XOM PH MHK COP APA T ETN L AZO VZ
2007-07-31 HPQ MMM HON IBM PH DJ CVX RTX GE COP ETN HCR MCD LIN CI
2007-08-31 COP CVX HPQ IBM MMM HON XOM RTX KLAC OXY URI GE CAT GOOG DVN
2007-09-28 COP CVX HAL HPQ APA RTX IBM XOM MMM OXY EBAY HON BIIB GE DE
2007-10-31 OXY HPQ APA COP HAL CVX DVN EXPE XOM MO NKE RTX GE GOOGL DE
2007-11-30 HPQ MO MRK KO YUM NKE D DHR LMT CL CVX MCD WAT BRK-B PEP
2007-12-31 HPQ MO D VLO MRK BRK-B DHR HAL NEE MCD YUM CVX RTX DVN COP
2008-01-31 MO ESRX RTX HUM BRK-B SO COP CL LMT CRL PEG FE KO BAX NOC
2008-02-29 HAL ABT CVX PEG AFL BRK-B CL XOM BAX RTX LMT NOC WMT NKE D
2008-03-31 ABT HAL MO AFL CF CAG DVN CL WMT WHR IBM WDC OXY D BAX
2008-04-30 HAL OXY CVX DVN CAG ABT EQT IBM D COP WMT AFL XOM EXC AON
2008-05-30 HAL OXY APA D DVN CSX UNP IBM CVX FMC ABT NBR COP EQT ADI
2008-06-30 HAL D WDC OXY MA ABT COP CVX FE PEG TTWO BKNG EXC EQT IBM
2008-07-31 ABT D EW HAL WDC WWY BAX MEE BTUUQ BKNG OXY IBM ESV CPB X
2008-08-29 CF MCD D AON ABT BAX SRCL HRS MHS ACS RTN STJ SCHW ANSS CXO
2008-09-30 ABT MCD ED CPB D AON BAX HAS PRGO HPQ ROST CLX APOL GIS EW
2008-10-31 ABT AON MCD ED D CPB WWY CHD MO BAX CAG HPQ MDLZ KMB HAS
2008-11-28 ABT AON MCD ED D KR CPB CLX CHD SJM KMB PRGO HSY WEC BAX
2008-12-31 ABT AON MCD BMY ED CAG DLTR AMGN SHW KR CPB DGX CHD CL EW
2009-01-30 ABT BMY MCD XOM CAG ED AON EW CVX DLTR AEP MDLZ SJM LDOS PCG
2009-02-27 ABT MCD AON CAG BMY ED XOM PCG EW CPB LDOS AEP XEL BAX CVX
2009-03-31 BMY CVX ED BKNG CAG AAPL AON ADI IBM WBD CF ABT EW VTRS MCD
2009-04-30 AON AAPL WBD IBM BR NFLX MNST BMY UPS AZO CVX GPS ROST OXY AAP
2009-05-29 EBAY AAPL WBD OXY CAG BMY WDC IBM ROST TJX RTX MCD YUM NEE CF
2009-06-30 AAPL WBD EBAY CAG MSFT IBM FISV TJX ELV ORCL BMY GOOG AMGN NEE ROST
2009-07-31 AAPL WBD BMY TJX AMGN FIS ROST IBM MCHP MMM FISV MSFT CAG CSCO OXY
2009-08-31 AAPL WBD EBAY BMY MSFT MTCH TRV MMM ROST TGT CAG HPQ KDP IBM BSX
2009-09-30 WBD AAPL MTCH CAG BMY MA HPQ KDP ROST JCI MCK GS EQIX RTX MMM
2009-10-30 WBD AAPL EBAY MSFT MCK TT MA HPQ GOOGL RTX COR JCI IBM CL TWX
2009-11-30 WBD AAPL MSFT GOOG MCK GOOGL HPQ EBAY RTX GS ITW BMY IBM BEN MA
2009-12-31 BKNG GOOG MSFT WBD GOOGL AAPL MA CCI IBM MMM V NFLX CAH ADBE COR
2010-01-29 BKNG WBD MSFT WLL GIS RTX EW PFE MA CCI SYK CAG PXD MMM TDG
2010-02-26 SYK CAG WBD AAPL OKE GIS COR CCI GE RTX SPG DIS EW DTE K
2010-03-31 XRX ISRG CI WBD AAPL SYK HON DIS EW WFC SPGI COR BTUUQ MJN MEE
2010-04-30 BBWI AAPL WBD JOY HON MEE A FTR NTAP XEC BTUUQ RHT GGP MJN DISCA
2010-05-28 BBWI WBD AAPL HON CMCSA TJX DTE ROST K GIS EW CSX YUM TSN TWX
2010-06-30 AAPL BBWI BMY NEM WBD SBUX DLTR GIS CB ISRG MCK TRV DTE HON MO
2010-07-30 HAS AAPL BMY NEM KDP DLTR AZO WBD MO PEG CMCSA CB PGR COP EW
2010-08-31 BMY NEM CB AAPL COP ED AZO D BBWI LLY CASY T CCI MCD KDP
2010-09-30 BBWI AAPL COP BMY NEM TXN CB INTU AZO LUMN ADI MO T CMS CCI
2010-10-29 AAPL TXN BMY ADI NEM CB F LUMN LYB SBUX DLTR CMS MO EMN HAS
2010-11-30 TXN AAPL MCHP ADI NTAP HON COP ETN SBUX DLTR CB EBAY LRCX SPGI AAP
2010-12-31 TXN ADI BBWI COP BKNG ETN HON AAPL DE PH OXY LUMN NTAP EXPD AZO
2011-01-31 TXN ADI COP AAPL MCHP LULU HON DE QCOM PH OXY ETN XOM BBWI NTAP
2011-02-28 COP TXN ADI AAPL QCOM MU HON CVX XOM MCHP HOG OKE BBWI DE CSX
2011-03-31 COP KLAC TER XOM WYNN CVX TXN ADI MCHP AAPL CAT KKR CSX OKE MU
2011-04-29 COP MCHP TXN CVX XOM CAT DHR OXY PM HUM PRGO MSI QCOM ELV OKE
2011-05-31 BKNG BBWI MCHP LULU CAT WYNN PM KKR ELV CVX SPG AXP T PFE MA
2011-06-30 BKNG BBWI MCO D WYNN CF SPG AXP ELV MA CAT OKE HUM CNP QCOM
2011-07-29 D AAPL COP SPG BBWI CVX OKE CNP DLTR AXP BIIB BAX MCO MNST COO
2011-08-31 AAPL BIIB MSFT PM COP VZ KO CVX TJX IBM OKE DUK ISRG FCX V
2011-09-30 AAPL CF BKNG DUK VZ XOM MSFT V BIIB KO MA INTC CL COP CAG
2011-10-31 AAPL INTC DLTR DUK BKNG V VZ DG ADI BBWI MA VFC WBD AZO NI
2011-11-30 KLAC MA AAPL PFE INTC DLTR XOM ISRG V TJX BKNG VZ MTCH MCO CVX
2011-12-30 PFE AAPL CF XOM MA PM ISRG V OKE TJX INTC BKNG VZ CVX GE
2012-01-31 AAPL PFE TJX GRMN INTC MA BKNG V DLTR DG GWW SHW YUM CAG CAT
2012-02-29 AAPL V MSFT TJX ISRG KLAC CAT SHW INTC CMCSA EBAY AZO MTCH HD YUM
2012-03-30 AAPL CF WBD QCOM MSFT EBAY INTC MTCH ISRG V CMCSA BBWI SHW PVH SPG
2012-04-30 AAPL WBD KLAC MSFT ISRG V TJX PM SPG MTCH WFC INTC QCOM PFE AZO
2012-05-31 AAPL BKNG WBD SPG NEE STX ISRG V ORLY CMCSA YUM CF SBAC SRE WFC
2012-06-29 AAPL WBD STX SPG NEE V CMCSA SBAC DG SRE KMB ISRG DIS SHW ROST
2012-07-31 AAPL NEE BKNG V KMB SPG CMCSA AEP CHD KLAC WBD MRK SRE WEC DIS
2012-08-31 AAPL ALL CMCSA SPG KLAC GE SBAC DIS MTCH MO WBD GILD AMGN MRK AEP
2012-09-28 STX AAPL ALL VLO EBAY WBD GE CMCSA WDC DIS SBAC EOG SHW AMGN HD
2012-10-31 ALL CF WBD CMCSA GE AAPL SBAC GILD MDT AEP VLO AMGN MRK TWX DIS
2012-11-30 ALL AMGN CMCSA CF BKNG SBAC GE TRV WBD AMT GS BAX LLY VTRS NEE
2012-12-31 STX AMGN ALL EBAY NWL CMCSA GS SBAC AMT WBD ORCL CCI GILD TRV MCO
2013-01-31 STX ALL WBD LEN CSCO TRV KKR NWL CMCSA EXR APTV ORCL GILD MA PPG
2013-02-28 ALL GS STX WBD TRV WDC GILD CMCSA EBAY NWL GE STT AMGN SYK CAG
2013-03-28 ALL KKR AMGN TRV HON GS PFE GILD MA GIS CI CMCSA HSY CB CLX
2013-04-30 ALL AMGN STX COR NWL TWX GIS PFE KR CI GILD TRV HSY NRG LEG
2013-05-31 MCO VLO GS JPM KKR ALL GILD DIS HON NWL KR WFC MA COR PHM
2013-06-28 JPM MCO CSCO MA WFC GS ALL HON DIS GOOG STZ GILD COR SLM BRK-B
2013-07-31 BKNG WDC STX JPM CSCO WFC RTX MA ALL GS PKG ELV HON TSN CBOE
2013-08-30 MA CI RTX MCO JNJ ELV SPGI WFC GHC PKG ECL COR GILD HON ORLY
2013-09-30 MA RTX URI GILD TXN HII MCK HON WYNN ECL DOV COR GHC CMI PGR
2013-10-31 MA META BX FLT SPGI V ADS CELG GILD HBI SIVB SBUX COR PXD REGN
2013-11-29 MA REGN COR OMX MS META PFE NKE MCO BA MSFT BR WYNN SPGI ICE
2013-12-31 BKNG MA ABBV AOS META V BR MCK PSX STZ AMP IBKR MCO ICE CAH
2014-01-31 BKNG MA V MSFT PSX RTX ESRX TT VFC GOOGL WFC AZO COR CMCSA LHX
2014-02-28 BX MU V META MA MCO SPGI GOOG MSFT AZO MAR GILD RTX WFC CAH
2014-03-31 BKNG BX MSFT WYNN EOG MU BAC GD MTCH WFC META MCHP SPGI FITB MCK
2014-04-30 EOG BKNG WFC RCL GD MSFT GLW MCHP SLB ORCL WYNN BX META UNP AAPL
2014-05-30 META EOG SLB COP LYB GD VNO AAPL AEP WFC OKE GLW HAL BKR MCHP
2014-06-30 META COP LUV FRX SLB GD LYB AAPL GILD AEP BX JNJ BALL MO WFC
2014-07-31 MU BKNG COP EOG MSFT AAPL BX SLB KLAC NOV GD META BALL CBRE COR
2014-08-29 MU META WDC AAPL BX IVZ MCO HAL GILD EOG DAL COP DIS GD INTC
2014-09-30 GILD URI WDC UNP VZ GD MS MCO MSFT AAPL IVZ KR DIS MO DLR
2014-10-31 GILD MU META GD MCO MS AAPL AEP URI ABBV MO DLR KDP KR TRV
2014-11-28 AAPL META GILD KR ABBV GD ED MCO V MO KDP AMGN AEP SO DLR
2014-12-31 WELL AEP ALL AAPL ED GD EQR AVB EIX LRCX MU PNW AMGN SO WEC
2015-01-30 ALL WELL RCL BX AEP SHW KDP LRCX ED GILD AMAT AVB EIX ESS TXN
2015-02-27 KR BX COR SHW CI TXN ALL DRI MAC RCL LRCX AAPL EXR BBWI ESS
2015-03-31 AAPL CI SBUX BX TXN DLTR SHW ULTA META AET KDP FISV ESS MO ZTS
2015-04-30 BX AAPL CI SBUX COR ULTA DRI DDS MCO VMC KMI FDS SHW MSCI BBWI
2015-05-29 GILD BX SBUX COR AAPL JPM MCO FDS GS DIS SHW EFX BNY BK AZO
2015-06-30 GILD BX JPM AAPL GS MCO DIS MA ABT EBAY SNA SWK COR NKE FDS
2015-07-31 GILD SBUX JPM GS DIS KR MCO ORLY NKE ABT MA MTG KRFT ACN PGR
2015-08-31 SBUX VLO GILD PGR CCI JPM DRI MO MDLZ CCL CPB NKE ULTA AYI GD
2015-09-30 PGR MO CCI HAS NEE DRI HUM STZ WEC PSA CLX NVR ED MDLZ AVB
2015-10-30 SBUX MO VLO CCI PGR STZ BBWI KDP AZO INTC PSA ACN CLX NVR CDW
2015-11-30 MO PLD GOOGL PSX LUV SBUX PSA CDNS BBWI ACN V STZ PAYX HD MAS
2015-12-31 VLO MO CCI PSA BKNG PLD GOOGL AMGN MCD CLX HD STZ V NEE SBUX
2016-01-29 KLAC NEE MO CCI TAP PSA CLX KDP KMB ADBE MCD GOOGL GOOG LHX PM
2016-02-29 T VZ KLAC AEP KMB XEL CCI CMS PM ISRG ATO ED AWK NI PGR
2016-03-31 T VZ KLAC PM AEP ISRG NI ED ATO PGR CMS XEL PSA AWK MKC
2016-04-29 T KLAC ISRG VZ PM ITW MRSH EMR ED DLR AEP HAS CINF SYK CDNS
2016-05-31 T KLAC DLR ADBE VZ META ISRG SPGI EQIX CDNS SYY XYL PM CCI ZBH
2016-06-30 T CCI VZ EQIX KLAC WM MO ISRG EVRG CNP EIX WEC SYY CMS SYK
2016-07-29 T KLAC CCI VZ ISRG DLR TXN AWK CNP IRM CSCO WM BSX NI HII
2016-08-31 T SPGI META CSCO INTU ISRG TXN GIS ALGN AMGN VTR ULTA MSFT PLD HII
2016-09-30 SPGI META ABBV DHR GEN ISRG AMGN CSCO MSFT T ADBE ITW AMZN GLW TSN
2016-10-31 SPGI META DHR BKNG MSFT GEN HPQ CSCO ADBE AMAT GLW PG TXN YUM ISRG
2016-11-30 SPGI KLAC BKNG TXN QCOM MSFT T JPM AMAT HPQ YUM GLW DHR GRMN WM
2016-12-30 MS JPM AMAT KLAC T DHR MSFT ADI FDX TXN USB DAL PFG CSX PSKY
2017-01-31 MS NVDA IP JPM IBM T DD TXN LUV ADI TT MSFT UNP HLT GM
2017-02-28 JPM MS SPGI ADBE AAPL META MTB NVDA UNM CSCO MSFT GEN IBM CHTR USB
2017-03-31 AMAT META SPGI ADBE ADI TXN MSFT EBAY AXP MO MHK NVDA AAPL GS CHTR
2017-04-28 AMAT META ADBE SPGI MSFT CHTR CCL MHK AAPL EBAY ADI TXN ISRG GEN NVDA
2017-05-31 META BKNG MSFT ADBE AAPL GOOGL SPGI EBAY CCL RCL MO ALL GOOG AMT NEE
2017-06-30 AMAT LRCX SPGI NVDA BX META ADBE MSFT CCL RCL BKNG ISRG EBAY GOOGL ALL
2017-07-31 AMAT SPGI META ADBE ALL BX MSFT AET CCL NEE ISRG RCL MS PGR MU
2017-08-31 META AMAT PGR BA SPGI NVDA NEE ALL BX ADBE CCL MSFT AMT CBOE ABBV
2017-09-29 NVDA RCL META BA SPGI BX MCHP CBOE MSFT MA NEE TXN GS V ADBE
2017-10-31 BA TXN ABBV RCL MCHP CBOE TROW SPGI JPM MSFT MTD LHX BAC MS META
2017-11-30 MU LRCX ON AMAT INTC TXN BA NVDA META ADBE ISRG ALL MSFT HLT MAR
2017-12-29 MU TXN LRCX BA ALL PGR AMAT META INTC NVDA CBOE PHM ADBE MAR FTNT
2018-01-31 MU TXN ABBV MSFT LRCX CBOE MAR JPM BAC ODFL HLT CSCO MS HD VFC
2018-02-28 TXN BX MA JPM NVDA MSFT NXPI BAC PGR ZTS EL ACN TEL META CTSH
2018-03-29 MU ANET AMAT NEE PSX ADBE PGR BA MA MCO NXPI CTSH NVDA EL XYL
2018-04-30 MU PSX MPC PGR NEE KDP MCO ADBE BR PFE PTC BA EL MA ALL
2018-05-31 PSX V BKNG MCO FCX PGR PFE OXY MA ANET EXR VFC INTU PTC URI
2018-06-29 MU PSX V MCO INTU META MSCI ADBE PFE ANET BKNG OKE SYY MA OXY
2018-07-31 MU PSX V PFE ADBE MCO TJX INTU VRSN MA MSFT MSCI AAPL CNC ISRG
2018-08-31 PFE MU PSX V PGR MCO VZ WAB DIS CTAS ELV KKR VRSN AAPL BDX
2018-09-28 PFE PGR TJX V ELV DIS AAPL INTU MRK ADBE NVDA AET PSX VRSN SHW
2018-10-31 PFE VZ TJX PGR DIS HCA AAPL ROST SPG AET CMCSA NEE ROL AEP PEG
2018-11-30 PFE VZ MRK MKC ESRX CMCSA SBUX AET CME NEE DIS KDP YUM BALL PEG
2018-12-31 PFE VZ MKC ESRX SBUX NEE YUM EXC KDP FE CMCSA BALL XEL LW ETR
2019-01-31 AVGO SBUX PFE DOC EXC BALL WELL CNP EXR VTR AIV NEE YUM XEL EQR
2019-02-28 AVGO PGR SBUX BALL AES MRK PFE PEG FE XEL SO REGN ETR EXC VZ
2019-03-29 AES BALL PGR KMI ADI LIN INTC XEL PEP MSFT WELL SO PAYX WEC MDLZ
2019-04-30 MSFT PEP ADI CSCO HON APD PAYX MA V AVGO PGR LIN TDG ROP BALL
2019-05-31 PEP MSFT SO MDLZ CDNS BALL HON LIN LLY CCI MA PGR APD WM KO
2019-06-28 MTCH MSFT LIN AXP HON PEP APD PGR MDLZ HSY LULU WM PHM FDS MSI
2019-07-31 MSFT SYK LIN AXP CINF PGR SNPS PEP BALL FIS ZTS WM MA APD SO
2019-08-30 MSFT HSY PEP KO CCI WEC SBAC SO SYK ETR QCOM LMT APD VRSK SBUX
2019-09-30 SO ETR PEP HSY WEC KO MSFT ES FE T CCI XEL WELL BKNG CINF
2019-10-31 BMY PHM SO ETR VRTX MSFT PEP T INVH WEC MAA DOC EQIX AMGN SHW
2019-11-29 BMY TER KLAC MSFT QCOM AMGN JPM PSX AAPL BF.B BF-B SO INTC LIN PLD
2019-12-31 MSFT AMGN BMY JPM VRTX QCOM FTNT BAC XRX C MCO SPGI GOOGL TYL GS
2020-01-31 MSFT BMY LLY SO LMT SPGI VRTX QCOM TER AMGN INTC GOOGL ANSS JPM NEM
2020-02-28 BMY MSFT VRTX LLY TYL KO PEP FTNT GOOGL QCOM ZTS SO NEE MCO AON
2020-03-31 NEM ABBV QCOM MSFT PGR LLY ENPH DVA TYL CSGP VRTX VZ BMY ALL AMT
2020-04-30 NEM LLY ABBV MSFT GEN GIS KR PGR CLX VZ PFE QCOM REGN EA AMT
2020-05-29 NEM LLY ABBV ANET CLX MSFT QCOM GIS GEN WST KR BIO TYL REGN VRTX
2020-06-30 EBAY ABBV NEM MSFT CDNS QCOM SPGI ENPH AAPL LOW CLX ADBE EA GIS INTC
2020-07-31 EBAY ABBV CDNS QCOM MSFT SPGI LOW ADBE KLAC CLX AAPL DHR URI SIVB CDAY
2020-08-31 EBAY CDNS META LOW PG NEM ADBE ABBV TER MSFT ETSY REGN TSCO PGR SPGI
2020-09-30 LOW CDNS META EBAY PG PGR SPGI DHR CHTR AAPL BBY MCO ABBV ORLY ADBE
2020-10-30 LOW PG PGR DHR META ABMD VAR BBY CTLT DG TXN BALL CPRT NVDA CDAY
2020-11-30 MS ABMD ABBV NOW QCOM CDNS CTLT TGT FDX DE PG DHR MPWR CDAY BLK
2020-12-31 AMAT LRCX KLAC MS ABBV NOW ABMD URI DE CTLT AMD TGT AAPL PGR AVGO
2021-01-29 AMAT MS TER ABBV LRCX TGT TUP GS CDNS ABMD AVGO EBAY SIVB DE TRMB
2021-02-26 ENPH MS CDNS ABBV TUP GS AVGO JPM MPWR FFIV XEC PYPL SIVB ABMD TGT
2021-03-31 ETSY GS MS JPM EBAY DVN SPG JCI LOW KKR C DE FTNT GOOGL ENPH
2021-04-30 AMAT GS MS LRCX ETSY KLAC KKR LEN URI DHI DELL JPM JCI DE C
2021-05-28 KKR MS AMAT GS ALL PHM ORCL JPM DHI C URI TGT ADM IQV BRK-B
2021-06-30 BX GS KKR TGT MS FCX GOOGL XEC EXR JPM BIG DE META INTU JCI
2021-07-30 GS TGT MS GOOGL ORCL SIVB INTU GOOG ORLY FCX BX EXR AMAT IDXX XEC
2021-08-31 MRNA KKR GOOGL GS PKI KSU A MS FRC GOOG DHR MMC EXR TGT INTU
2021-09-30 BX MRNA GOOGL KKR SIVB GS WFC SBNY CB DHR MS JPM PKI AMD ORCL
2021-10-29 GS MRNA GOOGL CB ORCL AVGO WFC JPM MS SBNY SIVB MSFT MRSH TMO ACN
2021-11-30 MRNA KKR COP AVGO SPG GOOGL AZO MSFT EOG REGN ORCL GILD TMO AAPL CPT
2021-12-31 PFE KKR BX AMD AVGO FCX SPG GILD COP REGN EXR ZTS GOOGL TMO NVDA
2022-01-31 PFE WFC CVX ON KLAC AVGO BX GILD CB MO ABBV EXC KKR SPG EXR
2022-02-28 WFC CVX REGN WY MCK CB EXC ABBV PFE MO COR WMB NI BRK-B AVGO
2022-03-31 ABBV REGN COP FCX CVX EOG PFE CB EXC MCK XOM BRK-B WMB BMY WY
2022-04-29 REGN ABBV COP PFE CVX FCX BMY MCK EXC CB WMB XOM SRE COR ADM
2022-05-31 PFE REGN ABBV CVX XOM MOS MRK BMY EXC GILD MCK WY SRE WRB CNP
2022-06-30 ABBV PFE EOG CF OXY REGN BMY XOM GILD MRK DVN CVX T MRO APA
2022-07-29 PFE ABBV XOM EOG CVX MPC MOS COP MCK APA REGN GILD BMY SRE MRK
2022-08-31 VRTX XOM CVX AZO MOS GPC HSY LW ABBV WM GIS RSG HUM VICI PFE
2022-09-30 DVN COP EOG OXY XOM CVX MRO PFE GPC MCK HSY ABBV LW MOS APA
2022-10-31 CVX XOM VRTX ABBV MCK AMGN GPC AZO PFE MRK BMY CAH LW GIS HUM
2022-11-30 XOM ABBV EOG CVX AIG CF MPC MRK AMGN VRTX COP PSX APA AFL GPC
2022-12-30 CVX XOM AIG PSX COP EOG BKNG MPC MRK ABBV MO AVGO AMGN AFL EMR
2023-01-31 MPC AIG XOM VRTX EOG VLO AVGO COP MRNA T AON CAT CVX ULTA ACGL
2023-02-28 AVGO MPC XOM ABBV ULTA LEN AIG MO ADI T CAT KLAC JPM MRK SLB
2023-03-31 AVGO URI ADI DHI XOM ULTA VRTX ORCL PSX NXPI V BSX TXN BWA MNST
2023-04-28 AVGO ADI XOM LW ANET VRTX CPRT BSX BKNG KLAC ULTA ORCL MCHP GIS MO
2023-05-31 BKNG PHM LEN GE VRTX LW ADI MNST MDLZ ORCL HSY BSX PCG DHI AON
2023-06-30 BKNG AVGO GE ORCL VRTX ABNB CAH ADI HCA AON AAPL CPRT MAR LW FISV
2023-07-31 AVGO GE EOG ORCL DAL MAR ADI VRTX LEN FTNT JPM CAH DE AAPL CSCO
2023-08-31 AVGO EOG MPC PSX EMR GE PH CAT JPM TJX MAR CSCO HAL DAL SLB
2023-09-29 JPM EMR EOG AVGO CAT MAR CSCO PHM AMGN NOW TJX MO VRSK KLAC PH
2023-10-31 BKNG PSX MPC AVGO CSCO EMR CME TJX AFL VRSK JPM HAL EOG COR MAR
2023-11-30 BKNG IBM JPM PGR CBOE AVGO GE CAH META MSFT CB AKAM AFL COR SPG
2023-12-29 AVGO IBM JPM NOW LEN SPG BKNG KLAC META WFC NRG CRM GE INTU PH
2024-01-31 BKNG IBM NVDA NOW JPM CRM AVGO GE META ABNB LEN DHI AMGN INTU PH
2024-02-29 GE PGR IBM JPM BKNG CRM PCAR CAT AVGO TDG NOW CB PH MSFT HLT
2024-03-28 GE NVDA META JPM PGR IBM CAT ANET WFC CRM PH AVGO PCAR CB KKR
2024-04-30 NVDA PGR WFC CAT META JPM PH URI AMAT KKR AXP ETN IR PLTR MLM
2024-05-31 NVDA WFC PGR META BKNG CAT JPM URI CB MO DAL FANG GOOGL TRGP AIG
2024-06-28 NVDA META PGR WFC MO PANW T TMUS GOOGL BSX AMZN MCK GDDY AMAT CB
2024-07-31 NVDA ANF MO META IBM ANET JPM GDDY TRGP NTAP PGR WELL GS NFLX VRTX
2024-08-30 NVDA MO PGR META IBM TMUS PANW MSI WELL AMT PM MCO VTR JPM GS
2024-09-30 PGR IBM MO AMT NVDA KKR META T WELL SPGI VTR TMUS PM AEP MCO
2024-10-31 NVDA META IBM PGR MO KKR TMUS T FISV BLK MSI SPG ANET BNY BK
2024-11-29 NVDA META TMUS FISV CRM MO WMB FTNT PYPL MS PGR BLK BNY BK KMI
2024-12-31 NVDA BKNG META MO TMUS PYPL GS PGR BLK FISV BK BNY CRM WMB AXP
2025-01-31 META BKNG BSX PGR GS PYPL COIN TMUS ANET V AXP MO BLK AMZN CRM
2025-02-28 META PGR GS PLTR MO NFLX BSX T JPM V TMUS FTNT NVDA MS SPGI
2025-03-31 MO PGR BKNG TMUS ABT V BRO TRV AEP VZ FTNT CME JPM BRK-B META
2025-04-30 MO PGR AMT VZ CME ABT TRV AEP CNP MCK CAH EXC WELL BRK-B TMUS
2025-05-30 GILD MO NEM UBER PM CME CAH ABT ALL TRV VRSN VZ COR PGR META
2025-06-30 GILD GS UBER PM JPM META MO CAH CF ABT MS FTNT EBAY PLTR VRSN
2025-07-31 BKNG C NVDA GS RCL GILD JPM MS UBER MO META SCHW BNY BK KLAC
2025-08-29 C NVDA HOOD GS COIN LRCX MS UBER MO APH KLAC GOOGL GILD BKNG SCHW
2025-09-30 AVGO C MS GS NVDA GOOGL UBER MO APH COIN BNY BK CCL JPM PLTR
2025-10-31 NEM AVGO C GILD MS NVDA GS GOOGL UBER APH COIN BAC AEP GE JCI
2025-11-28 KLAC MU GILD MPWR C HOOD LRCX GS GOOGL MS AEP AMGN NVDA COR JNJ
2025-12-31 C JNJ GILD AVGO STX GOOGL AMGN MS GS MPWR LLY BAC NVDA APH SCHW
2026-01-30 NEM GILD JNJ C GS GOOGL MS ADI AMGN LLY MNST EXPE APH VZ AVGO
2026-02-27 GILD MU MPWR JNJ STX ADI GOOGL VZ AMGN MNST AEP MO CF C MRK
2026-03-31 MU NEM GILD JNJ LRCX STX GOOGL SPG ADI AVGO MRK AMGN D NEE FDX
2026-04-30 APA CF NEM ADI SPG PSX JNJ AVGO DVN GILD NVDA GOOGL D BMY MU
2026-05-29 NVDA APA GILD ADI CF SPG MS AVGO PSX NEM GS GOOGL AAPL BNY BK
2026-06-26 WDC SPG STX C ADI MS HST BK BNY TRV GS AMD VLO STT MU
Scoring script (python)
FORMULA_NAME = "Contrarian 52-Week Recovery Quality Regime Momentum Hybrid (Arbitrated Repair Relay, v1191)"
LOGIC_VARIANT_COUNT = 4
NOTES = """mode=explore; family=contrarian-52w-recovery-quality-regime-momentum-hybrid
This variant combines four orthogonal ideas into an explicit arbitration system rather than a static blend: deep-52-week contrarian repair, early recovery confirmation, durable quality support, and trend momentum continuation. The structure is intentionally distinct from the parent relay because the regime branch does not merely reweight sleeves; it changes which conflicts are permitted. In panic and stressed tapes, broken names only score if they show concrete repair plus internal quality support. In neutral tapes, repaired recoveries can outrank pure momentum when extension is limited and durability is better. In risk-on tapes, momentum can dominate, but only if overextension, volatility, and low-quality internals do not trigger crowding taxes. The arbitration is explicit: each stock receives sleeve scores for repair, momentum, and durability, then branch-specific gates decide whether to reward convergence, suppress contradiction, or route capital to the strongest justified sleeve.
Deliberate metric coverage this run: momentum uses return_1m_pct, return_3m_pct, return_6m_pct, return_12m_pct, and momentum_12_1_pct; trend/recovery uses from_200d_ma_pct and from_52w_high_pct; volatility uses realized_vol_3m; liquidity uses avg_daily_volume_3m, avg_daily_dollar_volume_3m, and trading_days_3m; income uses dividend_yield_ttm_pct and dividend_ttm as secondary ballast; valuation uses pe, forward_pe, and peg; growth uses eps_growth_pct, revenue_growth_pct, operating_income_growth_pct, free_cash_flow_growth_pct, and forward_eps; quality uses operating_margin_pct and free_cash_flow_margin_pct; size uses market_cap as a crowding/fragility tilt rather than a direct preference.
Deliberate weight-0 metrics this run: shares_outstanding, close, adj_close, high_52w, ma_200d, eps_ttm, revenue_ttm, operating_income_ttm, and free_cash_flow_ttm. Correlated momentum features are separated by sleeve role, valuation is only active where quality/growth can justify it, and sparse fundamentals are normalized by present weight so missing fields do not automatically dominate or disqualify a stock.
"""

ACTIVE_METRICS = (
    "return_1m_pct",
    "return_3m_pct",
    "return_6m_pct",
    "return_12m_pct",
    "momentum_12_1_pct",
    "from_200d_ma_pct",
    "from_52w_high_pct",
    "realized_vol_3m",
    "avg_daily_volume_3m",
    "avg_daily_dollar_volume_3m",
    "trading_days_3m",
    "dividend_yield_ttm_pct",
    "dividend_ttm",
    "pe",
    "forward_pe",
    "peg",
    "eps_growth_pct",
    "revenue_growth_pct",
    "operating_income_growth_pct",
    "free_cash_flow_growth_pct",
    "forward_eps",
    "operating_margin_pct",
    "free_cash_flow_margin_pct",
    "market_cap",
)

REPAIR = {
    "from_52w_high_pct": (0.26, -1),
    "from_200d_ma_pct": (0.16, -1),
    "return_1m_pct": (0.10, +1),
    "return_3m_pct": (0.10, +1),
    "realized_vol_3m": (0.08, -1),
    "avg_daily_dollar_volume_3m": (0.06, +1),
    "trading_days_3m": (0.04, +1),
    "operating_margin_pct": (0.07, +1),
    "free_cash_flow_margin_pct": (0.07, +1),
    "free_cash_flow_growth_pct": (0.06, +1),
}

RECOVERY = {
    "from_52w_high_pct": (0.18, -1),
    "from_200d_ma_pct": (0.18, +1),
    "return_3m_pct": (0.13, +1),
    "return_6m_pct": (0.08, +1),
    "momentum_12_1_pct": (0.08, +1),
    "realized_vol_3m": (0.07, -1),
    "avg_daily_volume_3m": (0.05, +1),
    "peg": (0.05, -1),
    "operating_income_growth_pct": (0.08, +1),
    "operating_margin_pct": (0.10, +1),
}

MOMENTUM = {
    "momentum_12_1_pct": (0.18, +1),
    "return_6m_pct": (0.16, +1),
    "return_12m_pct": (0.10, +1),
    "return_3m_pct": (0.09, +1),
    "from_200d_ma_pct": (0.09, +1),
    "from_52w_high_pct": (0.08, +1),
    "realized_vol_3m": (0.08, -1),
    "avg_daily_dollar_volume_3m": (0.06, +1),
    "eps_growth_pct": (0.06, +1),
    "forward_pe": (0.05, -1),
    "free_cash_flow_margin_pct": (0.05, +1),
}

DURABILITY = {
    "operating_margin_pct": (0.16, +1),
    "free_cash_flow_margin_pct": (0.16, +1),
    "operating_income_growth_pct": (0.11, +1),
    "free_cash_flow_growth_pct": (0.11, +1),
    "revenue_growth_pct": (0.07, +1),
    "eps_growth_pct": (0.06, +1),
    "peg": (0.06, -1),
    "pe": (0.05, -1),
    "dividend_yield_ttm_pct": (0.04, +1),
    "dividend_ttm": (0.03, +1),
    "trading_days_3m": (0.05, +1),
    "realized_vol_3m": (0.10, -1),
}

BRANCHES = ("panic_repair", "stressed_recovery", "balanced_relay", "risk_on_momentum")


def _to_float(value):
    if value is None:
        return None
    if isinstance(value, bool):
        return 1.0 if value else 0.0
    if isinstance(value, (int, float)):
        return float(value)
    return None


def _metric_ranks(stocks, metric):
    pairs = []
    for stock in stocks:
        val = _to_float(stock.get(metric))
        if val is not None:
            pairs.append((val, stock.get("symbol")))
    if not pairs:
        return {}
    pairs.sort(key=lambda x: x[0])
    n = len(pairs)
    if n == 1:
        return {pairs[0][1]: 0.5}
    ranks = {}
    i = 0
    while i < n:
        j = i
        v = pairs[i][0]
        while j + 1 < n and pairs[j + 1][0] == v:
            j += 1
        rank = ((i + j) * 0.5) / (n - 1)
        k = i
        while k <= j:
            ranks[pairs[k][1]] = rank
            k += 1
        i = j + 1
    return ranks


def _build_rank_table(stocks):
    table = {}
    for metric in ACTIVE_METRICS:
        table[metric] = _metric_ranks(stocks, metric)
    return table


def _signed_rank(rank_table, symbol, metric, direction):
    rank = rank_table.get(metric, {}).get(symbol)
    if rank is None:
        return None
    return rank if direction > 0 else (1.0 - rank)


def _weighted_score(rank_table, symbol, weights):
    total = 0.0
    used = 0.0
    for metric, spec in weights.items():
        weight, direction = spec
        val = _signed_rank(rank_table, symbol, metric, direction)
        if val is None:
            continue
        total += weight * val
        used += weight
    if used <= 0.0:
        return 0.0
    return total / used


def _count_present(rank_table, symbol, weights):
    count = 0
    for metric in weights:
        if symbol in rank_table.get(metric, {}):
            count += 1
    return count


def _clamp(x, lo, hi):
    if x < lo:
        return lo
    if x > hi:
        return hi
    return x


def _regime_name(regime):
    if isinstance(regime, str):
        text = regime.lower()
    else:
        text = str(regime).lower() if regime is not None else ""
    if "panic" in text or "crash" in text:
        return "panic_repair"
    if "stress" in text or "bear" in text or "risk_off" in text or "risk-off" in text or "defensive" in text:
        return "stressed_recovery"
    if "bull" in text or "risk_on" in text or "risk-on" in text or "momo" in text or "momentum" in text:
        return "risk_on_momentum"
    return "balanced_relay"


def _branch_from_ctx(ctx):
    if not isinstance(ctx, dict):
        return None
    for key in ("regime", "market_regime", "branch", "state"):
        if key in ctx:
            name = _regime_name(ctx.get(key))
            if name:
                return name
    return None


def _raw(stock, key):
    return _to_float(stock.get(key))


def _repair_evidence(stock, rank_table, symbol):
    r1 = _signed_rank(rank_table, symbol, "return_1m_pct", +1)
    r3 = _signed_rank(rank_table, symbol, "return_3m_pct", +1)
    f200 = _signed_rank(rank_table, symbol, "from_200d_ma_pct", +1)
    high_gap = _signed_rank(rank_table, symbol, "from_52w_high_pct", -1)
    qual = _weighted_score(rank_table, symbol, {
        "operating_margin_pct": (0.5, +1),
        "free_cash_flow_margin_pct": (0.5, +1),
    })
    parts = []
    if r1 is not None:
        parts.append(r1)
    if r3 is not None:
        parts.append(r3)
    if f200 is not None:
        parts.append(f200)
    if high_gap is not None:
        parts.append(high_gap)
    if qual > 0.0:
        parts.append(qual)
    if not parts:
        return 0.0
    return sum(parts) / float(len(parts))


def _extension_risk(stock, rank_table, symbol):
    near_high = _signed_rank(rank_table, symbol, "from_52w_high_pct", +1)
    far_above_200 = _signed_rank(rank_table, symbol, "from_200d_ma_pct", +1)
    hot_1m = _signed_rank(rank_table, symbol, "return_1m_pct", +1)
    vol = _signed_rank(rank_table, symbol, "realized_vol_3m", +1)
    size_small = _signed_rank(rank_table, symbol, "market_cap", -1)
    parts = []
    if near_high is not None:
        parts.append(near_high)
    if far_above_200 is not None:
        parts.append(far_above_200)
    if hot_1m is not None:
        parts.append(hot_1m)
    if vol is not None:
        parts.append(vol)
    if size_small is not None:
        parts.append(size_small)
    if not parts:
        return 0.0
    return sum(parts) / float(len(parts))


def _fragility(stock, rank_table, symbol):
    vol = _signed_rank(rank_table, symbol, "realized_vol_3m", +1)
    liq = _weighted_score(rank_table, symbol, {
        "avg_daily_volume_3m": (0.4, -1),
        "avg_daily_dollar_volume_3m": (0.4, -1),
        "trading_days_3m": (0.2, -1),
    })
    qual = _weighted_score(rank_table, symbol, {
        "operating_margin_pct": (0.5, -1),
        "free_cash_flow_margin_pct": (0.5, -1),
    })
    parts = []
    if vol is not None:
        parts.append(vol)
    if liq > 0.0:
        parts.append(liq)
    if qual > 0.0:
        parts.append(qual)
    if not parts:
        return 0.5
    return sum(parts) / float(len(parts))


def _valuation_support(rank_table, symbol):
    return _weighted_score(rank_table, symbol, {
        "pe": (0.30, -1),
        "forward_pe": (0.30, -1),
        "peg": (0.40, -1),
    })


def score_universe(stocks, regime, ctx):
    rank_table = _build_rank_table(stocks)
    branch = _branch_from_ctx(ctx) or _regime_name(regime)
    scores = {}

    for stock in stocks:
        symbol = stock.get("symbol")
        if not symbol:
            continue

        repair = _weighted_score(rank_table, symbol, REPAIR)
        recovery = _weighted_score(rank_table, symbol, RECOVERY)
        momentum = _weighted_score(rank_table, symbol, MOMENTUM)
        durability = _weighted_score(rank_table, symbol, DURABILITY)

        repair_evidence = _repair_evidence(stock, rank_table, symbol)
        extension = _extension_risk(stock, rank_table, symbol)
        fragility = _fragility(stock, rank_table, symbol)
        value_support = _valuation_support(rank_table, symbol)

        conflict = abs(momentum - repair)
        convergence = 1.0 - conflict if conflict <= 1.0 else 0.0

        has_repair_depth = _signed_rank(rank_table, symbol, "from_52w_high_pct", -1)
        trend_ok = _signed_rank(rank_table, symbol, "from_200d_ma_pct", +1)
        liquid_ok = _weighted_score(rank_table, symbol, {
            "avg_daily_dollar_volume_3m": (0.7, +1),
            "trading_days_3m": (0.3, +1),
        })

        gate_repair = 1.0 if repair_evidence >= 0.52 else 0.70
        if has_repair_depth is not None and has_repair_depth < 0.35:
            gate_repair *= 0.82

        gate_momentum = 1.0 if extension <= 0.72 else 0.72
        if durability < 0.45:
            gate_momentum *= 0.82
        if fragility > 0.68:
            gate_momentum *= 0.82

        gate_durability = 1.0 if durability >= 0.50 else 0.78
        if liquid_ok < 0.35:
            gate_durability *= 0.85

        repair_adj = repair * gate_repair
        momentum_adj = momentum * gate_momentum
        durability_adj = durability * gate_durability
        recovery_adj = recovery * (0.92 + 0.16 * convergence)

        if branch == "panic_repair":
            dominant = repair_adj
            if durability_adj > dominant:
                dominant = durability_adj
            score = (
                0.42 * repair_adj
                + 0.24 * durability_adj
                + 0.18 * recovery_adj
                + 0.08 * value_support
                + 0.08 * convergence
            )
            if repair_adj >= 0.55 and durability_adj >= 0.50:
                score += 0.08
            if momentum_adj > repair_adj + 0.12 and extension > 0.60:
                score -= 0.08
            score -= 0.16 * fragility
            score += 0.10 * dominant

        elif branch == "stressed_recovery":
            dominant = recovery_adj
            if repair_adj > dominant:
                dominant = repair_adj
            score = (
                0.31 * recovery_adj
                + 0.24 * repair_adj
                + 0.23 * durability_adj
                + 0.10 * value_support
                + 0.06 * momentum_adj
                + 0.06 * convergence
            )
            if trend_ok is not None and trend_ok >= 0.52:
                score += 0.05
            if durability_adj >= 0.58 and repair_evidence >= 0.55:
                score += 0.06
            score -= 0.10 * extension
            score -= 0.10 * fragility
            score += 0.08 * dominant

        elif branch == "risk_on_momentum":
            dominant = momentum_adj
            if recovery_adj > dominant and recovery_adj - momentum_adj > 0.10 and extension > 0.75:
                dominant = recovery_adj
            score = (
                0.39 * momentum_adj
                + 0.18 * recovery_adj
                + 0.18 * durability_adj
                + 0.09 * repair_adj
                + 0.08 * value_support
                + 0.08 * convergence
            )
            if momentum_adj >= 0.62 and durability_adj >= 0.48:
                score += 0.07
            if extension > 0.78:
                score -= 0.09
            if fragility > 0.70:
                score -= 0.08
            score += 0.09 * dominant

        else:  # balanced_relay
            dominant = repair_adj
            if momentum_adj > dominant:
                dominant = momentum_adj
            if durability_adj > dominant:
                dominant = durability_adj
            score = (
                0.24 * repair_adj
                + 0.24 * recovery_adj
                + 0.22 * momentum_adj
                + 0.20 * durability_adj
                + 0.05 * value_support
                + 0.05 * convergence
            )
            if repair_adj >= 0.56 and momentum_adj >= 0.56 and durability_adj >= 0.50:
                score += 0.09
            elif dominant == durability_adj and fragility < 0.45:
                score += 0.04
            score -= 0.07 * extension
            score -= 0.06 * fragility
            score += 0.07 * dominant

        present_count = (
            _count_present(rank_table, symbol, REPAIR)
            + _count_present(rank_table, symbol, RECOVERY)
            + _count_present(rank_table, symbol, MOMENTUM)
            + _count_present(rank_table, symbol, DURABILITY)
        )
        coverage_boost = 0.0
        if present_count >= 22:
            coverage_boost = 0.02
        elif present_count <= 10:
            coverage_boost = -0.03

        scores[symbol] = _clamp(score + coverage_boost, 0.0, 1.0)

    return scores