diff --git a/reports/execution_recovery_matrix.json b/reports/execution_recovery_matrix.json new file mode 100644 index 0000000..9fea9f9 --- /dev/null +++ b/reports/execution_recovery_matrix.json @@ -0,0 +1,796 @@ +{ + "generated_at": "2026-07-18T16:56:10.007302", + "snapshot": "/Users/taathde3/git/lab/signal_platform/backtest_snapshots/prod.sqlite", + "validation_split": "2024-07-01", + "n_trials": 4, + "hypothesis": "stale_close (signal t-1, fill t close) recovers close-fill economics; the next_open haircut is scheduling, not lost edge", + "decision_baseline": "next_open", + "qualified_longs": 5189, + "arms": [ + { + "id": "close_control", + "label": "Close fill (historical control)", + "config": { + "fill_mode": "close" + }, + "windows": [ + { + "window": "train", + "dsr": 0.936, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "close", + "final_equity": 23706.04, + "total_return_pct": 137.1, + "cagr_pct": 49.8, + "max_drawdown_pct": 17.9, + "calmar": 2.78, + "sharpe": 1.75, + "sharpe_se": 0.675, + "psr": 0.9953, + "n_returns": 535, + "return_skew": 0.4266, + "return_kurtosis": 4.9374, + "trades": 240, + "win_rate": 36.7, + "avg_trade_pnl": 57.11, + "best_trade_r": 12.02, + "worst_trade_r": -3.1, + "best_trade_pnl": 2008.56, + "worst_trade_pnl": -561.69, + "avg_hold_days": 15.3, + "exit_reasons": { + "stop": 112, + "time": 53, + "trailing_stop": 75 + }, + "skipped_book_full": 327, + "spy_return_pct": 36.7, + "yearly_returns": [ + { + "year": 2022, + "return_pct": 11.9 + }, + { + "year": 2023, + "return_pct": 78.1 + }, + { + "year": 2024, + "return_pct": 19.1 + } + ], + "start_date": "2022-06-24", + "end_date": "2024-08-12", + "post_stop_events": 112, + "post_stop_reentries": 61, + "post_stop_states_open_at_end": 51 + }, + { + "window": "validation", + "dsr": 0.9039, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "close", + "final_equity": 20060.98, + "total_return_pct": 100.6, + "cagr_pct": 41.6, + "max_drawdown_pct": 20.9, + "calmar": 1.99, + "sharpe": 1.68, + "sharpe_se": 0.716, + "psr": 0.9905, + "n_returns": 502, + "return_skew": -0.0866, + "return_kurtosis": 4.395, + "trades": 239, + "win_rate": 35.1, + "avg_trade_pnl": 42.1, + "best_trade_r": 12.03, + "worst_trade_r": -2.82, + "best_trade_pnl": 2012.72, + "worst_trade_pnl": -330.01, + "avg_hold_days": 14.0, + "exit_reasons": { + "stop": 121, + "time": 44, + "trailing_stop": 74 + }, + "skipped_book_full": 207, + "spy_return_pct": 36.6, + "yearly_returns": [ + { + "year": 2024, + "return_pct": 16.7 + }, + { + "year": 2025, + "return_pct": 50.3 + }, + { + "year": 2026, + "return_pct": 14.5 + } + ], + "start_date": "2024-07-01", + "end_date": "2026-07-02", + "post_stop_events": 121, + "post_stop_reentries": 63, + "post_stop_states_open_at_end": 58 + }, + { + "window": "full", + "dsr": 0.9939, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "close", + "final_equity": 48810.86, + "total_return_pct": 388.1, + "cagr_pct": 48.3, + "max_drawdown_pct": 21.6, + "calmar": 2.23, + "sharpe": 1.77, + "sharpe_se": 0.496, + "psr": 0.9998, + "n_returns": 1008, + "return_skew": 0.2714, + "return_kurtosis": 4.9751, + "trades": 472, + "win_rate": 36.2, + "avg_trade_pnl": 82.23, + "best_trade_r": 12.03, + "worst_trade_r": -3.1, + "best_trade_pnl": 4897.19, + "worst_trade_pnl": -802.94, + "avg_hold_days": 14.6, + "exit_reasons": { + "stop": 229, + "time": 96, + "trailing_stop": 147 + }, + "skipped_book_full": 519, + "spy_return_pct": 90.9, + "yearly_returns": [ + { + "year": 2022, + "return_pct": 11.9 + }, + { + "year": 2023, + "return_pct": 78.1 + }, + { + "year": 2024, + "return_pct": 42.5 + }, + { + "year": 2025, + "return_pct": 50.3 + }, + { + "year": 2026, + "return_pct": 14.5 + } + ], + "start_date": "2022-06-24", + "end_date": "2026-07-02", + "post_stop_events": 229, + "post_stop_reentries": 142, + "post_stop_states_open_at_end": 87 + } + ] + }, + { + "id": "next_open", + "label": "Next-open fill (decision baseline)", + "config": { + "fill_mode": "next_open" + }, + "windows": [ + { + "window": "train", + "dsr": 0.6243, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 15364.14, + "total_return_pct": 53.6, + "cagr_pct": 22.2, + "max_drawdown_pct": 18.1, + "calmar": 1.23, + "sharpe": 0.94, + "sharpe_se": 0.688, + "psr": 0.9148, + "n_returns": 536, + "return_skew": -0.039, + "return_kurtosis": 4.2924, + "trades": 260, + "win_rate": 31.2, + "avg_trade_pnl": 20.63, + "best_trade_r": 11.53, + "worst_trade_r": -2.99, + "best_trade_pnl": 1265.39, + "worst_trade_pnl": -303.24, + "avg_hold_days": 13.7, + "exit_reasons": { + "stop": 133, + "time": 48, + "trailing_stop": 79 + }, + "skipped_book_full": 140, + "spy_return_pct": 39.0, + "yearly_returns": [ + { + "year": 2022, + "return_pct": 4.5 + }, + { + "year": 2023, + "return_pct": 44.6 + }, + { + "year": 2024, + "return_pct": 1.7 + } + ], + "start_date": "2022-06-24", + "end_date": "2024-08-13", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 260, + "mean_pct": -0.063, + "median_pct": -0.1627, + "p05_pct": -2.5148, + "p95_pct": 1.8498 + }, + "post_stop_events": 133, + "post_stop_reentries": 79, + "post_stop_states_open_at_end": 50 + }, + { + "window": "validation", + "dsr": 0.8327, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 18586.06, + "total_return_pct": 85.9, + "cagr_pct": 36.3, + "max_drawdown_pct": 28.2, + "calmar": 1.29, + "sharpe": 1.44, + "sharpe_se": 0.719, + "psr": 0.9774, + "n_returns": 502, + "return_skew": -0.2169, + "return_kurtosis": 4.6486, + "trades": 243, + "win_rate": 35.0, + "avg_trade_pnl": 35.33, + "best_trade_r": 12.2, + "worst_trade_r": -4.0, + "best_trade_pnl": 1731.6, + "worst_trade_pnl": -196.48, + "avg_hold_days": 13.8, + "exit_reasons": { + "stop": 114, + "time": 48, + "trailing_stop": 81 + }, + "skipped_book_full": 197, + "spy_return_pct": 36.6, + "yearly_returns": [ + { + "year": 2024, + "return_pct": 14.2 + }, + { + "year": 2025, + "return_pct": 42.6 + }, + { + "year": 2026, + "return_pct": 14.1 + } + ], + "start_date": "2024-07-01", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 243, + "mean_pct": -0.519, + "median_pct": -0.1786, + "p05_pct": -4.5194, + "p95_pct": 2.0911 + }, + "post_stop_events": 114, + "post_stop_reentries": 51, + "post_stop_states_open_at_end": 52 + }, + { + "window": "full", + "dsr": 0.9093, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 28701.57, + "total_return_pct": 187.0, + "cagr_pct": 30.0, + "max_drawdown_pct": 28.2, + "calmar": 1.06, + "sharpe": 1.2, + "sharpe_se": 0.504, + "psr": 0.9914, + "n_returns": 1008, + "return_skew": -0.1589, + "return_kurtosis": 4.4517, + "trades": 502, + "win_rate": 32.5, + "avg_trade_pnl": 37.25, + "best_trade_r": 12.2, + "worst_trade_r": -4.0, + "best_trade_pnl": 2674.03, + "worst_trade_pnl": -303.42, + "avg_hold_days": 13.7, + "exit_reasons": { + "stop": 251, + "time": 97, + "trailing_stop": 154 + }, + "skipped_book_full": 356, + "spy_return_pct": 90.9, + "yearly_returns": [ + { + "year": 2022, + "return_pct": 4.5 + }, + { + "year": 2023, + "return_pct": 44.6 + }, + { + "year": 2024, + "return_pct": 15.7 + }, + { + "year": 2025, + "return_pct": 44.0 + }, + { + "year": 2026, + "return_pct": 14.1 + } + ], + "start_date": "2022-06-24", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 502, + "mean_pct": -0.2566, + "median_pct": -0.1661, + "p05_pct": -2.7763, + "p95_pct": 1.8997 + }, + "post_stop_events": 251, + "post_stop_reentries": 157, + "post_stop_states_open_at_end": 81 + } + ] + }, + { + "id": "stale_close", + "label": "Stale-signal close fill (MOC proxy: signal t-1, fill t close)", + "config": { + "fill_mode": "stale_close" + }, + "windows": [ + { + "window": "train", + "dsr": 0.8241, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "stale_close", + "final_equity": 18942.53, + "total_return_pct": 89.4, + "cagr_pct": 34.8, + "max_drawdown_pct": 17.0, + "calmar": 2.05, + "sharpe": 1.36, + "sharpe_se": 0.685, + "psr": 0.9767, + "n_returns": 536, + "return_skew": 0.0918, + "return_kurtosis": 3.1111, + "trades": 246, + "win_rate": 39.0, + "avg_trade_pnl": 36.35, + "best_trade_r": 10.3, + "worst_trade_r": -2.67, + "best_trade_pnl": 1318.25, + "worst_trade_pnl": -328.1, + "avg_hold_days": 16.1, + "exit_reasons": { + "stop": 103, + "time": 54, + "trailing_stop": 89 + }, + "skipped_book_full": 668, + "spy_return_pct": 39.0, + "yearly_returns": [ + { + "year": 2022, + "return_pct": -0.9 + }, + { + "year": 2023, + "return_pct": 72.8 + }, + { + "year": 2024, + "return_pct": 10.6 + } + ], + "start_date": "2022-06-24", + "end_date": "2024-08-13", + "skipped_missing_fill": 0, + "signal_to_fill_drift": { + "n": 246, + "mean_pct": -0.3836, + "median_pct": -0.4703, + "p05_pct": -4.841, + "p95_pct": 3.908 + }, + "post_stop_events": 103, + "post_stop_reentries": 54, + "post_stop_states_open_at_end": 47 + }, + { + "window": "validation", + "dsr": 0.9216, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "stale_close", + "final_equity": 20546.48, + "total_return_pct": 105.5, + "cagr_pct": 43.3, + "max_drawdown_pct": 21.6, + "calmar": 2.0, + "sharpe": 1.74, + "sharpe_se": 0.702, + "psr": 0.9933, + "n_returns": 502, + "return_skew": 0.3013, + "return_kurtosis": 5.6337, + "trades": 234, + "win_rate": 37.2, + "avg_trade_pnl": 45.07, + "best_trade_r": 11.94, + "worst_trade_r": -4.23, + "best_trade_pnl": 2186.87, + "worst_trade_pnl": -732.55, + "avg_hold_days": 15.2, + "exit_reasons": { + "open_at_end": 1, + "stop": 103, + "time": 50, + "trailing_stop": 80 + }, + "skipped_book_full": 223, + "spy_return_pct": 36.6, + "yearly_returns": [ + { + "year": 2024, + "return_pct": 17.6 + }, + { + "year": 2025, + "return_pct": 74.8 + }, + { + "year": 2026, + "return_pct": -0.1 + } + ], + "start_date": "2024-07-01", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "signal_to_fill_drift": { + "n": 234, + "mean_pct": -0.5217, + "median_pct": -0.0138, + "p05_pct": -6.5593, + "p95_pct": 4.5614 + }, + "post_stop_events": 103, + "post_stop_reentries": 45, + "post_stop_states_open_at_end": 53 + }, + { + "window": "full", + "dsr": 0.9816, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "stale_close", + "final_equity": 39381.26, + "total_return_pct": 293.8, + "cagr_pct": 40.6, + "max_drawdown_pct": 21.8, + "calmar": 1.87, + "sharpe": 1.57, + "sharpe_se": 0.5, + "psr": 0.9991, + "n_returns": 1008, + "return_skew": 0.0941, + "return_kurtosis": 4.1297, + "trades": 483, + "win_rate": 37.5, + "avg_trade_pnl": 60.83, + "best_trade_r": 11.94, + "worst_trade_r": -4.23, + "best_trade_pnl": 4191.56, + "worst_trade_pnl": -1404.07, + "avg_hold_days": 15.5, + "exit_reasons": { + "open_at_end": 1, + "stop": 208, + "time": 102, + "trailing_stop": 172 + }, + "skipped_book_full": 894, + "spy_return_pct": 90.9, + "yearly_returns": [ + { + "year": 2022, + "return_pct": -0.9 + }, + { + "year": 2023, + "return_pct": 72.8 + }, + { + "year": 2024, + "return_pct": 31.7 + }, + { + "year": 2025, + "return_pct": 74.7 + }, + { + "year": 2026, + "return_pct": -0.1 + } + ], + "start_date": "2022-06-24", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "signal_to_fill_drift": { + "n": 483, + "mean_pct": -0.4799, + "median_pct": -0.381, + "p05_pct": -5.5621, + "p95_pct": 4.2818 + }, + "post_stop_events": 208, + "post_stop_reentries": 118, + "post_stop_states_open_at_end": 83 + } + ] + }, + { + "id": "next_open_gap2", + "label": "Next-open + skip gap-up > 2%", + "config": { + "fill_mode": "next_open", + "max_entry_gap_pct": 0.02 + }, + "windows": [ + { + "window": "train", + "dsr": 0.4988, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 13619.82, + "total_return_pct": 36.2, + "cagr_pct": 15.5, + "max_drawdown_pct": 21.5, + "calmar": 0.72, + "sharpe": 0.72, + "sharpe_se": 0.686, + "psr": 0.8518, + "n_returns": 536, + "return_skew": 0.0343, + "return_kurtosis": 4.6315, + "trades": 274, + "win_rate": 31.4, + "avg_trade_pnl": 13.21, + "best_trade_r": 11.53, + "worst_trade_r": -2.99, + "best_trade_pnl": 1223.62, + "worst_trade_pnl": -268.81, + "avg_hold_days": 13.4, + "exit_reasons": { + "stop": 138, + "time": 47, + "trailing_stop": 89 + }, + "skipped_book_full": 325, + "spy_return_pct": 39.0, + "yearly_returns": [ + { + "year": 2022, + "return_pct": -4.1 + }, + { + "year": 2023, + "return_pct": 38.7 + }, + { + "year": 2024, + "return_pct": 2.4 + } + ], + "start_date": "2022-06-24", + "end_date": "2024-08-13", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 274, + "mean_pct": -0.4245, + "median_pct": -0.2836, + "p05_pct": -2.6277, + "p95_pct": 1.3953 + }, + "max_entry_gap_pct": 0.02, + "skipped_gap_cap": 146, + "post_stop_events": 138, + "post_stop_reentries": 76, + "post_stop_states_open_at_end": 55 + }, + { + "window": "validation", + "dsr": 0.8234, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 18053.3, + "total_return_pct": 80.5, + "cagr_pct": 34.3, + "max_drawdown_pct": 28.2, + "calmar": 1.22, + "sharpe": 1.41, + "sharpe_se": 0.715, + "psr": 0.9758, + "n_returns": 502, + "return_skew": -0.0944, + "return_kurtosis": 4.7767, + "trades": 251, + "win_rate": 35.1, + "avg_trade_pnl": 32.08, + "best_trade_r": 12.2, + "worst_trade_r": -4.0, + "best_trade_pnl": 1693.37, + "worst_trade_pnl": -213.76, + "avg_hold_days": 13.7, + "exit_reasons": { + "open_at_end": 1, + "stop": 117, + "time": 49, + "trailing_stop": 84 + }, + "skipped_book_full": 200, + "spy_return_pct": 36.6, + "yearly_returns": [ + { + "year": 2024, + "return_pct": 12.7 + }, + { + "year": 2025, + "return_pct": 40.4 + }, + { + "year": 2026, + "return_pct": 14.1 + } + ], + "start_date": "2024-07-01", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 251, + "mean_pct": -0.7233, + "median_pct": -0.2245, + "p05_pct": -4.6154, + "p95_pct": 1.0467 + }, + "max_entry_gap_pct": 0.02, + "skipped_gap_cap": 116, + "post_stop_events": 117, + "post_stop_reentries": 56, + "post_stop_states_open_at_end": 53 + }, + { + "window": "full", + "dsr": 0.8561, + "starting_capital": 10000.0, + "cost_per_side_pct": 0.1, + "fill_mode": "next_open", + "final_equity": 24698.25, + "total_return_pct": 147.0, + "cagr_pct": 25.2, + "max_drawdown_pct": 27.8, + "calmar": 0.91, + "sharpe": 1.06, + "sharpe_se": 0.502, + "psr": 0.983, + "n_returns": 1008, + "return_skew": -0.0453, + "return_kurtosis": 4.7254, + "trades": 523, + "win_rate": 32.7, + "avg_trade_pnl": 28.1, + "best_trade_r": 12.2, + "worst_trade_r": -4.0, + "best_trade_pnl": 2316.66, + "worst_trade_pnl": -292.44, + "avg_hold_days": 13.4, + "exit_reasons": { + "open_at_end": 1, + "stop": 258, + "time": 97, + "trailing_stop": 167 + }, + "skipped_book_full": 525, + "spy_return_pct": 90.9, + "yearly_returns": [ + { + "year": 2022, + "return_pct": -4.1 + }, + { + "year": 2023, + "return_pct": 38.7 + }, + { + "year": 2024, + "return_pct": 14.8 + }, + { + "year": 2025, + "return_pct": 41.7 + }, + { + "year": 2026, + "return_pct": 14.1 + } + ], + "start_date": "2022-06-24", + "end_date": "2026-07-02", + "skipped_missing_fill": 0, + "overnight_slippage": { + "n": 523, + "mean_pct": -0.5565, + "median_pct": -0.2628, + "p05_pct": -3.5771, + "p95_pct": 1.3699 + }, + "max_entry_gap_pct": 0.02, + "skipped_gap_cap": 262, + "post_stop_events": 258, + "post_stop_reentries": 158, + "post_stop_states_open_at_end": 87 + } + ] + } + ], + "recovery": { + "recover": false, + "near_close_control": true, + "beats_next_open": true, + "train_ok": false, + "validation_delta_vs_close": 0.06, + "validation_delta_vs_next_open": 0.3, + "half_se": 0.358, + "reason": "stale_close does not meet recovery criteria \u2014 see flags" + } +} \ No newline at end of file diff --git a/reports/execution_recovery_matrix.md b/reports/execution_recovery_matrix.md new file mode 100644 index 0000000..9e873b2 --- /dev/null +++ b/reports/execution_recovery_matrix.md @@ -0,0 +1,23 @@ +# Execution recovery matrix — 2026-07-18T16:56:10.007302 + +Validation split: **2024-07-01**. N for DSR: **4**. + +| arm | window | Sharpe | SE | CAGR | MaxDD | trades | gap/drift | +|---|---|---:|---:|---:|---:|---:|---| +| close_control | train | 1.75 | 0.675 | 49.8 | 17.9 | 240 | — | +| close_control | validation | 1.68 | 0.716 | 41.6 | 20.9 | 239 | — | +| close_control | full | 1.77 | 0.496 | 48.3 | 21.6 | 472 | — | +| next_open | train | 0.94 | 0.688 | 22.2 | 18.1 | 260 | mean -0.063% n=260 | +| next_open | validation | 1.44 | 0.719 | 36.3 | 28.2 | 243 | mean -0.519% n=243 | +| next_open | full | 1.2 | 0.504 | 30.0 | 28.2 | 502 | mean -0.2566% n=502 | +| stale_close | train | 1.36 | 0.685 | 34.8 | 17.0 | 246 | mean -0.3836% n=246 | +| stale_close | validation | 1.74 | 0.702 | 43.3 | 21.6 | 234 | mean -0.5217% n=234 | +| stale_close | full | 1.57 | 0.5 | 40.6 | 21.8 | 483 | mean -0.4799% n=483 | +| next_open_gap2 | train | 0.72 | 0.686 | 15.5 | 21.5 | 274 | mean -0.4245% n=274; gap_skips=146 | +| next_open_gap2 | validation | 1.41 | 0.715 | 34.3 | 28.2 | 251 | mean -0.7233% n=251; gap_skips=116 | +| next_open_gap2 | full | 1.06 | 0.502 | 25.2 | 27.8 | 523 | mean -0.5565% n=523; gap_skips=262 | + +## Recovery decision (stale_close) + +- **recover: False** — stale_close does not meet recovery criteria — see flags +- flags: {'near_close_control': True, 'beats_next_open': True, 'train_ok': False, 'validation_delta_vs_close': 0.06, 'validation_delta_vs_next_open': 0.3, 'half_se': 0.358}