""" Day-1 trade-level comparison: process_day vs actor-style step_bar loop. Prints every trade entry/exit with bar_idx, gidx, bars_held, exit_type, pnl. Focus: identify which trade(s) differ between the two paths on 2025-12-31. """ import sys, math, pathlib import numpy as np import pandas as pd sys.path.insert(0, '/mnt/dolphinng5_predict') sys.path.insert(0, '/mnt/dolphinng5_predict/nautilus_dolphin') print("Importing...", flush=True) from nautilus_dolphin.nautilus.proxy_boost_engine import create_boost_engine print("Import done.", flush=True) PARQUET_DIR = pathlib.Path('/mnt/dolphinng5_predict/vbt_cache') VOL_P60_INWINDOW = 0.00009868 ENG_KWARGS = dict( max_hold_bars=120, min_irp_alignment=0.45, max_leverage=8.0, vel_div_threshold=-0.02, vel_div_extreme=-0.05, min_leverage=0.5, leverage_convexity=3.0, fraction=0.20, fixed_tp_pct=0.0095, stop_pct=1.0, use_direction_confirm=True, dc_lookback_bars=7, dc_min_magnitude_bps=0.75, dc_skip_contradicts=True, dc_leverage_boost=1.0, dc_leverage_reduce=0.5, use_asset_selection=True, use_sp_fees=True, use_sp_slippage=True, sp_maker_entry_rate=0.62, sp_maker_exit_rate=0.50, use_ob_edge=True, ob_edge_bps=5.0, ob_confirm_rate=0.40, lookback=100, use_alpha_layers=True, use_dynamic_leverage=True, seed=42, ) def make_engine(initial_capital=25000.0): return create_boost_engine(mode='d_liq', initial_capital=initial_capital, **ENG_KWARGS) def load_day(date_str): p = PARQUET_DIR / f"{date_str}.parquet" return pd.read_parquet(p) def compute_vol_ok(df): """Actor method: 49-ret window, static threshold, stored at j.""" btc_f = df['BTCUSDT'].values.astype('float64') n = len(btc_f) vol_ok = np.zeros(n, dtype=bool) for j in range(50, n): seg = btc_f[max(0, j-50):j] diffs = np.diff(seg) denom = seg[:-1] if np.any(denom == 0): continue v = float(np.std(diffs / denom)) if math.isfinite(v) and v > 0: vol_ok[j] = v > VOL_P60_INWINDOW return vol_ok def build_prices(row, assets): prices = {} for sym in assets: try: v = float(row[sym]) if math.isfinite(v): prices[sym] = v except: pass return prices ASSET_COLS = [c for c in ['BTCUSDT','ETHUSDT','BNBUSDT','LTCUSDT','XRPUSDT','ADAUSDT', 'LINKUSDT','ATOMUSDT','DOGEUSDT','XLMUSDT','TRXUSDT','ALGOUSDT'] ] def run_pd(df, initial_capital=25000.0): """Process_day path: NaN vel_div increments _global_bar_idx.""" eng = make_engine(initial_capital) eng.begin_day('2025-12-31') btc_f = df['BTCUSDT'].values.astype('float64') vol_ok = compute_vol_ok(df) trades = [] for i in range(len(df)): row = df.iloc[i] vd_raw = row['vel_div'] vd = None if (vd_raw is None or not math.isfinite(float(vd_raw))) else float(vd_raw) if vd is None: eng._global_bar_idx += 1 continue v750 = float(row.get('v750_lambda_max_velocity', 0.0)) inst50 = float(row.get('instability_50', 0.0)) v50 = float(row.get('v50_lambda_max_velocity', 0.0)) prices = build_prices(row, [c for c in df.columns if c.endswith('USDT')]) prev_cap = eng.capital prev_pos = eng.position gidx_before = eng._global_bar_idx if hasattr(eng, 'pre_bar_proxy_update'): eng.pre_bar_proxy_update(inst50, v750) result = eng.step_bar( bar_idx=i, vel_div=vd, prices=prices, v50_vel=v50, v750_vel=v750, vol_regime_ok=bool(vol_ok[i]), ) new_pos = eng.position new_cap = eng.capital if prev_pos is None and new_pos is not None: trades.append({'ev':'ENTRY','row':i,'gidx':gidx_before,'cap':new_cap,'price':btc_f[i]}) elif prev_pos is not None and new_pos is None: trades.append({'ev':'EXIT','row':i,'gidx':gidx_before,'cap':new_cap,'pnl':new_cap-prev_cap}) eng.end_day() return eng, trades def run_fixed(df, initial_capital=25000.0): """Fixed actor path: NaN vel_div DOES increment _global_bar_idx (matches process_day).""" eng = make_engine(initial_capital) eng.begin_day('2025-12-31') btc_f = df['BTCUSDT'].values.astype('float64') vol_ok = compute_vol_ok(df) trades = [] for i in range(len(df)): row = df.iloc[i] vd_raw = row['vel_div'] vd = None if (vd_raw is None or not math.isfinite(float(vd_raw))) else float(vd_raw) if vd is None: # FIXED: increment _global_bar_idx to match process_day eng._global_bar_idx += 1 continue v750 = float(row.get('v750_lambda_max_velocity', 0.0)) inst50 = float(row.get('instability_50', 0.0)) v50 = float(row.get('v50_lambda_max_velocity', 0.0)) prices = build_prices(row, [c for c in df.columns if c.endswith('USDT')]) prev_cap = eng.capital prev_pos = eng.position gidx_before = eng._global_bar_idx if hasattr(eng, 'pre_bar_proxy_update'): eng.pre_bar_proxy_update(inst50, v750) result = eng.step_bar( bar_idx=i, vel_div=vd, prices=prices, v50_vel=v50, v750_vel=v750, vol_regime_ok=bool(vol_ok[i]), ) new_pos = eng.position new_cap = eng.capital if prev_pos is None and new_pos is not None: trades.append({'ev':'ENTRY','row':i,'gidx':gidx_before,'cap':new_cap,'price':btc_f[i]}) elif prev_pos is not None and new_pos is None: trades.append({'ev':'EXIT','row':i,'gidx':gidx_before,'cap':new_cap,'pnl':new_cap-prev_cap}) eng.end_day() return eng, trades def run_act(df, initial_capital=25000.0): """Actor path: NaN vel_div does NOT increment _global_bar_idx.""" eng = make_engine(initial_capital) eng.begin_day('2025-12-31') btc_f = df['BTCUSDT'].values.astype('float64') vol_ok = compute_vol_ok(df) trades = [] for i in range(len(df)): row = df.iloc[i] vd_raw = row['vel_div'] vd = None if (vd_raw is None or not math.isfinite(float(vd_raw))) else float(vd_raw) if vd is None: # ACT path: skip entirely — _global_bar_idx NOT incremented continue v750 = float(row.get('v750_lambda_max_velocity', 0.0)) inst50 = float(row.get('instability_50', 0.0)) v50 = float(row.get('v50_lambda_max_velocity', 0.0)) prices = build_prices(row, [c for c in df.columns if c.endswith('USDT')]) prev_cap = eng.capital prev_pos = eng.position gidx_before = eng._global_bar_idx if hasattr(eng, 'pre_bar_proxy_update'): eng.pre_bar_proxy_update(inst50, v750) result = eng.step_bar( bar_idx=i, vel_div=vd, prices=prices, v50_vel=v50, v750_vel=v750, vol_regime_ok=bool(vol_ok[i]), ) new_pos = eng.position new_cap = eng.capital if prev_pos is None and new_pos is not None: trades.append({'ev':'ENTRY','row':i,'gidx':gidx_before,'cap':new_cap,'price':btc_f[i]}) elif prev_pos is not None and new_pos is None: trades.append({'ev':'EXIT','row':i,'gidx':gidx_before,'cap':new_cap,'pnl':new_cap-prev_cap}) eng.end_day() return eng, trades def main(): print("\n=== DAY 1 TRADE COMPARISON: 2025-12-31 ===", flush=True) df = load_day('2025-12-31') nan_count = df['vel_div'].isna().sum() print(f"Rows: {len(df)}, NaN vel_div: {nan_count}", flush=True) # Show where NaN rows cluster nan_rows = df.index[df['vel_div'].isna()].tolist() print(f"NaN rows (first 10): {nan_rows[:10]}", flush=True) pd_eng, pd_trades = run_pd(df) act_eng, act_trades = run_act(df) fix_eng, fix_trades = run_fixed(df) pd_exits = [t for t in pd_trades if t['ev']=='EXIT'] act_exits = [t for t in act_trades if t['ev']=='EXIT'] fix_exits = [t for t in fix_trades if t['ev']=='EXIT'] print(f"\nPD: T={len(pd_exits)}, cap=${pd_eng.capital:.2f}, pnl=${pd_eng.capital-25000:.2f}", flush=True) print(f"ACT: T={len(act_exits)}, cap=${act_eng.capital:.2f}, pnl=${act_eng.capital-25000:.2f}", flush=True) print(f"FIX: T={len(fix_exits)}, cap=${fix_eng.capital:.2f}, pnl=${fix_eng.capital-25000:.2f}", flush=True) print("\n--- PD TRADES (entry+exit pairs) ---", flush=True) entries = {t['row']: t for t in pd_trades if t['ev']=='ENTRY'} for t in pd_trades: if t['ev'] == 'ENTRY': print(f" E row={t['row']:4d} gidx={t['gidx']:4d} btc={t['price']:.2f}", flush=True) else: # Find matching entry e = next((x for x in reversed(pd_trades[:pd_trades.index(t)]) if x['ev']=='ENTRY'), None) held = t['gidx'] - (e['gidx'] if e else 0) print(f" X row={t['row']:4d} gidx={t['gidx']:4d} held={held:3d} pnl={t['pnl']:+8.2f} cap=${t['cap']:.2f}", flush=True) print("\n--- ACT TRADES (entry+exit pairs) ---", flush=True) for t in act_trades: if t['ev'] == 'ENTRY': print(f" E row={t['row']:4d} gidx={t['gidx']:4d} btc={t['price']:.2f}", flush=True) else: e = next((x for x in reversed(act_trades[:act_trades.index(t)]) if x['ev']=='ENTRY'), None) held = t['gidx'] - (e['gidx'] if e else 0) print(f" X row={t['row']:4d} gidx={t['gidx']:4d} held={held:3d} pnl={t['pnl']:+8.2f} cap=${t['cap']:.2f}", flush=True) # Diff: find first divergence print("\n--- DIVERGENCE ANALYSIS ---", flush=True) for i, (p, a) in enumerate(zip(pd_trades, act_trades)): if p['ev'] != a['ev'] or p['row'] != a['row'] or p['gidx'] != a['gidx']: print(f" First divergence at trade event #{i}:", flush=True) print(f" PD: {p}", flush=True) print(f" ACT: {a}", flush=True) break else: if len(pd_trades) != len(act_trades): print(f" Paths agree up to min length, but PD has {len(pd_trades)} events vs ACT {len(act_trades)}", flush=True) else: print(" Paths are identical in trade events!", flush=True) if __name__ == '__main__': main()