initial: import DOLPHIN baseline 2026-04-21 from dolphinng5_predict working tree
Includes core prod + GREEN/BLUE subsystems: - prod/ (BLUE harness, configs, scripts, docs) - nautilus_dolphin/ (GREEN Nautilus-native impl + dvae/ preserved) - adaptive_exit/ (AEM engine + models/bucket_assignments.pkl) - Observability/ (EsoF advisor, TUI, dashboards) - external_factors/ (EsoF producer) - mc_forewarning_qlabs_fork/ (MC regime/envelope) Excludes runtime caches, logs, backups, and reproducible artifacts per .gitignore.
This commit is contained in:
88
prod/validate_capital_fix.py
Executable file
88
prod/validate_capital_fix.py
Executable file
@@ -0,0 +1,88 @@
|
||||
"""
|
||||
Validates the two root-cause fixes:
|
||||
1. Capital no longer resets to 25k (portfolio sync removed)
|
||||
2. _exec_submit_entry no longer throws NaN (entry_price added to entry dict)
|
||||
|
||||
Runs TWO consecutive days and verifies capital carries forward.
|
||||
"""
|
||||
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 prod.nautilus_actor_56day_backtest import (
|
||||
run_one_day_nautilus, get_parquet_files, _safe_capital
|
||||
)
|
||||
|
||||
files = get_parquet_files()
|
||||
if len(files) < 2:
|
||||
print("FAIL: Need at least 2 parquet files for validation")
|
||||
sys.exit(1)
|
||||
|
||||
print("=" * 60)
|
||||
print("CAPITAL CARRY-FORWARD VALIDATION")
|
||||
print("=" * 60)
|
||||
|
||||
# Build vol_p60
|
||||
df0 = pd.read_parquet(files[0])
|
||||
btc = df0['BTCUSDT'].values
|
||||
vols = []
|
||||
for i in range(50, len(btc)):
|
||||
seg = btc[max(0, i-50):i]
|
||||
if len(seg) >= 10:
|
||||
v = float(np.std(np.diff(seg) / seg[:-1]))
|
||||
if v > 0 and np.isfinite(v):
|
||||
vols.append(v)
|
||||
vol_p60 = float(np.percentile(vols, 60)) if vols else 0.0002
|
||||
print(f"vol_p60 = {vol_p60:.8f}")
|
||||
|
||||
assets = [c for c in df0.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'
|
||||
}]
|
||||
all_dates = [f.stem for f in files]
|
||||
|
||||
# --- Day 1 ---
|
||||
d1 = files[0].stem
|
||||
print(f"\n[Day 1] {d1} start_cap=$25,000.00")
|
||||
r1 = run_one_day_nautilus(d1, 25000.0, vol_p60, all_dates, assets)
|
||||
cap1 = r1['capital']
|
||||
pnl1 = r1['pnl']
|
||||
trades1 = r1['trades']
|
||||
print(f" -> capital=${cap1:,.2f} pnl=${pnl1:+,.2f} trades={trades1}")
|
||||
|
||||
if not np.isfinite(cap1):
|
||||
print("FAIL: Day 1 capital is non-finite!")
|
||||
sys.exit(1)
|
||||
|
||||
# --- Day 2 (carried forward) ---
|
||||
d2 = files[1].stem
|
||||
print(f"\n[Day 2] {d2} start_cap=${cap1:,.2f}")
|
||||
r2 = run_one_day_nautilus(d2, cap1, vol_p60, all_dates, assets)
|
||||
cap2 = r2['capital']
|
||||
pnl2 = r2['pnl']
|
||||
trades2 = r2['trades']
|
||||
print(f" -> capital=${cap2:,.2f} pnl=${pnl2:+,.2f} trades={trades2}")
|
||||
|
||||
if not np.isfinite(cap2):
|
||||
print("FAIL: Day 2 capital is non-finite!")
|
||||
sys.exit(1)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("RESULTS:")
|
||||
print(f" Day 1 end cap : ${cap1:,.2f}")
|
||||
print(f" Day 2 end cap : ${cap2:,.2f}")
|
||||
print(f" Day 2 started with ${cap1:,.2f} (not $25,000)")
|
||||
|
||||
if abs(cap1 - 25000.0) < 0.01 and trades1 > 0:
|
||||
print(" FAIL: capital still stuck at $25,000 after trades!")
|
||||
elif abs(cap2 - 25000.0) < 0.01 and cap1 != 25000.0 and trades2 > 0:
|
||||
print(" FAIL: Day 2 reset capital back to $25,000 (carry-forward broken)!")
|
||||
else:
|
||||
print(" PASS: Capital carry-forward is working correctly")
|
||||
|
||||
print("=" * 60)
|
||||
Reference in New Issue
Block a user