fix(surfer): cwd-independent PoC + fixed-phase weekly rebalance (cron-ready)

- Rebalance keyed on FIXED calendar phase (epoch-day%7==0 -> Thursdays) instead of
  drifting days[0]%K, so backtest and live agree on rebalance timing.
- STATE path absolute (relative to script) -> paper mode runs from any cwd (cron-safe).
- Backtest unchanged (net +0.40@$20M, CPCV-med +0.47).
Installed system crontab (daily 12:07): marks paper PnL daily, rebalances Thursdays,
logs to data/surfer/paper_runs.log. Forward-test seeded inception 2026-06-06.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-06-06 16:55:42 +02:00
parent d6eb5b2ada
commit ec308346b2

View File

@@ -31,7 +31,8 @@ import torch # noqa: E402
DEV = "cuda" if torch.cuda.is_available() else "cpu"
DAY_MS = 86_400_000
STATE = "data/surfer/poc_state.json"
_REPO = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # cwd-independent (cron-safe)
STATE = os.path.join(_REPO, "data/surfer/poc_state.json")
CFG = dict(
lookback=20, # XS momentum horizon (days)
@@ -81,11 +82,11 @@ def compute_weights(close, qvol, days, cfg):
sig = trailing(lc, cfg["lookback"]).copy(); sig[~univ] = np.nan
wt = xs_weights(sig) # daily target (market-neutral, unit gross)
wt = ewma_rows(wt, cfg["smooth_span"]) # smooth
held = wt.copy() # weekly rebalance on calendar day % K
K = cfg["rebal_k"]
held = wt.copy() # weekly rebalance on FIXED calendar phase (day%K==0)
K = cfg["rebal_k"] # epoch day0=Thu → rebalances every Thursday, live-consistent
last = 0
for t in range(T):
if days[t] % K == days[0] % K:
if days[t] % K == 0:
last = t
held[t] = wt[last]
return held, univ
@@ -234,7 +235,7 @@ def paper(cfg):
st["equity"] *= (1.0 + ret)
st["log"].append({"day": today, "mark_ret": round(ret, 6), "equity": round(st["equity"], 5)})
# 2) REBALANCE on the weekly boundary
rebal = (st["last_mark_day"] is None) or (today % cfg["rebal_k"] == days[0] % cfg["rebal_k"])
rebal = (st["last_mark_day"] is None) or (today % cfg["rebal_k"] == 0) # fixed weekly phase (Thursdays)
trades = []
if rebal:
cur = st["positions"]