97 lines
4.3 KiB
Python
97 lines
4.3 KiB
Python
|
|
"""5-day diagnostic: compare TEST A vs TEST B daily capital to find where they diverge."""
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
import numpy as np
|
||
|
|
import pandas as pd
|
||
|
|
import time, gc, math
|
||
|
|
|
||
|
|
ROOT = Path(r"C:\Users\Lenovo\Documents\- DOLPHIN NG HD HCM TSF Predict")
|
||
|
|
sys.path.insert(0, str(ROOT / 'nautilus_dolphin'))
|
||
|
|
sys.path.insert(0, str(ROOT / 'nautilus_dolphin' / 'dvae'))
|
||
|
|
|
||
|
|
import exp_shared
|
||
|
|
from nautilus_dolphin.nautilus.proxy_boost_engine import create_d_liq_engine
|
||
|
|
from nautilus_dolphin.nautilus.adaptive_circuit_breaker import AdaptiveCircuitBreaker
|
||
|
|
from exp_shared import load_data, ENGINE_KWARGS, META_COLS
|
||
|
|
|
||
|
|
exp_shared.ensure_jit()
|
||
|
|
|
||
|
|
# ── TEST A: exp_shared.run_backtest style (set hazard + per-day OB + rolling vol) ────────────
|
||
|
|
print("\n=== TEST A: 5 days (hazard call + per-day OB clear + rolling vol_p60) ===")
|
||
|
|
d = load_data()
|
||
|
|
kw = ENGINE_KWARGS.copy()
|
||
|
|
kw.update({'sp_maker_entry_rate': 1.0, 'sp_maker_exit_rate': 1.0, 'use_sp_slippage': False})
|
||
|
|
|
||
|
|
acb = AdaptiveCircuitBreaker()
|
||
|
|
acb.preload_w750(d['date_strings'])
|
||
|
|
eng = create_d_liq_engine(**kw)
|
||
|
|
eng.set_ob_engine(d['ob_eng'])
|
||
|
|
eng.set_acb(acb)
|
||
|
|
eng.set_esoteric_hazard_multiplier(0.0)
|
||
|
|
print(f" After hazard call: base_max={eng.base_max_leverage} sizer={eng.bet_sizer.max_leverage} abs={eng.abs_max_leverage}")
|
||
|
|
|
||
|
|
all_vols = []
|
||
|
|
for i, pf in enumerate(d['parquet_files'][:5]):
|
||
|
|
ds = pf.stem
|
||
|
|
df = pd.read_parquet(pf)
|
||
|
|
for c in df.columns:
|
||
|
|
if df[c].dtype == 'float64':
|
||
|
|
df[c] = df[c].astype('float32')
|
||
|
|
acols = [c for c in df.columns if c not in META_COLS]
|
||
|
|
if eng.ob_engine is not None:
|
||
|
|
eng.ob_engine.preload_date(ds, d['OB_ASSETS'])
|
||
|
|
bp = df['BTCUSDT'].values if 'BTCUSDT' in df.columns else None
|
||
|
|
dvol = np.zeros(len(df), dtype=np.float32)
|
||
|
|
if bp is not None:
|
||
|
|
rets = np.diff(bp.astype('float64')) / (bp[:-1].astype('float64') + 1e-9)
|
||
|
|
for j in range(50, len(rets)):
|
||
|
|
v = np.std(rets[j-50:j])
|
||
|
|
dvol[j+1] = v
|
||
|
|
if v > 0: all_vols.append(v)
|
||
|
|
vp60 = np.percentile(all_vols, 60) if len(all_vols) > 1000 else d['vol_p60']
|
||
|
|
n_vol_ok = np.sum(np.where(dvol > 0, dvol > vp60, False))
|
||
|
|
vol_ok = np.where(dvol > 0, dvol > vp60, False)
|
||
|
|
n_before = len(eng.trade_history)
|
||
|
|
eng.process_day(ds, df, acols, vol_regime_ok=vol_ok)
|
||
|
|
n_after = len(eng.trade_history)
|
||
|
|
print(f" Day {i+1} {ds}: cap=${eng.capital:,.0f} trades_today={n_after-n_before} total={n_after} vol_ok_bars={n_vol_ok}/{len(df)} vp60={vp60:.6f} base_max={eng.base_max_leverage:.1f}")
|
||
|
|
if eng.ob_engine is not None:
|
||
|
|
eng.ob_engine._preloaded_placement.clear()
|
||
|
|
eng.ob_engine._preloaded_signal.clear()
|
||
|
|
eng.ob_engine._preloaded_market.clear()
|
||
|
|
eng.ob_engine._ts_to_idx.clear()
|
||
|
|
del df; gc.collect()
|
||
|
|
|
||
|
|
# ── TEST B: replicate style (no hazard call, static vol, float64) ─────────────────────────────
|
||
|
|
print("\n=== TEST B: 5 days (no hazard call, static vol_p60, float64) ===")
|
||
|
|
d2 = load_data()
|
||
|
|
kw2 = ENGINE_KWARGS.copy()
|
||
|
|
kw2.update({'sp_maker_entry_rate': 1.0, 'sp_maker_exit_rate': 1.0, 'use_sp_slippage': False})
|
||
|
|
acb2 = AdaptiveCircuitBreaker()
|
||
|
|
acb2.preload_w750(d2['date_strings'])
|
||
|
|
eng2 = create_d_liq_engine(**kw2)
|
||
|
|
eng2.set_ob_engine(d2['ob_eng'])
|
||
|
|
eng2.set_acb(acb2)
|
||
|
|
print(f" No hazard call: base_max={eng2.base_max_leverage} sizer={eng2.bet_sizer.max_leverage} abs={eng2.abs_max_leverage}")
|
||
|
|
|
||
|
|
for i, pf in enumerate(d2['parquet_files'][:5]):
|
||
|
|
ds = pf.stem
|
||
|
|
df = pd.read_parquet(pf)
|
||
|
|
acols = [c for c in df.columns if c not in META_COLS]
|
||
|
|
bp = df['BTCUSDT'].values if 'BTCUSDT' in df.columns else None
|
||
|
|
dvol = np.full(len(df), np.nan)
|
||
|
|
if bp is not None:
|
||
|
|
diffs = np.zeros(len(bp), dtype=np.float64)
|
||
|
|
diffs[1:] = np.diff(bp) / bp[:-1]
|
||
|
|
for j in range(50, len(bp)):
|
||
|
|
dvol[j] = np.std(diffs[j-50:j])
|
||
|
|
n_vol_ok = np.sum(np.where(np.isfinite(dvol), dvol > d2['vol_p60'], False))
|
||
|
|
vol_ok = np.where(np.isfinite(dvol), dvol > d2['vol_p60'], False)
|
||
|
|
n_before = len(eng2.trade_history)
|
||
|
|
eng2.process_day(ds, df, acols, vol_regime_ok=vol_ok)
|
||
|
|
n_after = len(eng2.trade_history)
|
||
|
|
print(f" Day {i+1} {ds}: cap=${eng2.capital:,.0f} trades_today={n_after-n_before} total={n_after} vol_ok_bars={n_vol_ok}/{len(df)} base_max={eng2.base_max_leverage:.1f}")
|
||
|
|
del df; gc.collect()
|
||
|
|
|
||
|
|
print("\nDONE")
|