93 lines
3.7 KiB
Python
93 lines
3.7 KiB
Python
|
|
"""
|
||
|
|
Direct engine test - bypasses Nautilus completely.
|
||
|
|
Runs NDAlphaEngine (D_LIQ_GOLD) on Day 1 parquet and prints capital.
|
||
|
|
Should take ~5 seconds. If capital moves from 25000, the engine is fine.
|
||
|
|
If capital stays at 25000, reset() is being called somewhere wrong.
|
||
|
|
"""
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
import numpy as np
|
||
|
|
import pandas as pd
|
||
|
|
|
||
|
|
sys.path.insert(0, str(Path(__file__).parent.parent))
|
||
|
|
sys.path.insert(0, str(Path(__file__).parent.parent / 'nautilus_dolphin'))
|
||
|
|
|
||
|
|
from nautilus_dolphin.nautilus.proxy_boost_engine import create_boost_engine
|
||
|
|
|
||
|
|
VBT_DIR = Path(__file__).parent.parent / 'vbt_cache'
|
||
|
|
files = sorted(VBT_DIR.glob('*.parquet'))
|
||
|
|
files = [f for f in files if 'catalog' not in str(f)]
|
||
|
|
assert files, f"No parquets in {VBT_DIR}"
|
||
|
|
|
||
|
|
df = pd.read_parquet(files[0])
|
||
|
|
print(f"Day: {files[0].stem} rows={len(df)}")
|
||
|
|
|
||
|
|
asset_cols = [c for c in df.columns if c not in {
|
||
|
|
'timestamp','scan_number','v50_lambda_max_velocity',
|
||
|
|
'v150_lambda_max_velocity','v300_lambda_max_velocity',
|
||
|
|
'v750_lambda_max_velocity','vel_div','instability_50','instability_150'
|
||
|
|
}]
|
||
|
|
|
||
|
|
engine = create_boost_engine(mode='d_liq', initial_capital=25000.0, seed=42)
|
||
|
|
|
||
|
|
# Build vol mask identical to _run_replay_day
|
||
|
|
btc = df['BTCUSDT'].values if 'BTCUSDT' in df.columns else None
|
||
|
|
vol_ok = np.zeros(len(df), dtype=bool)
|
||
|
|
if btc is not None:
|
||
|
|
for i in range(50, len(btc)):
|
||
|
|
seg = btc[max(0,i-50):i]
|
||
|
|
if len(seg) >= 10 and all(seg > 0):
|
||
|
|
v = float(np.std(np.diff(seg)/seg[:-1]))
|
||
|
|
if np.isfinite(v):
|
||
|
|
vol_ok[i] = True # just mark computable; gate uses percentile
|
||
|
|
|
||
|
|
vol_p60 = float(np.percentile([float(np.std(np.diff(btc[max(0,i-50):i])/btc[max(0,i-50):i][:-1]))
|
||
|
|
for i in range(50, len(btc))
|
||
|
|
if len(btc[max(0,i-50):i])>=10 and all(btc[max(0,i-50):i]>0)
|
||
|
|
and np.isfinite(float(np.std(np.diff(btc[max(0,i-50):i])/btc[max(0,i-50):i][:-1])))], 60)) if btc is not None else 0.0002
|
||
|
|
|
||
|
|
dvol_arr = np.full(len(df), np.nan)
|
||
|
|
if btc is not None:
|
||
|
|
for i in range(50, len(btc)):
|
||
|
|
seg = btc[max(0,i-50):i]
|
||
|
|
if len(seg)>=10 and (seg>0).all():
|
||
|
|
dvol_arr[i] = float(np.std(np.diff(seg)/seg[:-1]))
|
||
|
|
vol_ok_mask = np.where(np.isfinite(dvol_arr), dvol_arr > vol_p60, False)
|
||
|
|
|
||
|
|
engine.begin_day(files[0].stem)
|
||
|
|
trades_count = 0
|
||
|
|
for i in range(len(df)):
|
||
|
|
row = df.iloc[i]
|
||
|
|
vd = row.get('vel_div', 0.0)
|
||
|
|
if vd is None or not np.isfinite(float(vd)):
|
||
|
|
continue
|
||
|
|
prices = {ac: float(row[ac]) for ac in asset_cols
|
||
|
|
if ac in row and row[ac] is not None and float(row[ac]) > 0 and np.isfinite(float(row[ac]))}
|
||
|
|
if not prices:
|
||
|
|
continue
|
||
|
|
vrok = (i >= 100) and bool(vol_ok_mask[i])
|
||
|
|
v50 = float(row.get('v50_lambda_max_velocity', 0.0) or 0.0)
|
||
|
|
v750 = float(row.get('v750_lambda_max_velocity', 0.0) or 0.0)
|
||
|
|
result = engine.step_bar(bar_idx=i, vel_div=float(vd), prices=prices,
|
||
|
|
vol_regime_ok=vrok, v50_vel=v50, v750_vel=v750)
|
||
|
|
if result.get('entry'):
|
||
|
|
trades_count += 1
|
||
|
|
|
||
|
|
day_result = engine.end_day()
|
||
|
|
capital_end = engine.capital
|
||
|
|
trades_end = len(engine.trade_history)
|
||
|
|
|
||
|
|
print(f"vol_p60 = {vol_p60:.8f}")
|
||
|
|
print(f"capital_start = $25,000.00")
|
||
|
|
print(f"capital_end = ${capital_end:,.2f}")
|
||
|
|
print(f"pnl = ${capital_end - 25000.0:+,.2f}")
|
||
|
|
print(f"trades_entered = {trades_count}")
|
||
|
|
print(f"trades_closed = {trades_end}")
|
||
|
|
if capital_end == 25000.0:
|
||
|
|
if trades_end == 0:
|
||
|
|
print("INFO: No trades closed yet (open position or vol gate blocked all entries)")
|
||
|
|
else:
|
||
|
|
print("WARN: Capital unchanged despite trades — check fee model and P&L calc")
|
||
|
|
else:
|
||
|
|
print("PASS: Capital moved correctly — engine P&L is working")
|