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:
162
nautilus_dolphin/patch_orchestrator.py
Executable file
162
nautilus_dolphin/patch_orchestrator.py
Executable file
@@ -0,0 +1,162 @@
|
||||
import sys
|
||||
|
||||
with open('nautilus_dolphin/nautilus/alpha_orchestrator.py', 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
addition = """
|
||||
def set_acb(self, acb) -> None:
|
||||
\"\"\"Inject AdaptiveCircuitBreaker for per-date boost + dynamic beta.\"\"\"
|
||||
self._acb = acb
|
||||
|
||||
def set_mc_forewarner(self, forewarner, mc_base_cfg: dict) -> None:
|
||||
\"\"\"Inject DolphinForewarner + frozen champion config for per-date envelope gate.\"\"\"
|
||||
self._forewarner = forewarner
|
||||
self._mc_base_cfg = dict(mc_base_cfg)
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# Internal helpers — ACB 3-scale meta-boost
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _strength_cubic(self, vel_div: float) -> float:
|
||||
\"\"\"Normalised signal strength in [0,1]^convexity — mirrors bet_sizer formula.\"\"\"
|
||||
if vel_div >= self.signal_gen.threshold:
|
||||
return 0.0
|
||||
raw = (self.signal_gen.threshold - vel_div) / (self.signal_gen.threshold - self.signal_gen.extreme)
|
||||
return min(1.0, max(0.0, raw)) ** self.bet_sizer.convexity
|
||||
|
||||
def _update_regime_size_mult(self, vel_div: float) -> None:
|
||||
\"\"\"Compute regime_size_mult from ACB day state + current vel_div strength.
|
||||
|
||||
3-scale formula: base_boost × (1 + β × strength³) × mc_scale
|
||||
β>0 gate is doctrinal: applies whenever eigenvalue-velocity regime is active,
|
||||
independent of whether ACB has macro signals (base_boost may still be 1.0).
|
||||
\"\"\"
|
||||
if self._day_beta > 0:
|
||||
ss = self._strength_cubic(vel_div)
|
||||
self.regime_size_mult = self._day_base_boost * (1.0 + self._day_beta * ss) * self._day_mc_scale
|
||||
else:
|
||||
self.regime_size_mult = self._day_base_boost * self._day_mc_scale
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# process_day — canonical day runner (params live here, not in tests)
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def process_day(
|
||||
self,
|
||||
date_str: str,
|
||||
df,
|
||||
asset_columns: list,
|
||||
vol_regime_ok = None,
|
||||
) -> dict:
|
||||
\"\"\"Run one full trading day. All per-date regime setup is internal.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
date_str : str
|
||||
Date string matching ACB w750 cache key, e.g. '2026-01-14'.
|
||||
df : pd.DataFrame
|
||||
Parquet bar data: must contain 'vel_div' column + asset price columns.
|
||||
asset_columns : List[str]
|
||||
Non-meta column names (asset price columns only).
|
||||
vol_regime_ok : Optional[np.ndarray]
|
||||
Per-bar boolean array (len == len(df)). If None, bars 0-99 are treated
|
||||
as warm-up (vol_ok=False); bar 100+ treated as True.
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
date, pnl, capital, boost, beta, mc_status, trades
|
||||
\"\"\"
|
||||
import numpy as np
|
||||
cap_start = self.capital
|
||||
self.regime_direction = -1 # SHORT-biased (invariant of champion)
|
||||
self.regime_dd_halt = False
|
||||
self._day_mc_scale = 1.0
|
||||
self._day_mc_status = 'OK'
|
||||
|
||||
# 1. ACB per-date: dynamic beta + base boost (OB Sub-4 modulates beta)
|
||||
if hasattr(self, '_acb') and self._acb is not None:
|
||||
acb_info = self._acb.get_dynamic_boost_for_date(date_str, ob_engine=self.ob_engine)
|
||||
self._day_base_boost = acb_info['boost']
|
||||
self._day_beta = acb_info['beta']
|
||||
else:
|
||||
self._day_base_boost = 1.0
|
||||
self._day_beta = 0.0
|
||||
|
||||
# 2. MC-Forewarner per-date envelope gate
|
||||
if hasattr(self, '_forewarner') and self._forewarner is not None and self._mc_base_cfg is not None:
|
||||
mc_cfg = dict(self._mc_base_cfg)
|
||||
mc_cfg['max_leverage'] = self.base_max_leverage * self._day_base_boost
|
||||
mc_report = self._forewarner.assess_config_dict(mc_cfg)
|
||||
mc_red = mc_report.catastrophic_probability > 0.25 or mc_report.envelope_score < -1.0
|
||||
mc_orange = (not mc_red) and (
|
||||
mc_report.envelope_score < 0 or mc_report.catastrophic_probability > 0.10
|
||||
)
|
||||
self._day_mc_status = 'RED' if mc_red else ('ORANGE' if mc_orange else 'OK')
|
||||
self._day_mc_scale = 0.5 if mc_orange else 1.0
|
||||
if mc_red:
|
||||
self.regime_dd_halt = True
|
||||
|
||||
# 3. Bar loop
|
||||
n_before = len(self.trade_history)
|
||||
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(float(vd)):
|
||||
self._global_bar_idx += 1; bid += 1; continue
|
||||
|
||||
v50_raw = row.get('v50_lambda_max_velocity')
|
||||
v750_raw = row.get('v750_lambda_max_velocity')
|
||||
v50_val = float(v50_raw) if (v50_raw is not None and np.isfinite(float(v50_raw))) else 0.0
|
||||
v750_val = float(v750_raw) if (v750_raw is not None and np.isfinite(float(v750_raw))) else 0.0
|
||||
|
||||
prices = {}
|
||||
for ac in asset_columns:
|
||||
p = row.get(ac)
|
||||
if p is not None and p > 0 and np.isfinite(p):
|
||||
prices[ac] = float(p)
|
||||
if ac not in self._price_histories:
|
||||
self._price_histories[ac] = []
|
||||
self._price_histories[ac].append(float(p))
|
||||
if len(self._price_histories[ac]) > 500:
|
||||
self._price_histories[ac] = self._price_histories[ac][-200:]
|
||||
|
||||
if not prices:
|
||||
self._global_bar_idx += 1; bid += 1; continue
|
||||
|
||||
vrok = bool(vol_regime_ok[ri]) if vol_regime_ok is not None else (bid >= 100)
|
||||
|
||||
# Compute regime_size_mult from ACB day state + current signal strength
|
||||
self._update_regime_size_mult(float(vd))
|
||||
|
||||
self.process_bar(
|
||||
bar_idx=self._global_bar_idx,
|
||||
vel_div=float(vd),
|
||||
prices=prices,
|
||||
vol_regime_ok=vrok,
|
||||
price_histories=self._price_histories,
|
||||
v50_vel=v50_val,
|
||||
v750_vel=v750_val,
|
||||
)
|
||||
self._global_bar_idx += 1
|
||||
bid += 1
|
||||
|
||||
return {
|
||||
'date': date_str,
|
||||
'pnl': self.capital - cap_start,
|
||||
'capital': self.capital,
|
||||
'boost': self._day_base_boost,
|
||||
'beta': self._day_beta,
|
||||
'mc_status': self._day_mc_status,
|
||||
'trades': len(self.trade_history) - n_before,
|
||||
}
|
||||
"""
|
||||
|
||||
if "def process_day" not in text:
|
||||
with open('nautilus_dolphin/nautilus/alpha_orchestrator.py', 'a', encoding='utf-8') as f:
|
||||
f.write(addition)
|
||||
print("Patched alpha_orchestrator.py successfully.")
|
||||
else:
|
||||
print("Already patched.")
|
||||
|
||||
Reference in New Issue
Block a user