fix: judge robustness under the recommended exit, not the abandoned one
The robustness warning was computed on the target-model distribution while the same panel recommends the hold exit — internally inconsistent. _robustness_stats (median, profit factor, ex-top-5% expectancy) is now shared by _bucket_stats and _time_exit_bucket, the time-exit table shows Median Net R and Ex-Top-5% per hold length, and _build_recommendation reads the trimmed expectancy from the recommended exit's bucket (falling back to the target model when no hold is recommended). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -143,6 +143,10 @@ class TestTimeExitBucket:
|
||||
# No stop_day on any candidate → every hold runs the full 5 days.
|
||||
assert b["avg_hold_days"] == 5.0
|
||||
assert b["net_r_per_day"] == pytest.approx(0.28 / 5.0, abs=0.001)
|
||||
# robustness on net rs [1.38, -1.02, 0.48]
|
||||
assert b["median_net_r"] == pytest.approx(0.48, abs=0.001)
|
||||
assert b["profit_factor"] == pytest.approx(1.86 / 1.02, abs=0.01)
|
||||
assert b["net_avg_r_ex_top5"] == pytest.approx((0.48 - 1.02) / 2, abs=0.001)
|
||||
|
||||
def test_missing_hold_skipped(self):
|
||||
b = bt._time_exit_bucket([{"time_r": {5: 1.0}}], 21)
|
||||
@@ -341,7 +345,7 @@ def test_build_recommendation_reads_the_report():
|
||||
"overall_qualified": {"net_avg_r": 0.13, "net_avg_r_ex_top5": 0.05},
|
||||
"time_exit_sweep": [
|
||||
{"hold_days": 21, "net_avg_r": 0.38},
|
||||
{"hold_days": 30, "net_avg_r": 0.50},
|
||||
{"hold_days": 30, "net_avg_r": 0.50, "net_avg_r_ex_top5": 0.21},
|
||||
],
|
||||
"gate_ablation": [
|
||||
{"variant": "all_floors", "total": 100, "hold_net_avg_r": 0.50},
|
||||
@@ -374,7 +378,12 @@ 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]
|
||||
assert any("not a handful of outliers" in t for t in by_topic["robustness"])
|
||||
# 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"]
|
||||
)
|
||||
|
||||
|
||||
def test_build_recommendation_flags_outlier_dependence():
|
||||
|
||||
Reference in New Issue
Block a user