"""regime_analyzer.py — Claude Desktop Option B test. Hypothesis (Claude Desktop, 2026-06-08): HIGH TENSION = asymmetry > arm A q90 OR coherence < arm A q10 LOW TENSION = asymmetry < arm A q10 AND coherence > arm A q90 NEUTRAL = otherwise Primary test: vol_ratio for (HIGH ∩ top-decile trade_count) must exceed vol_ratio for top-decile trade_count alone (best 2.42x). Secondary test: For HIGH TENSION minutes, sign of (taker_buy_z - taker_sell_z) → sign(fwd_60). Also try (stress_xx - stress_yy) as the lattice-derived direction signal. Usage: edit RUN below, then `wsl python3 /mnt/d/Resonance_Engine/regime_analyzer.py` """ import pandas as pd, numpy as np, glob, sys RUN = sys.argv[1] if len(sys.argv) > 1 else "/mnt/d/Resonance_Engine/traj/regime_20260608T131732" print(f"=== regime_analyzer on {RUN} ===") A = pd.read_parquet(f"{RUN}/arm_A_no_inject.parquet") T = pd.read_parquet(f"{RUN}/arm_T_3ch.parquet") print(f"arm A: {len(A):,} arm T: {len(T):,}") # Load BTC prices (joined to compute fwd_60 returns) files = sorted(glob.glob("/mnt/d/PaperTrader/research/hl_data/minutes/202604*/*.parquet")) px_parts = [] for f in files: d = pd.read_parquet(f, columns=["minute", "coin", "mid_price"]) px_parts.append(d[d.coin == "BTC"][["minute", "mid_price"]]) px = pd.concat(px_parts, ignore_index=True).drop_duplicates("minute").sort_values("minute").reset_index(drop=True) px["fwd_60_bps"] = (np.log(px["mid_price"].shift(-60)) - np.log(px["mid_price"])) * 10000.0 print(f"prices: {len(px):,} minutes") # Join price returns into arm T (we measure on T's telemetry + raw fields) df = T.merge(px[["minute", "fwd_60_bps"]], on="minute", how="inner").sort_values("minute").reset_index(drop=True) df = df.dropna(subset=["fwd_60_bps", "asymmetry", "coherence", "trade_count"]).reset_index(drop=True) print(f"joined arm T rows with fwd_60 + telemetry: {len(df):,}") # ─── thresholds from arm A free-running baseline ─── asym_p10 = A["asymmetry"].quantile(0.10) asym_p90 = A["asymmetry"].quantile(0.90) coh_p10 = A["coherence"].quantile(0.10) coh_p90 = A["coherence"].quantile(0.90) print() print("=== arm A baseline thresholds ===") print(f" asymmetry p10={asym_p10:.4f} p90={asym_p90:.4f} (mean={A.asymmetry.mean():.4f})") print(f" coherence p10={coh_p10:.4f} p90={coh_p90:.4f} (mean={A.coherence.mean():.4f})") # Label regimes on arm T using arm A thresholds high = (df["asymmetry"] > asym_p90) | (df["coherence"] < coh_p10) low = (df["asymmetry"] < asym_p10) & (df["coherence"] > coh_p90) neutral = ~(high | low) df["regime"] = "NEUTRAL" df.loc[high, "regime"] = "HIGH" df.loc[low, "regime"] = "LOW" print() print("=== regime label distribution (arm T) ===") print(df["regime"].value_counts()) print(f" HIGH frac: {high.mean()*100:.2f}%") print(f" LOW frac: {low.mean()*100:.2f}%") print(f" NEUTRAL frac: {neutral.mean()*100:.2f}%") # ─── trade_count top decile (the validated raw signal) ─── tc_p90 = df["trade_count"].quantile(0.90) top_tc = df["trade_count"] >= tc_p90 print() print(f"=== trade_count top decile (>= {tc_p90:.0f}) ===") print(f" fraction: {top_tc.mean()*100:.2f}% ({top_tc.sum():,} rows)") # ─── PRIMARY TEST: vol ratios ─── base_abs = df["fwd_60_bps"].abs().mean() print() print("=" * 90) print("PRIMARY TEST — |fwd_60_bps| vol ratios vs full sample") print("=" * 90) print(f" baseline |fwd_60| mean (all minutes): {base_abs:.3f} bps") print() def vol_report(mask, name): n = int(mask.sum()) if n < 50: print(f" {name:<60} n={n:>6,} too small") return sub = df.loc[mask, "fwd_60_bps"].abs() ratio = sub.mean() / base_abs print(f" {name:<60} n={n:>6,} mean|y|={sub.mean():>6.2f}bps ratio={ratio:.3f}x") vol_report(top_tc, "top decile trade_count (validated baseline)") vol_report(high, "lattice HIGH TENSION (all)") vol_report(low, "lattice LOW TENSION (all)") vol_report(high & top_tc, "HIGH ∩ top-decile trade_count <-- THE TEST") vol_report(low & top_tc, "LOW ∩ top-decile trade_count") vol_report(neutral & top_tc, "NEUTRAL ∩ top-decile trade_count") print() top_ratio = (df.loc[top_tc, "fwd_60_bps"].abs().mean() / base_abs) hi_top_ratio = (df.loc[high & top_tc, "fwd_60_bps"].abs().mean() / base_abs) print(f" top-decile trade_count ratio: {top_ratio:.3f}x") print(f" HIGH ∩ top-decile trade_count: {hi_top_ratio:.3f}x") diff = hi_top_ratio - top_ratio print(f" lattice lift over raw top-decile: {diff:+.3f}x ({diff/top_ratio*100:+.1f}%)") print(f" success criterion (Claude): > 2.42x -> {'PASS' if hi_top_ratio > 2.42 else 'FAIL'}") # ─── SECONDARY TEST: direction for HIGH TENSION minutes ─── print() print("=" * 90) print("SECONDARY TEST — direction for HIGH TENSION minutes") print("=" * 90) sub = df.loc[high].copy() sub = sub.dropna(subset=["taker_buy_usd_z", "taker_sell_usd_z", "stress_xx", "stress_yy"]) print(f" n HIGH minutes (after dropna z+stress): {len(sub):,}") if len(sub) > 100: # direct injected-signal direction buy_minus_sell = sub["taker_buy_usd_z"] - sub["taker_sell_usd_z"] stress_xx_minus_yy = sub["stress_xx"] - sub["stress_yy"] print() print(f" Spearman (buy_z - sell_z, fwd_60): " f"{buy_minus_sell.corr(sub.fwd_60_bps, method='spearman'):+.4f}") print(f" Spearman (stress_xx - stress_yy, fwd_60): " f"{stress_xx_minus_yy.corr(sub.fwd_60_bps, method='spearman'):+.4f}") # directional accuracy of each sign-based predictor def dacc(predictor, y): valid = predictor.notna() & y.notna() & (predictor != 0) & (y != 0) if valid.sum() == 0: return None, 0 return (np.sign(predictor[valid]) == np.sign(y[valid])).mean() * 100, int(valid.sum()) d, n = dacc(buy_minus_sell, sub.fwd_60_bps) print(f" dacc sign(buy_z - sell_z) vs sign(fwd_60): {d:.2f}% (n={n:,})") d, n = dacc(stress_xx_minus_yy, sub.fwd_60_bps) print(f" dacc sign(stress_xx - stress_yy) vs sign(fwd_60): {d:.2f}% (n={n:,})") # mean signed return when each predictor is positive vs negative pos = buy_minus_sell > 0 neg = buy_minus_sell < 0 print() print(f" mean fwd_60 when buy_z > sell_z: {sub.loc[pos, 'fwd_60_bps'].mean():+.3f} bps (n={pos.sum():,})") print(f" mean fwd_60 when buy_z < sell_z: {sub.loc[neg, 'fwd_60_bps'].mean():+.3f} bps (n={neg.sum():,})") pos_s = stress_xx_minus_yy > 0 neg_s = stress_xx_minus_yy < 0 print(f" mean fwd_60 when xx > yy: {sub.loc[pos_s, 'fwd_60_bps'].mean():+.3f} bps (n={pos_s.sum():,})") print(f" mean fwd_60 when xx < yy: {sub.loc[neg_s, 'fwd_60_bps'].mean():+.3f} bps (n={neg_s.sum():,})")