#!/usr/bin/env python3
"""A2.R6b (pre-registered 7 Oct 2026): is the funding-spike edge more than price momentum?
Pooled panel, chain natives vs BTC. y = rel return t+1..t+15 (1 day delay, 14d). Features (trailing only):
fz = z(funding 7d mean, 90d), mz = z(past 14d rel return, 90d). OLS y ~ fz + mz per era, plus
fires split: funding fire with momentum fire (mz>=2) vs funding fire alone (mz<1). Pass: fz coef > 0 in both eras
AND 'funding alone' fires beat all days by > 1% in both eras."""
import pandas as pd, numpy as np, os
D = os.path.dirname(os.path.abspath(__file__))
df = pd.read_csv(f"{D}/data/flows_daily.csv.gz"); df["date"] = pd.to_datetime(df["date"])
def wide(m): return df[df.metric == m].pivot_table(index="date", columns="entity", values="value", aggfunc="sum").sort_index().asfreq("D")
px = wide("close_usd"); fu = wide("funding_daily")
rel = np.log(px.div(px["BTC"], axis=0))
z = lambda s: (s - s.rolling(90, min_periods=60).mean()) / s.rolling(90, min_periods=60).std()
rows = []
for c in fu.columns:
    if c == "BTC" or c not in rel.columns: continue
    r = rel[c]; f7 = fu[c].rolling(7, min_periods=5).mean()
    t = pd.DataFrame({"y": r.shift(-15) - r.shift(-1), "fz": z(f7), "mz": z(r - r.shift(14)), "chain": c})
    rows.append(t.dropna())
P = pd.concat(rows); P["era"] = np.where(P.index < "2023-01-01", "2020-22", "2023-26")
out = []
for era, g in P.groupby("era"):
    X = np.column_stack([np.ones(len(g)), g.fz, g.mz]); b = np.linalg.lstsq(X, g.y, rcond=None)[0]
    res = g.y - X @ b; se = np.sqrt(np.diag(np.linalg.inv(X.T @ X)) * res.var()) * np.sqrt(14)  # overlap inflation ~sqrt(14)
    fa = g[(g.fz >= 2) & (g.mz < 1)].y; fm = g[(g.fz >= 2) & (g.mz >= 2)].y; mo = g[(g.mz >= 2) & (g.fz < 1)].y
    out.append(dict(era=era, n=len(g), b_fz=round(b[1], 4), t_fz=round(b[1] / se[1], 2), b_mz=round(b[2], 4), t_mz=round(b[2] / se[2], 2),
        all_days=round(g.y.mean(), 4), fund_alone=round(fa.mean(), 4), n_fa=len(fa), fund_and_mom=round(fm.mean(), 4), n_fm=len(fm),
        mom_alone=round(mo.mean(), 4), n_mo=len(mo)))
o = pd.DataFrame(out); o.to_csv(f"{D}/out/r6_control.csv", index=False)
pd.set_option("display.width", 250); print(o.to_string(index=False))
