Spaces:
Running
Running
File size: 3,981 Bytes
8e50444 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | import sys, os
import numpy as np, pandas as pd
import warnings; warnings.filterwarnings('ignore')
sys.path.insert(0, os.path.dirname(__file__))
from backtesting.engines.v30_causal_engine import get_data, evaluate_slice, V30_PARAMS
from backtesting.audits.v53_causal_audit import run_v53_causal
def test_4_1_param_surface(dc, spy, vf, daily_ret):
print("--- Test 4.1: Parameter Sensitivity Surface ---")
rebal_grid = [21, 30, 40, 60]
pick_grid = [5, 10, 15, 20]
print("Sweeping parameter grid...", end="", flush=True)
results = {}
for r in rebal_grid:
for p in pick_grid:
params = V30_PARAMS.copy()
params['rebal_days'] = r
params['top_n'] = p
c = run_v53_causal(dc, spy, vf, daily_ret, **params)
m = evaluate_slice(c, "2008-01-01", "2025-12-31")
results[(r, p)] = m['sharpe']
print(".", end="", flush=True)
print("\n")
sharpes = list(results.values())
min_s, max_s = min(sharpes), max(sharpes)
for r in rebal_grid:
row_str = f"Rebal {r:2d}d | "
for p in pick_grid:
row_str += f"Pick{p:2d}: {results[(r, p)]:.2f} "
print(row_str)
print(f"\nSurface Range: {min_s:.2f} to {max_s:.2f}")
if min_s >= 0.70:
print("Result: PASS (Smooth, robust surface)")
elif min_s < 0.60:
print("Result: FAIL (Cliff edge detected)")
else:
print("Result: WEAK PASS (Acceptable but contains weak spots)")
return results
def test_4_2_single_param_overfit(dc, spy, vf, daily_ret, results):
print("\n--- Test 4.2: Single Parameter Overfit Detection ---")
# Find the parameter set that gave the highest full-period Sharpe
best_params = max(results, key=results.get)
best_r, best_p = best_params
best_s = results[best_params]
base_s = results.get((60, 15), 0)
print(f"Base Params (60d, 15 picks) Sharpe: {base_s:.4f}")
print(f"Best Params ({best_r}d, {best_p} picks) Sharpe: {best_s:.4f}")
diff = best_s - base_s
if diff > 0.10:
print("\nSignificant improvement detected. Running Train/Test Split on best params...")
params = V30_PARAMS.copy()
params['rebal_days'] = best_r
params['top_n'] = best_p
c = run_v53_causal(dc, spy, vf, daily_ret, **params)
m_train = evaluate_slice(c, "2008-01-01", "2018-12-31")
m_test = evaluate_slice(c, "2019-01-01", "2025-12-31")
print(f"Train Sharpe (2008-2018): {m_train['sharpe']:.4f}")
print(f"Test Sharpe (2019-2025): {m_test['sharpe']:.4f}")
# Original baseline test sharpe
c_orig = run_v53_causal(dc, spy, vf, daily_ret, **V30_PARAMS)
m_orig_test = evaluate_slice(c_orig, "2019-01-01", "2025-12-31")
orig_test_s = m_orig_test['sharpe']
test_diff = m_test['sharpe'] - orig_test_s
print(f"Out-of-sample edge over base params: {test_diff:+.4f}")
if test_diff > 0.10:
print("Result: PASS (Improvement is genuine out-of-sample)")
elif test_diff < 0:
print("Result: FAIL (Pure overfit, optimization disappeared out-of-sample)")
else:
print("Result: WEAK PASS (Marginal out-of-sample improvement)")
else:
print("\nNo single parameter caused dramatic (>0.10) overfit behavior.")
print("Result: PASS (Base parameters are near optimal or stable)")
if __name__ == "__main__":
print("========================================")
print(" V53 FRAMEWORK VALIDATION - PHASE 4")
print("========================================")
dc, spy, vf, daily_ret = get_data()
res = test_4_1_param_surface(dc, spy, vf, daily_ret)
test_4_2_single_param_overfit(dc, spy, vf, daily_ret, res)
|