fix(backtest): one window, and stop calling a rejected exit "recommended"
Two ways the recommendation still disagreed with the page it sits on. It preferred the "all" monitor row while the UI defaulted its selector to "3y", so a default page load showed one set of returns in the tiles and a different set in the recommendation. The row it used is now published as basis_lookback and the page defaults to it, so the two cannot open on different windows. The test fixture gains a second monitor row with different numbers — with only an "all" row present, a lookback mix-up could not fail. Robustness picked its basis between "the recommended Nd hold" and "the S/R target exit", naming an exit the production book replaced as recommended. There is no ATR-trail ex-top-5% figure in the report, so it now always reports the gate-level grading and says that is what it is, rather than dressing a legacy number as a verdict on the production book. time_exit_sweep is no longer read here at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1287,6 +1287,12 @@ def test_build_recommendation_reads_the_report():
|
||||
"strategy": "prod", "lookback": "all", "lookback_label": "All history",
|
||||
"cagr_pct": 40.0, "sharpe": 1.72, "max_drawdown_pct": 17.7,
|
||||
"total_return_pct": 297.8, "spy_return_pct": 101.9,
|
||||
}, {
|
||||
# A second window with DIFFERENT numbers. Without it the "all"
|
||||
# preference is untested and a lookback mix-up cannot fail.
|
||||
"strategy": "prod", "lookback": "3y", "lookback_label": "3y",
|
||||
"cagr_pct": 47.9, "sharpe": 1.96, "max_drawdown_pct": 17.3,
|
||||
"total_return_pct": 220.9, "spy_return_pct": 71.5,
|
||||
}],
|
||||
},
|
||||
}
|
||||
@@ -1308,12 +1314,21 @@ def test_build_recommendation_reads_the_report():
|
||||
assert "keep the NEUTRAL exclusion" in gate_texts
|
||||
assert "80" in by_topic["cutoff"][0]
|
||||
assert "beats" in by_topic["benchmark"][0]
|
||||
# robustness is judged under the RECOMMENDED exit (the 30d hold), not the
|
||||
# target model the recommendation advises abandoning
|
||||
assert any(
|
||||
"not a handful of outliers" in t and "under the recommended 30d hold" in t
|
||||
for t in by_topic["robustness"]
|
||||
)
|
||||
|
||||
# Every production figure comes from ONE window, and the report says which,
|
||||
# so the page can default its selector to the same one.
|
||||
assert rec["basis_lookback"] == "all"
|
||||
assert rec["basis_lookback_label"] == "All history"
|
||||
assert "+40.0%" in by_topic["production"][0]
|
||||
assert "47.9" not in by_topic["production"][0] # the 3y row must not leak in
|
||||
assert "220.9" not in by_topic["benchmark"][0]
|
||||
|
||||
# Robustness names its real basis. It used to claim "under the recommended
|
||||
# 30d hold" — nothing recommends that exit; production is the ATR trail.
|
||||
robustness = by_topic["robustness"][0]
|
||||
assert "not a handful of outliers" in robustness
|
||||
assert "gate-level grading" in robustness
|
||||
assert "recommended" not in robustness
|
||||
|
||||
|
||||
def test_build_recommendation_flags_outlier_dependence():
|
||||
|
||||
Reference in New Issue
Block a user