exp_1195

Recovery Quality Contrarian 52-Week Hybrid (Evidence-Relay Arbitration, v1195)

← All V2 experiments
Relative return
1.031x
Excess vs bench
3.05%
Benchmark
CAPW_UNIV
Rolling windows
179 · monthly
Mean strategy gain
17.51%
Mean benchmark gain
14.08%
Mean excess gain
3.43%
Dispersion (ref)
5.35%
Win-rate vs bench (ref)
82.68%
Worst / best ratio (ref)
0.960x / 1.090x
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 4.78% 2.22% 1.025x
2011-07-01 … 2016-06-30 22.46% 13.74% 1.077x
2016-07-01 … 2021-06-30 24.13% 20.63% 1.029x
2021-07-01 … 2026-06-26 16.61% 15.48% 1.010x
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.031x · beat benchmark in 148/179
#WindowStrategyBenchmarkRatio
1 2006-07-31 … 2011-07-29 4.70% 1.79% 1.029x
2 2006-08-31 … 2011-08-31 3.57% 0.21% 1.034x
3 2006-09-29 … 2011-08-31 3.23% -0.14% 1.034x
4 2006-10-31 … 2011-10-31 4.58% 0.23% 1.043x
5 2006-11-30 … 2011-11-30 4.08% -0.05% 1.041x
6 2006-12-29 … 2011-11-30 3.61% -0.32% 1.039x
7 2007-01-31 … 2012-01-31 5.54% 0.93% 1.046x
8 2007-02-28 … 2012-01-31 6.16% 1.43% 1.047x
9 2007-03-30 … 2012-03-30 9.10% 3.09% 1.058x
10 2007-04-30 … 2012-04-30 8.42% 2.42% 1.059x
11 2007-05-31 … 2012-05-31 6.55% 0.60% 1.059x
12 2007-06-29 … 2012-06-29 8.02% 1.92% 1.060x
13 2007-07-31 … 2012-07-31 9.19% 2.69% 1.063x
14 2007-08-31 … 2012-08-31 10.08% 2.95% 1.069x
15 2007-09-28 … 2012-09-28 9.94% 3.20% 1.065x
16 2007-10-31 … 2012-10-31 8.43% 2.60% 1.057x
17 2007-11-30 … 2012-11-30 8.82% 3.45% 1.052x
18 2007-12-31 … 2012-12-31 9.12% 3.69% 1.052x
19 2008-01-31 … 2013-01-31 11.78% 5.85% 1.056x
20 2008-02-29 … 2013-02-28 11.65% 6.82% 1.045x
21 2008-03-31 … 2013-03-28 13.15% 7.73% 1.050x
22 2008-04-30 … 2013-04-30 12.57% 7.51% 1.047x
23 2008-05-30 … 2013-04-30 12.38% 7.81% 1.042x
24 2008-06-30 … 2013-06-28 13.78% 9.33% 1.041x
25 2008-07-31 … 2013-07-31 15.88% 10.48% 1.049x
26 2008-08-29 … 2013-07-31 16.12% 10.52% 1.051x
27 2008-09-30 … 2013-09-30 16.10% 11.48% 1.041x
28 2008-10-31 … 2013-10-31 19.89% 15.76% 1.036x
29 2008-11-28 … 2013-10-31 21.08% 17.46% 1.031x
30 2008-12-31 … 2013-12-31 21.37% 18.44% 1.025x
31 2009-01-30 … 2013-12-31 22.44% 20.64% 1.015x
32 2009-02-27 … 2014-01-31 25.13% 21.63% 1.029x
33 2009-03-31 … 2014-03-31 26.35% 20.60% 1.048x
34 2009-04-30 … 2014-04-30 24.26% 19.00% 1.044x
35 2009-05-29 … 2014-04-30 23.28% 18.32% 1.042x
36 2009-06-30 … 2014-06-30 24.54% 19.01% 1.047x
37 2009-07-31 … 2014-07-31 22.56% 17.39% 1.044x
38 2009-08-31 … 2014-08-29 23.10% 17.70% 1.046x
39 2009-09-30 … 2014-09-30 22.25% 16.64% 1.048x
40 2009-10-30 … 2014-09-30 25.12% 17.08% 1.069x
41 2009-11-30 … 2014-11-28 25.04% 16.82% 1.070x
42 2009-12-31 … 2014-12-31 23.89% 16.28% 1.065x
43 2010-01-29 … 2014-12-31 25.08% 17.23% 1.067x
44 2010-02-26 … 2015-01-30 23.94% 15.80% 1.070x
45 2010-03-31 … 2015-03-31 22.93% 15.40% 1.065x
46 2010-04-30 … 2015-04-30 21.52% 15.38% 1.053x
47 2010-05-28 … 2015-04-30 23.56% 17.09% 1.055x
48 2010-06-30 … 2015-06-30 27.23% 17.45% 1.083x
49 2010-07-30 … 2015-06-30 26.86% 16.43% 1.090x
50 2010-08-31 … 2015-08-31 24.15% 15.76% 1.072x
51 2010-09-30 … 2015-09-30 22.43% 13.61% 1.078x
52 2010-10-29 … 2015-09-30 22.23% 13.06% 1.081x
53 2010-11-30 … 2015-11-30 23.18% 15.09% 1.070x
54 2010-12-31 … 2015-12-31 22.45% 13.55% 1.078x
55 2011-01-31 … 2016-01-29 21.38% 11.90% 1.085x
56 2011-02-28 … 2016-01-29 20.92% 11.53% 1.084x
57 2011-03-31 … 2016-03-31 23.03% 12.90% 1.090x
58 2011-04-29 … 2016-04-29 22.06% 12.39% 1.086x
59 2011-05-31 … 2016-05-31 22.35% 12.94% 1.083x
60 2011-06-30 … 2016-06-30 22.16% 13.30% 1.078x
61 2011-07-29 … 2016-07-29 22.89% 14.52% 1.073x
62 2011-08-31 … 2016-08-31 22.38% 15.19% 1.062x
63 2011-09-30 … 2016-09-30 22.66% 16.32% 1.055x
64 2011-10-31 … 2016-10-31 19.58% 14.02% 1.049x
65 2011-11-30 … 2016-11-30 21.17% 14.66% 1.057x
66 2011-12-30 … 2016-12-30 21.25% 14.92% 1.055x
67 2012-01-31 … 2017-01-31 21.06% 14.63% 1.056x
68 2012-02-29 … 2017-02-28 20.71% 14.78% 1.052x
69 2012-03-30 … 2017-02-28 19.89% 14.43% 1.048x
70 2012-04-30 … 2017-04-28 19.20% 14.61% 1.040x
71 2012-05-31 … 2017-05-31 20.71% 15.98% 1.041x
72 2012-06-29 … 2017-05-31 20.03% 15.44% 1.040x
73 2012-07-31 … 2017-07-31 19.78% 15.43% 1.038x
74 2012-08-31 … 2017-08-31 19.65% 15.12% 1.039x
75 2012-09-28 … 2017-08-31 19.46% 14.77% 1.041x
76 2012-10-31 … 2017-10-31 20.97% 16.12% 1.042x
77 2012-11-30 … 2017-11-30 22.00% 16.79% 1.045x
78 2012-12-31 … 2017-12-29 21.08% 16.93% 1.036x
79 2013-01-31 … 2018-01-31 22.36% 17.57% 1.041x
80 2013-02-28 … 2018-02-28 21.65% 16.21% 1.047x
81 2013-03-28 … 2018-02-28 21.01% 15.81% 1.045x
82 2013-04-30 … 2018-04-30 18.31% 14.25% 1.036x
83 2013-05-31 … 2018-05-31 17.27% 14.57% 1.024x
84 2013-06-28 … 2018-05-31 18.93% 14.97% 1.034x
85 2013-07-31 … 2018-07-31 17.77% 14.83% 1.026x
86 2013-08-30 … 2018-07-31 19.05% 15.59% 1.030x
87 2013-09-30 … 2018-09-28 19.31% 15.84% 1.030x
88 2013-10-31 … 2018-10-31 17.27% 12.89% 1.039x
89 2013-11-29 … 2018-10-31 16.89% 12.60% 1.038x
90 2013-12-31 … 2018-12-31 13.90% 9.93% 1.036x
91 2014-01-31 … 2019-01-31 15.43% 12.37% 1.027x
92 2014-02-28 … 2019-02-28 14.55% 12.38% 1.019x
93 2014-03-31 … 2019-03-29 14.94% 12.76% 1.019x
94 2014-04-30 … 2019-04-30 16.46% 13.73% 1.024x
95 2014-05-30 … 2019-04-30 16.05% 13.54% 1.022x
96 2014-06-30 … 2019-06-28 15.29% 12.81% 1.022x
97 2014-07-31 … 2019-07-31 15.34% 13.30% 1.018x
98 2014-08-29 … 2019-07-31 15.04% 12.80% 1.020x
99 2014-09-30 … 2019-09-30 16.35% 12.70% 1.032x
100 2014-10-31 … 2019-10-31 17.08% 12.91% 1.037x
101 2014-11-28 … 2019-10-31 17.02% 12.60% 1.039x
102 2014-12-31 … 2019-12-31 18.45% 14.16% 1.038x
103 2015-01-30 … 2019-12-31 18.36% 14.85% 1.031x
104 2015-02-27 … 2020-01-31 17.58% 14.04% 1.031x
105 2015-03-31 … 2020-03-31 12.54% 8.56% 1.037x
106 2015-04-30 … 2020-04-30 15.70% 11.65% 1.036x
107 2015-05-29 … 2020-05-29 15.79% 12.61% 1.028x
108 2015-06-30 … 2020-06-30 15.33% 13.64% 1.015x
109 2015-07-31 … 2020-07-31 17.23% 14.60% 1.023x
110 2015-08-31 … 2020-08-31 19.46% 18.07% 1.012x
111 2015-09-30 … 2020-09-30 17.83% 17.05% 1.007x
112 2015-10-30 … 2020-10-30 14.77% 14.60% 1.002x
113 2015-11-30 … 2020-11-30 20.44% 17.43% 1.026x
114 2015-12-31 … 2020-12-31 20.79% 18.65% 1.018x
115 2016-01-29 … 2021-01-29 24.09% 19.26% 1.040x
116 2016-02-29 … 2021-02-26 25.52% 19.79% 1.048x
117 2016-03-31 … 2021-03-31 25.29% 19.42% 1.049x
118 2016-04-29 … 2021-03-31 25.85% 19.66% 1.052x
119 2016-05-31 … 2021-05-28 24.41% 20.42% 1.033x
120 2016-06-30 … 2021-06-30 24.38% 21.06% 1.027x
121 2016-07-29 … 2021-06-30 24.13% 20.63% 1.029x
122 2016-08-31 … 2021-08-31 25.85% 21.75% 1.034x
123 2016-09-30 … 2021-09-30 23.95% 20.22% 1.031x
124 2016-10-31 … 2021-10-29 26.54% 22.50% 1.033x
125 2016-11-30 … 2021-11-30 26.23% 21.87% 1.036x
126 2016-12-30 … 2021-11-30 25.89% 21.75% 1.034x
127 2017-01-31 … 2022-01-31 21.27% 20.17% 1.009x
128 2017-02-28 … 2022-02-28 19.86% 18.51% 1.011x
129 2017-03-31 … 2022-03-31 20.75% 19.46% 1.011x
130 2017-04-28 … 2022-03-31 21.01% 19.46% 1.013x
131 2017-05-31 … 2022-05-31 20.38% 15.59% 1.041x
132 2017-06-30 … 2022-06-30 19.40% 13.08% 1.056x
133 2017-07-31 … 2022-07-29 18.77% 15.16% 1.031x
134 2017-08-31 … 2022-08-31 16.76% 13.72% 1.027x
135 2017-09-29 … 2022-08-31 16.90% 13.56% 1.029x
136 2017-10-31 … 2022-10-31 16.44% 11.86% 1.041x
137 2017-11-30 … 2022-11-30 17.50% 12.52% 1.044x
138 2017-12-29 … 2022-11-30 18.00% 12.46% 1.049x
139 2018-01-31 … 2023-01-31 15.35% 11.01% 1.039x
140 2018-02-28 … 2023-02-28 14.87% 11.03% 1.035x
141 2018-03-29 … 2023-02-28 16.28% 11.72% 1.041x
142 2018-04-30 … 2023-04-28 16.26% 13.01% 1.029x
143 2018-05-31 … 2023-05-31 14.59% 12.95% 1.015x
144 2018-06-29 … 2023-05-31 14.69% 13.01% 1.015x
145 2018-07-31 … 2023-07-31 15.15% 14.67% 1.004x
146 2018-08-31 … 2023-08-31 13.60% 13.51% 1.001x
147 2018-09-28 … 2023-08-31 14.06% 13.56% 1.004x
148 2018-10-31 … 2023-10-31 11.48% 12.60% 0.990x
149 2018-11-30 … 2023-11-30 12.29% 14.58% 0.980x
150 2018-12-31 … 2023-12-29 14.91% 17.26% 0.980x
151 2019-01-31 … 2024-01-31 12.75% 16.27% 0.970x
152 2019-02-28 … 2024-01-31 12.08% 15.94% 0.967x
153 2019-03-29 … 2024-03-28 14.23% 17.50% 0.972x
154 2019-04-30 … 2024-04-30 11.99% 15.50% 0.970x
155 2019-05-31 … 2024-05-31 14.64% 18.12% 0.971x
156 2019-06-28 … 2024-06-28 14.84% 17.99% 0.973x
157 2019-07-31 … 2024-07-31 14.01% 17.70% 0.969x
158 2019-08-30 … 2024-08-30 14.22% 18.41% 0.965x
159 2019-09-30 … 2024-09-30 15.16% 18.65% 0.971x
160 2019-10-31 … 2024-10-31 14.59% 17.87% 0.972x
161 2019-11-29 … 2024-11-29 16.31% 18.64% 0.980x
162 2019-12-31 … 2024-12-31 12.95% 17.62% 0.960x
163 2020-01-31 … 2025-01-31 15.09% 18.07% 0.975x
164 2020-02-28 … 2025-02-28 15.59% 19.00% 0.971x
165 2020-03-31 … 2025-03-31 14.92% 19.24% 0.964x
166 2020-04-30 … 2025-04-30 13.79% 16.49% 0.977x
167 2020-05-29 … 2025-04-30 13.11% 15.80% 0.977x
168 2020-06-30 … 2025-06-30 14.71% 18.19% 0.971x
169 2020-07-31 … 2025-07-31 13.72% 17.87% 0.965x
170 2020-08-31 … 2025-08-29 13.30% 16.69% 0.971x
171 2020-09-30 … 2025-09-30 16.61% 18.57% 0.983x
172 2020-10-30 … 2025-09-30 18.00% 19.43% 0.988x
173 2020-11-30 … 2025-11-28 15.70% 17.77% 0.982x
174 2020-12-31 … 2025-12-31 15.70% 16.92% 0.990x
175 2021-01-29 … 2025-12-31 14.03% 17.20% 0.973x
176 2021-02-26 … 2026-01-30 14.18% 17.04% 0.976x
177 2021-03-31 … 2026-03-31 12.56% 14.07% 0.987x
178 2021-04-30 … 2026-04-30 15.96% 16.03% 0.999x
179 2021-05-28 … 2026-04-30 16.60% 16.22% 1.003x
Notes
mode=explore; family=recovery-quality-contrarian-52w-hybrid New hybrid family built as an evidence-relay rather than a static blend: every stock is first classified into a repair, leadership, durability, or skeptical state, then each regime branch decides which state is allowed to dominate and how hard conflicting signals are taxed. The design preserves what deep-52w contrarian repair does well, keeps recovery-quality discipline so damaged junk does not float to the top, and still lets genuine leaders win in cleaner tapes only after extension, volatility, and valuation sanity checks clear. Deliberate metric coverage this run: active momentum uses return_3m_pct, return_6m_pct, and momentum_12_1_pct; trend/recovery uses both 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; valuation uses forward_pe and peg; growth uses 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 stability tilt. Deliberate weight-0 metrics this run: return_1m_pct, return_12m_pct, dividend_ttm, pe, eps_growth_pct, revenue_growth_pct, shares_outstanding, close, adj_close, high_52w, ma_200d, eps_ttm, revenue_ttm, operating_income_ttm, and free_cash_flow_ttm. Sparse fundamentals are normalized by present weight inside each case so missing fields do not mechanically dominate selection.
Lesson notes
#893 · degrade · relative_return Δ -0.3604 · parent exp_1118 · Jul 21, 2026 · auto/explore; benchmark CAPW_UNIV
explore/recovery-quality-contrarian-52w-hybrid: relative_return 1.0305x (delta -0.3604 vs exp_1118); win-rate 82.6816%, worst-window 0.960258, dispersion 5.3482%.
Monthly picks — top stocks selected each month (whole timeline)
timeline — 240 months · top 15 each
Month 123456789101112131415
2006-07-31 XOM USB VZ JNJ KO PFE TWX NEE OMC PG WMT ETR EXC PSKY GE
2006-08-31 VZ PFE USB JNJ PG KO NEE ETR GE T SO TFC XOM TWX WMT
2006-09-29 XOM PG JNJ TWX WMT MSFT NEE T KO GE STZ GEN OMC ORCL SO
2006-10-31 TWX MSFT PG JNJ USB WFC PFE JCI WMT IBM FMCC KO PEP GS T
2006-11-30 TWX MSFT USB PG WFC IBM JCI JNJ JPM BAC GS KO NKE ZBH MS
2006-12-29 MSFT USB IBM MO ZBH PSKY TWX PG KO XOM VNO WFC C NKE GS
2007-01-31 MSFT USB MO PG TWX UAL JPM XEL KO JCI MET WFC XOM C PRU
2007-02-28 TWX USB VZ JPM WYNN MO WMT DD MSFT WFC KO PG HD HON MCK
2007-03-30 ICE USB VZ ON WY IBM KO TWX WMT MCK RTX OMC PG NEE HON
2007-04-30 PEG SYK VZ SRE USB IBM LLY PFE WMT GE CF SO PEP ES WY
2007-05-31 XOM KO ZBH MO CVX IBM SYK ETR PEP MCD MET PEG HON WMT PFE
2007-06-29 XOM AMZN NRG PRU KO MO RTX ICE GOOGL IBM CLF ZBH MSFT PSKY PFE
2007-07-31 VZ RTX T MMM KO GOOGL GE UPS MO BA HPQ WMT MCD VFC GOOG
2007-08-31 RTX KO T UPS PG PAYX MO GE PEP OXY TXN CVS MSFT MRK JNJ
2007-09-28 PG PEP ORCL MDT GE JNJ MO TXN UPS MSFT CVS BIIB PFE PAYX LLY
2007-10-31 PG MSFT PEP MO GE GRMN JNJ UPS PFE AMZN CL WMT EXPE MDLZ UNH
2007-11-30 PG XOM JNJ WMT UNH RTX T MDLZ GE SRE FCX XEL SO UPS WYNN
2007-12-31 UNH VZ JNJ WMT SO XEL T MCD MRK SRE ELV KO UPS WEC PFE
2008-01-31 UNH FSLR JNJ WMT PFE RTX UPS USB VZ T XEL WEC MRSH ELV TXN
2008-02-29 KMB D MDLZ JNJ MRSH BA MSFT LH WEC XEL TWX UNH WRB FISV GE
2008-03-31 RTX MDLZ D GE KMB WM UHS XEL MSFT LMT WEC SRE OMC MMM WRB
2008-04-30 ABT WM JCI RTX D NRG ZBH MDLZ MO TEL WEC BA SRE XEL PPL
2008-05-30 WM D ABT XOM RTX PPL MO MDLZ ETR HPQ ZBH BA UNP T USB
2008-06-30 WM ABT XOM PPL PM HPQ PEG MO SRE RTX LLY ZBH XEL L PCG
2008-07-31 ABT D HPQ MDLZ WM PM MO SRE LLY XOM MEE X XEL PPL WLP
2008-08-29 D MDLZ SRE ABT LLY IBM HPQ PG XEL ED PM FFIV BAX WEC XOM
2008-09-30 MDLZ D SYY ED LLY MO VFC XEL HPQ IBM KMB KR PAYX SRE CL
2008-10-31 HPQ XEL WM PM RTX KDP PAYX MMM VZ IBM LLY CAG PFE XRAY T
2008-11-28 PM RTX LLY TAP UNP MSFT FDX MCD CAG DAL KR XRAY MRK SHW AEP
2008-12-31 PM RTX MRK HPQ IBM MO CAG MSFT V MCD UNH TJX XRAY UNP SHW
2009-01-30 PM ELV MCK XOM MCD GILD HON GOOG XRAY HUM ITW WM MSFT PPL ABT
2009-02-27 RTX PM MRK HPQ PFE PPL HON TMO XOM XRAY MCD PCG AAPL ZBH GILD
2009-03-31 UPS MS PG RTX HPQ CF ADI PPL XRAY VTRS GOOG LLY TJX PCG TGT
2009-04-30 T CVX XOM OXY MS GOOG MCD NVDA EBAY RTX CF JNJ PG PM WMT
2009-05-29 UPS OXY EBAY CVX MCD RTX XOM PM CF BMY VZ T JNJ MOS FCX
2009-06-30 PM XOM EBAY STX PRU MCD WLL SLB BMY PG FCX JNJ THC CL NFX
2009-07-31 BMY PM FCX PG XOM MOS JCI JNJ CF MCD UPS IP PEP AMGN WAT
2009-08-31 MSFT PRU LVS IBM PFE COF HIG FNMA TWX TGT GILD MA BMY XOM TEL
2009-09-30 FNMA FMCC FITB LVS MSFT PFE MGM ZBH GILD MTG TJX MA GOOG PG XOM
2009-10-30 LVS GNW PFE HIG FMCC IBM V PM RTX MA FNMA TT MSFT SLG XOM
2009-11-30 PFE ABT MSFT LVS GILD STX IBM RTX PG AMGN MRK V TT JBL FLEX
2009-12-31 BKNG MSFT PFE FCX MRK IBM ABT WBD ZBH ORCL RTX GILD PG CAH SYY
2010-01-29 BKNG AMD MU PFE ABT STX GIS UAL AMGN SLG MSFT RTX MTW WYNN MCD
2010-02-26 AMD MU ABT GIS MSFT AMGN NYT PG MCD MTW SYY RTX JBL UPS PEP
2010-03-31 F BMY ZION MSFT TRV SANM PG WSM AAL DPZ AMGN MDLZ ISRG SYY VRSN
2010-04-30 UAL MTG CLF VIAV BBWI LVS TJX F HBAN MBI WSM TWX LPX DECK MSFT
2010-05-28 ZION MTG MBI UAL TWX HON UNP VIAV SYY RF VTRS PVH BMY HST MGM
2010-06-30 BMY ZION SYY PEG MDLZ TRV TXN MRK HON WEC GIS BRK-B TWX KMB WRB
2010-07-30 BMY PM TXN PEG QCOM VZ TRV XEL MDLZ KMB T HON LUMN GS MRK
2010-08-31 PM INTC MDLZ T TXN MRK VZ KMB LLY MSFT QCOM WELL WM CB HON
2010-09-30 INTC QCOM MRO CB MSFT MDLZ HON WM SRE MRK LLY TRV MMM GILD KMB
2010-10-29 INTC QCOM T XEL WELL AAPL MRO HON MDLZ TRV MSFT LYB EBAY XOM CB
2010-11-30 INTC NTAP XOM QCOM MSFT BMY D TXN GILD BKNG T COP TT XEL OXY
2010-12-31 LVS INTC MSFT BKNG TXN XOM MCHP DECK TT QCOM FFIV OXY TPR MGM LULU
2011-01-31 WLL INTC XOM MSFT FCX CIEN MCHP OXY WMB XEC DECK TT LULU GILD BMY
2011-02-28 VIAV NVDA INTC XOM MSFT VLO TEX LULU OXY GILD ANDV MCHP CVX URI WU
2011-03-31 VIAV INTC TER TXN NVDA PM MSFT KLAC D XOM CIEN T SWKS AAPL MCHP
2011-04-29 VIAV COP TXN T PM INTC PSKY MSFT KO D ANDV MTW AAPL IRM BIIB
2011-05-31 BKNG XOM T GE D SPG MSFT LULU BBWI WMB KO MCHP MDLZ AAPL INTC
2011-06-30 XOM T D SPG GE PM MSFT COP BKNG MCO KO MDLZ INTC AAPL LLY
2011-07-29 T INTC MDLZ XOM KO COP MSFT TJX PPL GE LLY CVX MCK PFE NI
2011-08-31 VZ MDLZ MSFT KO T WBD PPL XOM INTC GE KMB COP CL KR NI
2011-09-30 T WBD CF MRK GE EXC COP KLAC AAPL PCG KR SYY MSFT SRE ZBH
2011-10-31 WBD T XOM MRK CF GE COP AAPL KLAC GOOG TWX PCG V SRE UNP
2011-11-30 XOM MSFT WBD GOOG GE MRK KO KLAC CF SHW UNP AAPL MA ORCL USB
2011-12-30 GE MSFT WBD KO CF KLAC COP SYY MA V PM USB BKNG PFE AAPL
2012-01-31 GE XOM MSFT WBD KO USB CF WFC AAPL KMI TJX PFE V KLAC SYY
2012-02-29 GE AAPL WBD XOM BKNG PFE USB MRK COP MSFT V EBAY CF TFC KLAC
2012-03-30 WBD MSFT AAPL GE INTC BKNG PFE XOM USB QCOM VLO COP ORCL CF SPG
2012-04-30 AAPL GE XOM KLAC WBD QCOM KMB MDLZ MRK COP TJX TT V VFC BKNG
2012-05-31 BKNG MDLZ LLY WBD XEL MRK AAPL PCG XOM STX QCOM KLAC INTC LUMN CL
2012-06-29 XEL XOM LLY PFE MDLZ PCG AAPL STX WELL LUMN ORCL TWX COP AEP V
2012-07-31 AAPL VRTX XOM MDLZ MSFT COP PPL TWX QCOM WM BKNG V BRK-B WDC SYY
2012-08-31 STX XOM AAPL MRK QCOM PPL XEL COP MDT ORCL GE TWX SYY CF CVX
2012-09-28 STX XOM QCOM AAPL KMB LUMN ORCL MDT CVX AEP WDC BRK-B VLO KMI GE
2012-10-31 XOM GE VLO AAPL JPM COP PPL TWX CF QCOM MO WBD BRK-B SPG SYY
2012-11-30 XOM NEE GE KBH BKNG SYY STX KMB AMGN MDT WFC ORCL QCOM WELL BRK-B
2012-12-31 STX GE CSCO PFE NEE WELL XOM UNP ORCL WFC SRE MS AMGN VTRS SYY
2013-01-31 STX META CSCO GE BAC ZBH SBAC PPG F PHM PFE XOM WFC CMCSA LPX
2013-02-28 STX MS PHM CSCO WELL WFC NEE STT WM UNP XOM F BAC ORCL KMB
2013-03-28 GS WM JPM VLO WFC GE BKNG T PG STX XOM MO VTRS CSCO STT
2013-04-30 PFE GILD AMGN WFC T NI BKNG JPM FNMA SBAC CSCO KR XOM MO FMCC
2013-05-31 WFC BKNG FNMA PFE REGN FMCC KKR MCO RTX MO GILD TWX GE KBH MA
2013-06-28 WFC FSLR FNMA PFE USB FMCC MCO WM REGN WU GE TJX MO RTX XOM
2013-07-31 BKNG WDC STX PFE FNMA USB WU GE FMCC TFC XOM BRK-B T GOOG UNP
2013-08-30 PFE WFC JNJ MA DAL RTX VFC USB JPM TSN GE TRIP MTG PRU BKNG
2013-09-30 PFE WFC JNJ RTX TWX MA COP TRIP VFC MTG GE USB T ORCL META
2013-10-31 META PFE MA WFC FNMA GE MGM TWX FMCC BKNG COP JNJ RTX ORCL TXN
2013-11-29 META PFE REGN MO V WFC JNJ FNMA PBI RTX MA COP ORCL BKNG T
2013-12-31 BKNG PFE V MO FNMA DAL META WFC MCK JNJ MA MSFT FMCC PBI XOM
2014-01-31 V PFE MA MO FNMA MGM UNP WFC RTX BKNG FMCC JNJ USB T ESRX
2014-02-28 PFE MSFT META MA MO WFC UNP V BKNG VLO RTX LLY ESRX CSCO REGN
2014-03-31 META BKNG WFC WYNN VZ T PFE ILMN V FNMA USB VTRS FMCC TFC MGM
2014-04-30 T VZ FNMA PFE VTRS V FMCC WEC META VNO USB INTC LLY XEL PPL
2014-05-30 META T VZ COP JNJ MO SRE PFE USB UPS OXY V LYB ETR XOM
2014-06-30 META VZ T MSFT WFC JNJ OXY DAL MO PFE LYB SRE ETR USB TRV
2014-07-31 VZ T MU V OXY WFC URI PFE META BKNG JNJ NFX USB UDR COP
2014-08-29 T VZ MU TWX WELL COP WFC META OXY GILD RSG EOG HAL V XOM
2014-09-30 VZ T GILD WFC MRK URI TWX BRK-B OXY WM V STT NTRS STLD WRB
2014-10-31 VZ T META GILD WELL NXPI WFC PM BRK-B WM SO XOM WRB URI TRV
2014-11-28 VZ T GILD META SO HIG PAYX VTR CSX TJX ABBV UNP USB WFC MS
2014-12-31 T VZ WELL GILD TJX AMGN AAPL ZTS WM META SO PLD WEC EIX EW
2015-01-30 T VZ RCL PLD BX KR META GILD GE SYY WELL WY HST ITW JNJ
2015-02-27 KR T VZ SHW GILD RCL PLD PPG WELL GE MAC TJX META PCG TT
2015-03-31 GILD TXN GE AAPL TJX META TT V PAYX WELL WY VTR SBUX KR ITW
2015-04-30 SWKS JPM BKNG TWX NXPI VLO GILD META PNC USB INCY MO TEL LH TXN
2015-05-29 KMI TWX PNC GILD SWK META BKNG WFC USB XOM TFC LH GE JNJ PPG
2015-06-30 GILD TWX XOM PNC BKNG USB TFC WFC CSCO COF PPG STT BNY KMI PFE
2015-07-31 GILD GE TWX TFC CI PLD TSN WFC META CSCO USB NEE JPM STZ VLO
2015-08-31 CCI NEE PM GILD GE WM XEL MDLZ SYY SO PPL PLD RSG WEC KMB
2015-09-30 NEE PM WM PLD INTC WELL PEP SRE GILD KO CSCO HUM BRK-B WEC BKNG
2015-10-30 PM PLD NEE INTC SO PEG KO SRE GILD WY MO SPG SYY ORCL JNJ
2015-11-30 NEE INTC GILD SO GE MO WEC JPM CSCO JNJ V PCG USB KO BKNG
2015-12-31 NEE GILD XEL SO OMC CSCO JNJ MO V GE USB KO TEL PCG UAL
2016-01-29 PLD WEC PCG IBM EIX GE GILD OMC TAP PG GOOG MRK TXN PEG USB
2016-02-29 VZ UAL T ABBV BRK-B UPS RTX IBM SCG XEL BKNG GILD MRK PM EXC
2016-03-31 VZ TJX CCI T IBM PM EMR UPS PPG BRK-B ORCL MRK RTX GILD ABBV
2016-04-29 ABBV ZBH CCI RTX VZ BRK-B EMR TJX MRK GILD XOM UPS SPG SWK T
2016-05-31 ABBV CSCO TT MRK GE QCOM XOM SWK META VTR T TWX NXPI KHC INTC
2016-06-30 VTR ABBV MRK KHC KLAC SHW PFE MCD T CSCO GE AMGN INTC TWX CCI
2016-07-29 VZ CCI XEL WEC OKE PCG DLR IBM ABBV META MO WM KLAC SRE INTC
2016-08-31 T VZ ABBV META SYY MSFT PG WM CLF TSN ULTA WMB AMGN VTR BKNG
2016-09-30 ABBV T BKNG MSFT VZ PG META WMB ZTS SPGI WM MS JPM BAC TWX
2016-10-31 BKNG T USB VZ META GOOG WB GILD JPM ABBV PNC GOOGL TFC BAC UAL
2016-11-30 T USB META VZ CSCO PNC TFC PG IBM PRU BRK-B PSKY GOOGL TJX PEP
2016-12-30 T META NVDA VZ DD SPGI BRK-B WM KLAC CLF STLD PG YUM DAL CSCO
2017-01-31 T MSFT NVDA SPGI GS VZ STLD BRK-B DAL WM CSCO TFC PG AAPL CLF
2017-02-28 META T NVDA SPGI CLF ABBV CSCO PM PG MO GOOGL VZ BRK-B MSFT ADBE
2017-03-31 MO PM META PG USB INCY SPGI BAC CSCO EBAY CSX IBM CCL ORCL WM
2017-04-28 META MSFT MO TWX SPGI PG TXN SHW PM CSCO GOOG ABBV GOOGL USB MDT
2017-05-31 META MO ADBE MSFT PG GOOGL KHC NEE TWX WB XEL TXN BKNG PEP GILD
2017-06-30 NVDA LRCX AMAT MSFT MO WB NEE PG META TTWO ABBV TWX VEEV XEL AMGN
2017-07-31 AMAT VRTX NEE PG META TWX ABBV XEL ISRG LRCX KHC MA MSFT VRSN LITE
2017-08-31 V XEL META PG TWX NXPI JPM PM INTC BRK-B WTW WM SRE WEC VRTX
2017-09-29 VRTX WB INTC PG META V XEL TWX MNST WM NVDA WTW RCL ADBE JPM
2017-10-31 ABBV WB NEE TXN MO WTW SPGI TROW V PG XEL MSFT MNST BRK-B ZTS
2017-11-30 MU LRCX XYZ NVDA AMAT ON XOM TXN PFE MO MA INTC NXPI META XEL
2017-12-29 XYZ MU NVDA PFE MO NEE XOM BBBY PG NXPI MS TXN META BRK-B JPM
2018-01-31 TXN MO BBBY PFE MU TROW MS META WFC BRK-B ABBV XOM PNC TFC WM
2018-02-28 ANET NXPI BBBY BKNG MO TXN LRCX META PFE TFC WM XOM NEE BX STZ
2018-03-29 MU XYZ NXPI PFE ANET NEE VZ PSX TJX WM T TWX SYY XOM SRE
2018-04-30 MU PFE TJX XYZ VZ TWX ANET NKTR XEL NXPI SRE FE T XOM WM
2018-05-31 PFE VZ NEE TWX V XOM STZ MU CVX T SEDG EXC WM F MRK
2018-06-29 MU PFE TWX NEE VZ V XOM VICI USB BKNG WFC META CVX PSX PAYX
2018-07-31 MU VZ V MRK NEE TTD BKNG USB XOM PAYX MCO TXN MO DIS TJX
2018-08-31 MRK VZ MU USB NEE WFC PFE EVHC EXC DIS WELL XOM WAB RSG V
2018-09-28 VZ USB NEE XOM VICI V TJX MU BRK-B FTV PFE SPG CVNA EXC SRE
2018-10-31 XYZ XEL NEE WM WEC USB PPL XOM WFC TJX SRE WMB MDLZ AVGO BRK-B
2018-11-30 USB VICI MDLZ XOM T MRK SO MO PPL PNW PFE SRE AVGO MKC PEG
2018-12-31 MDLZ SRE USB T MRK MO OMC PPL SO PFE XEL NI PEP XOM MKC
2019-01-31 T USB CMCSA WTW VICI MU PAYX V AVGO DIS XOM MRK OXY XEL TFC
2019-02-28 AVGO T SRE CMCSA XOM USB XYZ CVX SPG TJX SYY V TFC DIS MRK
2019-03-29 JNJ PEP LRCX WMB SRE HON TSN TJX CVX MU VICI ADI AXP T JCI
2019-04-30 ORCL JNJ SYF META SRE TSN WMB CSCO IBM LIN MKC VFC INTC NEE TJX
2019-05-31 KO JNJ LLY SYF WU WMB AMGN MRK BKNG TXN BMY TJX ICE MSFT USB
2019-06-28 PEP KO JNJ MSFT AMGN USB CCI UNP BKNG QCOM ICE GILD META WELL T
2019-07-31 PEP KO USB AMGN JNJ WELL ICE MRSH IBM BKNG WU GS NEM JPM V
2019-08-30 GILD JNJ QCOM SYY INTC MSFT USB HON JPM VRTX BMY IBM CCI WEC V
2019-09-30 BMY ORCL GILD JNJ BKNG USB CCI JPM WFC QCOM INTC PSX STZ SPGI V
2019-10-31 SYY BKNG GILD ORCL JNJ WFC GOOGL JPM PPL CCI VICI VRTX PSX USB PLD
2019-11-29 QCOM KLAC USB WFC ORCL SYY KO PEP BMY GOOGL PNC GOOG TFC JNJ VICI
2019-12-31 QCOM USB WFC PEP LLY KO ORCL GOOG MSFT VRTX PM AMGN WU MDT MS
2020-01-31 JNJ PEP AMGN SWKS MSFT BMY QCOM TER ORCL V QRVO WM SIVB TJX VRTX
2020-02-28 JNJ KO PEP XEL ORCL PM WEC QCOM MNST SRE SWKS SPGI TSLA WM MSFT
2020-03-31 VZ PFE MRK MO ENPH KO SJM ABBV MA WBD WM MSFT QCOM WTW CL
2020-04-30 MO ANET ABBV QCOM KO WBD MSFT KR VRTX WM IBM PCAR MA REGN GEN
2020-05-29 PFE VZ PGR QCOM MRK MO KO MSFT ABBV ANET SJM MDLZ CSCO V VRTX
2020-06-30 PFE VZ ENPH MSFT ABBV KO SPGI MO VRTX META QCOM MA UNP CSCO PCAR
2020-07-31 VZ PFE EBAY ABBV MSFT MRSH KO XEL SPGI QCOM MO ADBE MDLZ VRTX GOOG
2020-08-31 VZ MO BBBY PFE EBAY XEL MDLZ MSFT ETSY KMB META VRTX KO REGN ABBV
2020-09-30 PG VZ ABBV BBBY META PFE PGR MO VRTX BRK-B KO WM VRSK MDLZ AAPL
2020-10-30 PENN VZ ABBV ENPH PSKY PFE VIAC KO CVNA MO TSLA MS TUP META MSFT
2020-11-30 PG PSKY ABBV VZ VIAC INTC MSFT TMO META PAYX TT ADBE SLM XEC TUP
2020-12-31 XYZ MRNA PG ETSY ABBV VZ GE PENN DVN LRCX PSKY VIAC TTD AMAT PCG
2021-01-29 ENPH MS ABBV PSKY PG LRCX CLF PBI TER ETSY VZ TUP SCHW GS DVN
2021-02-26 ENPH ABBV PG PENN TUP XYZ VZ CLF TDC CSCO JPM TSLA PBI PGR GME
2021-03-31 ETSY WBD DVN MO TRIP TPR MS PG OXY GS FANG PENN MRNA FCX VRTX
2021-04-30 AMAT TRIP VIAC LRCX PG DVN WSM VRTX ORCL DISCA DISCK TDC TPL ETSY FCX
2021-05-28 VRTX PG PM WSM PGR MAC BRK-B TPL CLF VZ WM LPX GME PFE OMC
2021-06-30 NUE PM FCX MAC XEC PG ETSY TRGP BRK-B STLD ORCL WM WMB CLF PFE
2021-07-30 OTIS PG PM DVN WM ZTS GOOGL MRSH TRGP JPM PFE SHW MO GOOG PXD
2021-08-31 MRNA PFE RE WM AMD QCOM ZTS SHW MSFT PAYX MRSH SIVB PKI CLF ACN
2021-09-30 MRNA BX PFE WM AMD SIVB MRSH SBNY ZTS AVGO RSG XEC NUE GOOGL SHW
2021-10-29 MRNA WM QCOM ZTS SHW SBNY RRC EXC SIVB CB ORCL VRSK UNP MCD C
2021-11-30 GILD MRNA JPM SHW VRSK CAR RRC UNP VZ TXN ICE SPG MCD GS MO
2021-12-31 AMD GILD BX UNP NVDA CAR KKR PFE MO JPM ZTS MCD VRSK SPG VZ
2022-01-31 GILD MO UNP ON PFE BRK-B PM MDLZ GOOGL VZ STZ AVGO XEL JPM TXN
2022-02-28 GILD REGN PM VZ MRK XEL PFE BMY MET WM SYY JPM TRV MCD ICE
2022-03-31 GILD MRK XEL VZ ABBV REGN WM MDLZ MCD SPG WEC COP KDP JNJ WMB
2022-04-29 GILD REGN ABBV MDLZ FCX VZ VICI STZ T KDP WMB VRSK PM PFE TXN
2022-05-31 GILD PFE ABBV REGN VZ TXN MRNA MRK CF UNP WMB BMY SRE USB KDP
2022-06-30 VZ ABBV UNP CL MRNA TXN GILD MRO PFE MRK USB REGN BMY TFC DVN
2022-07-29 GILD UNP MDLZ ABBV VZ MRNA WY PFE BRK-B UPS SPG MRK GS TXN DVN
2022-08-31 ABBV UNP VRTX MDLZ PM UPS CF MRNA MS NDAQ VRSK V VICI MCK T
2022-09-30 VRTX MS WFC MDLZ V BRK-B WTW MCHP MRNA MO TXN PLD MOS CF T
2022-10-31 PFE MRNA WM WFC V TXN MDLZ JPM VRTX PM T MO MS GS BRK-B
2022-11-30 T PFE MO MRNA JPM WFC MCHP MDLZ TXN VRTX BKNG WM MRK VZ TJX
2022-12-30 MRNA T PFE ABBV PM JPM MDLZ BKNG SPG AMGN VZ TXN BRK-B MRK VRTX
2023-01-31 T JPM MO MRNA ABBV PM VZ BKNG MS WFC PFE TXN AVGO VRTX USB
2023-02-28 MO ZBH VZ WFC VICI PM PFE VRTX C BRK-B PSA AVGO MET USB BSX
2023-03-31 MO VZ BKNG VRTX ZBH PFE PM CVX PSA BRK-B V HSY TEL QCOM AVGO
2023-04-28 MO VZ PFE BKNG CVX WM AVGO KMB BRK-B MCHP PM ZTS TXN VICI RSG
2023-05-31 MO NEE WM VZ BRK-B BKNG VRTX GILD ROP PFE ZTS STZ MA CVX PSA
2023-06-30 MO XOM TJX MDLZ NEE MRK PCG BRK-B MRSH BKNG WM VZ RSG ORCL AVGO
2023-07-31 MO NEE XOM ORCL BRK-B STZ MSFT BKNG ROP MRSH AVGO VRTX V CVX OXY
2023-08-31 SMCI MO JPM NEE XOM WMB STZ MCD ICE AMGN MDLZ PM ABNB COP FISV
2023-09-29 MO SMCI CVNA PLTR V STZ WFC MDLZ PM GILD MCD PRU ICE WRB CME
2023-10-31 MO UNP RSG V WM GILD MRK WFC MCD HUM PM OKE TMUS KMI ICE
2023-11-30 MO UNP WFC JNJ VZ TMUS VRSK BRK-B GILD WM MCD BKNG WRB PEG EA
2023-12-29 UNP WFC MO XYZ GILD JNJ TJX BKNG CVNA TMUS WMB MCD SPG ADBE C
2024-01-31 MO VZ UNP MRK AVGO WFC BKNG TJX JNJ NVDA COIN MCD C BRK-B META
2024-02-29 SMCI MRK JNJ UNP MO TJX BRK-B TMUS TDG MCD MSFT META IBM CSCO SPG
2024-03-28 META SMCI NVDA AVGO MO PLTR DELL JNJ ANET MSFT GE ANF MRK BRK-B UNP
2024-04-30 SMCI NVDA META WM MO PLTR HOOD MRK OKE WMB JNJ NEE COIN JCI ANF
2024-05-31 MO META DELL WM CVNA COIN WELL NVDA TMUS JNJ KMI VLTO MRK CL T
2024-06-28 NVDA VST VRT DELL PM FSLR JNJ IBM META BRK-B VRTX MRK MO QCOM MRSH
2024-07-31 NVDA IBM META ANF JNJ HOOD AVGO MO MS BRK-B VRTX COIN T FSLR TJX
2024-08-30 NVDA IBM JNJ META TJX BRK-B LUMN WELL AMT AVGO TMUS PPL WEC UDR KDP
2024-09-30 NVDA JNJ AMT MO WELL SPGI PM WEC VTR XEL TJX MCO BRK-B KDP IBM
2024-10-31 JNJ IBM META WEC NVDA LUMN PPL AMT SPGI TMUS PLTR CMCSA XEL HOOD MSI
2024-11-29 NVDA TJX VRT XEL LUMN WMB COIN WEC META TPL KMI ORCL V CRM SO
2024-12-31 NVDA VST TJX APP TPL VRT CVNA XEL WMB TMUS WEC META WDAY COIN BRK-B
2025-01-31 TJX COIN NVDA META LULU WDAY MA TPL VRT FNMA WEC GEV SPGI BRK-B CME
2025-02-28 META PLTR HOOD TJX BRK-B NVDA LULU WM APP JPM ICE MRSH SPGI V UBER
2025-03-31 VZ PFE HOOD WM PLTR META VICI V UBER XOM ROP OTIS NVDA UNP MO
2025-04-30 PFE MDLZ KDP META HOOD MO V TSN NVDA AMT VZ PM WELL SHW CPRT
2025-05-30 GILD MDLZ PM APP KDP VICI EW AMT META LHX MRSH NVDA UBER V KMB
2025-06-30 VZ TJX GILD WM SMCI MDLZ PM VRT VICI MPWR APP AMT BKNG MCD XEL
2025-07-31 VZ NVDA SMCI TJX BKNG RCL BAC VICI MPWR GILD WM XOM AVGO COIN SYY
2025-08-29 VZ COIN NVDA TJX PLTR GILD MPWR LRCX NSC VRT HOOD XYZ MSFT PNC USB
2025-09-30 VZ AVGO USB NVDA GOOGL XEL GILD WMB SRE PNC WEC TFC GOOG JNJ D
2025-10-31 NEM TJX VZ GILD TE NVDA MO SRE AVGO UNP WEC USB XOM DIS META
2025-11-28 HOOD NVDA MPWR VZ LUMN SRE UNP NSC TE MO APP GILD USB VRTX WEC
2025-12-31 AVGO VZ PFE NVDA LUMN T USB XEL MO VRT SRE UNP WELL PLTR AMT
2026-01-30 KLAC NEM WDC PFE TFC T NVDA AVGO MO PNC ECHO BAC SCHW AMT RF
2026-02-27 PFE MO TE GILD T UNP PM NVDA USB KLAC XEL AVGO CMCSA BMY KO
2026-03-31 MU SPG T VZ GILD XEL AVGO NVDA MO UNP NEM WDC COHR PFE WM
2026-04-30 GILD T NVDA TJX VZ UNP VTR MU WM KLAC SRE XEL KVUE TFC NEM
2026-05-29 NVDA VZ VRT APA LITE CF T GILD VTR MU BAC MSFT WFC WELL RF
2026-06-26 WDC HPE STX VRT USB TE NVDA LITE VZ MU GILD ADI TXN TRV QCOM
Scoring script (python)
FORMULA_NAME = "Recovery Quality Contrarian 52-Week Hybrid (Evidence-Relay Arbitration, v1195)"
LOGIC_VARIANT_COUNT = 4
NOTES = """mode=explore; family=recovery-quality-contrarian-52w-hybrid
New hybrid family built as an evidence-relay rather than a static blend: every stock is first classified into a repair, leadership, durability, or skeptical state, then each regime branch decides which state is allowed to dominate and how hard conflicting signals are taxed. The design preserves what deep-52w contrarian repair does well, keeps recovery-quality discipline so damaged junk does not float to the top, and still lets genuine leaders win in cleaner tapes only after extension, volatility, and valuation sanity checks clear.
Deliberate metric coverage this run: active momentum uses return_3m_pct, return_6m_pct, and momentum_12_1_pct; trend/recovery uses both 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; valuation uses forward_pe and peg; growth uses 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 stability tilt. Deliberate weight-0 metrics this run: return_1m_pct, return_12m_pct, dividend_ttm, pe, eps_growth_pct, revenue_growth_pct, shares_outstanding, close, adj_close, high_52w, ma_200d, eps_ttm, revenue_ttm, operating_income_ttm, and free_cash_flow_ttm. Sparse fundamentals are normalized by present weight inside each case so missing fields do not mechanically dominate selection."""

ACTIVE_METRICS = (
    "return_3m_pct",
    "return_6m_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",
    "forward_pe",
    "peg",
    "operating_income_growth_pct",
    "free_cash_flow_growth_pct",
    "forward_eps",
    "operating_margin_pct",
    "free_cash_flow_margin_pct",
    "market_cap",
)

REPAIR_WEIGHTS = {
    "from_52w_high_pct": (0.24, -1),
    "from_200d_ma_pct": (0.18, +1),
    "return_3m_pct": (0.16, +1),
    "return_6m_pct": (0.10, +1),
    "operating_margin_pct": (0.08, +1),
    "free_cash_flow_margin_pct": (0.08, +1),
    "operating_income_growth_pct": (0.06, +1),
    "free_cash_flow_growth_pct": (0.05, +1),
    "forward_pe": (0.03, -1),
    "peg": (0.02, -1),
}

LEADERSHIP_WEIGHTS = {
    "momentum_12_1_pct": (0.22, +1),
    "return_6m_pct": (0.18, +1),
    "return_3m_pct": (0.10, +1),
    "from_200d_ma_pct": (0.10, +1),
    "operating_margin_pct": (0.09, +1),
    "free_cash_flow_margin_pct": (0.08, +1),
    "operating_income_growth_pct": (0.07, +1),
    "free_cash_flow_growth_pct": (0.06, +1),
    "forward_eps": (0.05, +1),
    "realized_vol_3m": (0.03, -1),
    "forward_pe": (0.02, -1),
}

DURABILITY_WEIGHTS = {
    "realized_vol_3m": (0.20, -1),
    "operating_margin_pct": (0.16, +1),
    "free_cash_flow_margin_pct": (0.14, +1),
    "dividend_yield_ttm_pct": (0.12, +1),
    "market_cap": (0.10, +1),
    "forward_pe": (0.08, -1),
    "peg": (0.06, -1),
    "from_200d_ma_pct": (0.05, +1),
    "trading_days_3m": (0.05, +1),
    "avg_daily_dollar_volume_3m": (0.04, +1),
}

LIQUIDITY_WEIGHTS = {
    "avg_daily_volume_3m": (0.34, +1),
    "avg_daily_dollar_volume_3m": (0.46, +1),
    "trading_days_3m": (0.20, +1),
}


def _safe_float(value):
    try:
        if value is None:
            return None
        value = float(value)
        if value != value:
            return None
        return value
    except Exception:
        return None


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


def _metric_value(stock, name):
    if isinstance(stock, dict):
        return _safe_float(stock.get(name))
    return None


def _symbol_of(stock, idx):
    if isinstance(stock, dict):
        symbol = stock.get("symbol")
        if symbol is not None:
            return symbol
    return "stock_%s" % idx


def _build_rank_maps(stocks):
    rank_maps = {}
    for metric in ACTIVE_METRICS:
        pairs = []
        i = 0
        while i < len(stocks):
            v = _metric_value(stocks[i], metric)
            if v is not None:
                pairs.append((v, i))
            i += 1
        pairs.sort(key=lambda x: x[0])
        metric_ranks = {}
        n = len(pairs)
        if n == 1:
            metric_ranks[pairs[0][1]] = 0.5
        elif n > 1:
            j = 0
            while j < n:
                metric_ranks[pairs[j][1]] = float(j) / float(n - 1)
                j += 1
        rank_maps[metric] = metric_ranks
    return rank_maps


def _weighted_score(rank_maps, idx, weights):
    total = 0.0
    present = 0.0
    for metric, cfg in weights.items():
        metric_ranks = rank_maps.get(metric, {})
        if idx in metric_ranks:
            w, direction = cfg
            r = metric_ranks[idx]
            if direction < 0:
                r = 1.0 - r
            total += w * r
            present += w
    if present <= 0.0:
        return 0.0
    return total / present


def _regime_branch(regime):
    label = ""
    if isinstance(regime, str):
        label = regime.lower()
    elif isinstance(regime, dict):
        raw = regime.get("label")
        if raw is None:
            raw = regime.get("name")
        if raw is not None:
            label = str(raw).lower()

    if "panic" in label or "crash" in label or "bear" in label or "risk_off" in label or "risk-off" in label:
        return "washout"
    if "bull" in label or "trend" in label or "risk_on" in label or "risk-on" in label:
        return "trend"
    if "defen" in label or "late" in label or "slow" in label:
        return "defensive"
    if "trans" in label or "mixed" in label or "chop" in label:
        return "transition"

    trend = 0.0
    risk = 0.0
    breadth = 0.0
    if isinstance(regime, dict):
        for key in ("trend", "market_trend", "risk_on", "uptrend", "momentum"):
            v = _safe_float(regime.get(key))
            if v is not None:
                trend = v
                break
        for key in ("risk_off", "stress", "volatility", "drawdown_risk", "turbulence"):
            v = _safe_float(regime.get(key))
            if v is not None:
                risk = v
                break
        for key in ("breadth", "participation", "internals"):
            v = _safe_float(regime.get(key))
            if v is not None:
                breadth = v
                break

    if risk >= 0.65 or trend <= -0.35:
        return "washout"
    if trend >= 0.55 and breadth >= 0.45 and risk < 0.50:
        return "trend"
    if risk >= 0.45:
        return "defensive"
    return "transition"


def score_universe(stocks, regime, ctx):
    rank_maps = _build_rank_maps(stocks)
    branch = _regime_branch(regime)
    scores = {}

    i = 0
    while i < len(stocks):
        stock = stocks[i]
        symbol = _symbol_of(stock, i)

        repair = _weighted_score(rank_maps, i, REPAIR_WEIGHTS)
        leadership = _weighted_score(rank_maps, i, LEADERSHIP_WEIGHTS)
        durability = _weighted_score(rank_maps, i, DURABILITY_WEIGHTS)
        liquidity = _weighted_score(rank_maps, i, LIQUIDITY_WEIGHTS)

        drawdown = 1.0 - rank_maps.get("from_52w_high_pct", {}).get(i, 0.5)
        rebound = rank_maps.get("from_200d_ma_pct", {}).get(i, 0.5)
        trend_3m = rank_maps.get("return_3m_pct", {}).get(i, 0.5)
        trend_6m = rank_maps.get("return_6m_pct", {}).get(i, 0.5)
        momo = rank_maps.get("momentum_12_1_pct", {}).get(i, 0.5)
        vol_calm = 1.0 - rank_maps.get("realized_vol_3m", {}).get(i, 0.5)
        valuation = 0.5 * (
            (1.0 - rank_maps.get("forward_pe", {}).get(i, 0.5)) +
            (1.0 - rank_maps.get("peg", {}).get(i, 0.5))
        )
        quality = 0.5 * (
            rank_maps.get("operating_margin_pct", {}).get(i, 0.5) +
            rank_maps.get("free_cash_flow_margin_pct", {}).get(i, 0.5)
        )
        growth = (
            rank_maps.get("operating_income_growth_pct", {}).get(i, 0.5) * 0.45 +
            rank_maps.get("free_cash_flow_growth_pct", {}).get(i, 0.5) * 0.35 +
            rank_maps.get("forward_eps", {}).get(i, 0.5) * 0.20
        )

        repair_ready = _clamp(
            0.45 * drawdown +
            0.30 * rebound +
            0.15 * trend_3m +
            0.10 * quality,
            0.0,
            1.0,
        )
        leader_ready = _clamp(
            0.35 * momo +
            0.25 * trend_6m +
            0.15 * rebound +
            0.15 * quality +
            0.10 * growth,
            0.0,
            1.0,
        )
        durable_ready = _clamp(
            0.35 * durability +
            0.20 * quality +
            0.15 * vol_calm +
            0.10 * valuation +
            0.10 * liquidity +
            0.10 * rebound,
            0.0,
            1.0,
        )

        extension_penalty = _clamp(
            0.55 * (1.0 - drawdown) +
            0.45 * (1.0 - vol_calm),
            0.0,
            1.0,
        )
        broken_penalty = _clamp(
            0.45 * (1.0 - rebound) +
            0.35 * (1.0 - quality) +
            0.20 * (1.0 - liquidity),
            0.0,
            1.0,
        )
        conflict = abs(repair_ready - leader_ready)

        if repair_ready >= 0.62 and drawdown >= 0.58 and trend_3m >= 0.48:
            state = "repair"
        elif leader_ready >= 0.64 and trend_6m >= 0.56 and drawdown <= 0.55:
            state = "leader"
        elif durable_ready >= 0.60 and vol_calm >= 0.55:
            state = "durable"
        else:
            state = "skeptical"

        if branch == "washout":
            if state == "repair":
                score = (
                    0.52 * repair +
                    0.18 * durability +
                    0.12 * valuation +
                    0.10 * liquidity +
                    0.08 * leader_ready
                )
                score -= 0.18 * broken_penalty
            elif state == "durable":
                score = 0.62 * durability + 0.18 * repair + 0.12 * valuation + 0.08 * liquidity
            elif state == "leader":
                score = 0.42 * leadership + 0.24 * durability + 0.16 * repair + 0.18 * liquidity
                score -= 0.22 * extension_penalty
            else:
                score = 0.45 * durability + 0.30 * repair + 0.15 * valuation + 0.10 * liquidity
                score -= 0.16 * broken_penalty

        elif branch == "transition":
            if state == "repair":
                relay_bonus = 0.14 * leader_ready if conflict <= 0.22 else 0.04 * leader_ready
                score = 0.48 * repair + 0.20 * durability + 0.12 * valuation + 0.10 * liquidity + relay_bonus
                score -= 0.10 * broken_penalty
            elif state == "leader":
                relay_bonus = 0.12 * repair_ready if conflict <= 0.22 else 0.04 * repair_ready
                score = 0.42 * leadership + 0.18 * durability + 0.12 * quality + 0.10 * growth + 0.08 * liquidity + relay_bonus
                score -= 0.12 * extension_penalty
            elif state == "durable":
                score = 0.48 * durability + 0.18 * repair + 0.12 * leadership + 0.12 * valuation + 0.10 * liquidity
            else:
                if repair_ready >= leader_ready:
                    score = 0.40 * repair + 0.24 * durability + 0.14 * valuation + 0.12 * liquidity + 0.10 * growth
                    score -= 0.10 * broken_penalty
                else:
                    score = 0.40 * leadership + 0.24 * durability + 0.12 * growth + 0.12 * liquidity + 0.12 * quality
                    score -= 0.10 * extension_penalty

        elif branch == "trend":
            if state == "leader":
                score = (
                    0.50 * leadership +
                    0.16 * durability +
                    0.12 * growth +
                    0.10 * liquidity +
                    0.06 * valuation +
                    0.06 * repair_ready
                )
                score -= 0.14 * extension_penalty
            elif state == "repair":
                score = 0.44 * repair + 0.18 * leadership + 0.16 * durability + 0.10 * growth + 0.12 * liquidity
                score -= 0.12 * broken_penalty
            elif state == "durable":
                score = 0.44 * durability + 0.24 * leadership + 0.12 * growth + 0.10 * liquidity + 0.10 * valuation
            else:
                score = 0.34 * leadership + 0.30 * durability + 0.16 * repair + 0.10 * growth + 0.10 * liquidity
                score -= 0.08 * extension_penalty

        else:  # defensive
            if state == "durable":
                score = 0.56 * durability + 0.14 * valuation + 0.12 * liquidity + 0.10 * repair_ready + 0.08 * leadership
            elif state == "repair":
                score = 0.40 * repair + 0.30 * durability + 0.12 * valuation + 0.10 * liquidity + 0.08 * quality
                score -= 0.12 * broken_penalty
            elif state == "leader":
                score = 0.34 * leadership + 0.34 * durability + 0.10 * valuation + 0.12 * liquidity + 0.10 * quality
                score -= 0.16 * extension_penalty
            else:
                score = 0.50 * durability + 0.18 * valuation + 0.16 * liquidity + 0.08 * repair + 0.08 * quality

        score += 0.04 * liquidity
        score = _clamp(score, 0.0, 1.0)
        scores[symbol] = score
        i += 1

    return scores