Warrior_EA/research/d1_drift_null.py

82 lines
3 KiB
Python
Raw Permalink Normal View History

"""Drift null for the SP500 D1 fractal-model gate pass (2026-08-15).
The deployed PAI cleared the family-wise gate: dir-precision 73.1% vs BE ~63% (+10.4pp,
4.04 sigma, p=0.0081, 350 test calls) - long-heavy calls (Buy recall ~75-80%). Question:
what does ALWAYS-LONG (and always-short) score at the same barrier geometry (stop 2.64*ATR,
target 1.66*ATR, horizon 48 D1 bars, spread charged, intrabar ties to the stop) on the
recent slices of D1 history? If always-long ~= the model, the pass is drift; if it sits at
the BE, the selection is real. Also reports median bars-to-resolution (the swap exposure).
"""
import numpy as np
import sys
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
import book
import fills
SL_M, TP_M, HORIZON = 2.64, 1.66, 48
def atr14(h, l, c):
pc = np.roll(c, 1)
pc[0] = c[0]
tr = np.maximum(h - l, np.maximum(np.abs(h - pc), np.abs(l - pc)))
a = np.empty_like(tr)
a[:14] = tr[:14].mean()
for i in range(14, len(tr)):
a[i] = (a[i - 1] * 13 + tr[i]) / 14.0
return a
def main():
bk = fills.Book("SP500")
f = book.frame("SP500", "D1", bk)
a = atr14(f.h, f.l, f.c)
sp = float(np.nanmean(f.spread))
n = f.n
res = {}
for name, lo_frac, hi_frac in (("last 15%", 0.85, 1.0), ("last 30%", 0.70, 1.0),
("full", 0.05, 1.0)):
i0, i1 = int(n * lo_frac), int(n * hi_frac) - HORIZON - 1
wl = ws = nl = 0
holds = []
for i in range(max(i0, 20), i1):
entry = f.c[i]
risk, rew = SL_M * a[i], TP_M * a[i]
ltp, lsl = entry + sp + rew, entry + sp - risk
stp, ssl = entry - rew - sp, entry + risk - sp
lw = ll = sw = ss = False
lat = sat = -1
for t in range(i + 1, min(i + 1 + HORIZON, n)):
if not ll and not lw:
if f.l[t] <= lsl:
ll = True
elif f.h[t] >= ltp:
lw = True
lat = t - i
if not ss and not sw:
if f.h[t] >= ssl:
ss = True
elif f.l[t] <= stp:
sw = True
sat = t - i
if (ll or lw) and (ss or sw):
break
nl += 1
if lw:
wl += 1
holds.append(lat)
if sw:
ws += 1
res[name] = (100.0 * wl / max(nl, 1), 100.0 * ws / max(nl, 1), nl,
np.median(holds) if holds else 0)
be = 100.0 * SL_M / (SL_M + TP_M)
print(f"SP500 D1, geometry {SL_M}/{TP_M}, horizon {HORIZON} bars | zero-cost BE {be:.1f}%"
f" | spread {sp:.2f} pts")
for name, (l, s, cnt, medhold) in res.items():
print(f" {name:<9}: always-LONG win {l:.1f}% | always-SHORT {s:.1f}% | n={cnt} | "
f"median bars to long target {medhold:.0f}")
if __name__ == "__main__":
main()