Files
DOLPHIN/nautilus_dolphin/test_pf_meta_boost.py
hjnormey 01c19662cb 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.
2026-04-21 16:58:38 +02:00

192 lines
8.2 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Meta-boost: ACB inverse boost × signal confidence (cubic convex strength).
final_boost = acb_boost * (1 + beta * strength^3)
Where strength = (threshold - vel_div) / (threshold - extreme), clamped [0,1].
When eigenvalue + external factors BOTH confirm stress → amplified position.
"""
import sys, time, math
from pathlib import Path
import numpy as np
import pandas as pd
sys.path.insert(0, str(Path(__file__).parent))
print("Compiling numba kernels...")
t0c = time.time()
from nautilus_dolphin.nautilus.alpha_asset_selector import compute_irp_nb, compute_ars_nb, rank_assets_irp_nb
from nautilus_dolphin.nautilus.alpha_bet_sizer import compute_sizing_nb
from nautilus_dolphin.nautilus.alpha_signal_generator import check_dc_nb
_p = np.array([1.0, 2.0, 3.0], dtype=np.float64)
compute_irp_nb(_p, -1); compute_ars_nb(1.0, 0.5, 0.01)
rank_assets_irp_nb(np.ones((10, 2), dtype=np.float64), 8, -1, 5, 500.0, 20, 0.20)
compute_sizing_nb(-0.03, -0.02, -0.05, 3.0, 0.5, 5.0, 0.20, True, True, 0.0,
np.zeros(4, dtype=np.int64), np.zeros(4, dtype=np.int64),
np.zeros(5, dtype=np.float64), 0, -1, 0.01, 0.04)
check_dc_nb(_p, 3, 1, 0.75)
print(f" JIT: {time.time() - t0c:.1f}s")
from nautilus_dolphin.nautilus.alpha_orchestrator import NDAlphaEngine
from nautilus_dolphin.nautilus.adaptive_circuit_breaker import AdaptiveCircuitBreaker
VBT_DIR = Path(r"C:\Users\Lenovo\Documents\- DOLPHIN NG HD HCM TSF Predict\vbt_cache")
META_COLS = {'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_KWARGS = dict(
initial_capital=25000.0, vel_div_threshold=-0.02, vel_div_extreme=-0.05,
min_leverage=0.5, max_leverage=5.0, leverage_convexity=3.0,
fraction=0.20, fixed_tp_pct=0.0099, stop_pct=1.0, max_hold_bars=120,
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, min_irp_alignment=0.45,
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,
)
VD_THRESH = -0.02
VD_EXTREME = -0.05
CONVEXITY = 3.0
acb = AdaptiveCircuitBreaker()
parquet_files = sorted(VBT_DIR.glob("*.parquet"))
acb_signals = {pf.stem: acb.get_cut_for_date(pf.stem)['signals'] for pf in parquet_files}
# Vol
all_vols = []
for pf in parquet_files[:2]:
df = pd.read_parquet(pf)
if 'BTCUSDT' not in df.columns: continue
pr = df['BTCUSDT'].values
for i in range(60, len(pr)):
seg = pr[max(0,i-50):i]
if len(seg)<10: continue
v = float(np.std(np.diff(seg)/seg[:-1]))
if v > 0: all_vols.append(v)
vol_p60 = float(np.percentile(all_vols, 60))
# Pre-load
pq_data = {}
for pf in parquet_files:
df = pd.read_parquet(pf)
ac = [c for c in df.columns if c not in META_COLS]
bp = df['BTCUSDT'].values if 'BTCUSDT' in df.columns else None
dv = np.full(len(df), np.nan)
if bp is not None:
for i in range(50, len(bp)):
seg = bp[max(0,i-50):i]
if len(seg)<10: continue
dv[i] = float(np.std(np.diff(seg)/seg[:-1]))
pq_data[pf.stem] = (df, ac, dv)
def log05(s):
return 1.0 + 0.5 * math.log1p(s) if s >= 1.0 else 1.0
def strength_score(vel_div):
"""Cubic convex signal confidence, same as bet_sizer."""
if vel_div >= VD_THRESH: return 0.0
raw = (VD_THRESH - vel_div) / (VD_THRESH - VD_EXTREME)
return min(1.0, max(0.0, raw)) ** CONVEXITY
def run(beta, label=""):
"""beta=0 means no meta-boost (pure log_0.5). beta>0 adds meta-boost."""
engine = NDAlphaEngine(**ENGINE_KWARGS)
bar_idx = 0; ph = {}; peak = engine.capital; max_dd = 0.0; dstats = []
meta_boosts_applied = []
for pf in parquet_files:
ds = pf.stem; cs = engine.capital; ts = len(engine.trade_history)
signals = acb_signals[ds]
base_boost = log05(signals)
engine.regime_direction = -1
engine.regime_dd_halt = False
df, acols, dvol = pq_data[ds]
bid = 0
for ri in range(len(df)):
row = df.iloc[ri]; vd = row.get("vel_div")
if vd is None or not np.isfinite(vd): bar_idx+=1; bid+=1; continue
prices = {}
for ac in acols:
p = row[ac]
if p and p > 0 and np.isfinite(p):
prices[ac] = float(p)
if ac not in ph: ph[ac] = []
ph[ac].append(float(p))
if not prices: bar_idx+=1; bid+=1; continue
vrok = False if bid < 100 else (np.isfinite(dvol[ri]) and dvol[ri] > vol_p60)
# Meta-boost: per-bar, uses current vel_div strength
if beta > 0 and base_boost > 1.0:
ss = strength_score(float(vd))
meta_mult = 1.0 + beta * ss
engine.regime_size_mult = base_boost * meta_mult
if ss > 0.1:
meta_boosts_applied.append((ds, float(vd), ss, base_boost, meta_mult, engine.regime_size_mult))
else:
engine.regime_size_mult = base_boost
engine.process_bar(bar_idx=bar_idx, vel_div=float(vd), prices=prices,
vol_regime_ok=vrok, price_histories=ph)
bar_idx+=1; bid+=1
ce = engine.capital; peak = max(peak, ce)
dd = (peak-ce)/peak*100 if peak>0 else 0; max_dd = max(max_dd, dd)
dstats.append({'date':ds,'pnl':ce-cs,'cap':ce,'dd':dd})
tr = engine.trade_history
w = [t for t in tr if t.pnl_absolute>0]; l = [t for t in tr if t.pnl_absolute<=0]
gw = sum(t.pnl_absolute for t in w) if w else 0
gl = abs(sum(t.pnl_absolute for t in l)) if l else 0
dr = [s['pnl']/25000*100 for s in dstats]
return {
'roi':(engine.capital-25000)/25000*100, 'pf':gw/gl if gl>0 else 999,
'dd':max_dd, 'sharpe':np.mean(dr)/np.std(dr)*np.sqrt(365) if np.std(dr)>0 else 0,
'trades':len(tr), 'wr':len(w)/len(tr)*100 if tr else 0,
'cap':engine.capital,
}, dstats, meta_boosts_applied
# Run sweep of beta values
print(f"\n{'='*85}")
print(f"{'STRATEGY':<25} {'ROI%':>7} {'PF':>6} {'DD%':>6} {'SHARPE':>7} {'TRADES':>7} {'WR%':>6} {'CAPITAL':>10}")
print(f"{'='*85}")
t0 = time.time()
results = {}
for beta in [0, 0.3, 0.5, 0.7, 1.0, 1.5, 2.0]:
label = "log_0.5 (no meta)" if beta == 0 else f"meta_beta={beta}"
r, ds, mb = run(beta)
results[beta] = (r, ds, mb)
print(f"{label:<25} {r['roi']:>+7.2f} {r['pf']:>6.3f} {r['dd']:>6.2f} {r['sharpe']:>7.2f} "
f"{r['trades']:>7} {r['wr']:>6.1f} {r['cap']:>10.2f}")
# Overfitting check on top 3
mid = len(parquet_files) // 2
print(f"\n--- OVERFITTING CHECK (H1 vs H2 P&L) ---")
for beta in [0, 0.5, 1.0, 1.5]:
r, ds, _ = results[beta]
h1 = sum(s['pnl'] for s in ds[:mid])
h2 = sum(s['pnl'] for s in ds[mid:])
label = "log_0.5" if beta == 0 else f"meta_{beta}"
print(f" {label:<15} H1=${h1:>+9.2f} H2=${h2:>+9.2f} H2/H1={h2/h1:.2f}" if h1 != 0 else f" {label}: H1=0")
# Show meta-boost examples from best beta
best_beta = max(results.keys(), key=lambda b: results[b][0]['roi'] if b > 0 else -999)
print(f"\n--- META-BOOST EXAMPLES (beta={best_beta}) ---")
_, _, mb = results[best_beta]
seen_dates = set()
for ds, vd, ss, bb, mm, final in sorted(mb, key=lambda x: -x[5])[:15]:
if ds not in seen_dates:
print(f" {ds} vel_div={vd:.4f} strength³={ss:.3f} acb_boost={bb:.2f}x meta_mult={mm:.2f}x FINAL={final:.2f}x")
seen_dates.add(ds)
r0 = results[0][0]
rb = results[best_beta][0]
print(f"\n=== BEST: meta_beta={best_beta} ===")
print(f"ROI: {r0['roi']:+.2f}% -> {rb['roi']:+.2f}% ({rb['roi']-r0['roi']:+.2f}% over log_0.5)")
print(f"PF: {r0['pf']:.3f} -> {rb['pf']:.3f}")
print(f"Sharpe: {r0['sharpe']:.2f} -> {rb['sharpe']:.2f}")
print(f"DD: {r0['dd']:.2f}% -> {rb['dd']:.2f}%")
print(f"Total time: {time.time()-t0:.0f}s")