Files
DOLPHIN/prod/docs/NAUTILUS_DOLPHIN_SPEC.md
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

31 KiB
Executable File
Raw Permalink Blame History

Nautilus-DOLPHIN / Alpha Engine Core — Implementation Specification

Version: 1.0 Date: 2026-03-22 Status: Production-ready (paper trading); live deployment pending exchange integration Environment: siloqy-env (/home/dolphin/siloqy_env/bin/activate) Stack: nautilus_trader 1.219.0 · prefect 3.6.22 · hazelcast-python-client 5.6.0 · numba 0.61.2


1. System Overview

Nautilus-DOLPHIN is a production algorithmic trading system built on the NautilusTrader Rust-core HFT framework. It wraps a 7-layer alpha engine ("NDAlphaEngine") inside a NautilusTrader Strategy primitive ("DolphinActor"), supervised by Prefect for resilience and Hazelcast for distributed system memory.

1.1 Performance Specification (Champion — FROZEN)

Metric Champion Value
ROI (backtest period) +54.67%
Profit Factor 1.141
Sharpe Ratio 2.84
Max Drawdown 15.80%
Win Rate 49.5%
Direction SHORT only (blue deployment)
Bar resolution 5-second
Markets Binance Futures perpetuals (~48 assets)

These numbers are invariants. Any code change that causes a statistically significant deviation must be rejected.

1.2 Architecture Summary

┌────────────────────────────────────────────────────────────────┐
│                    Prefect Supervision Layer                    │
│  paper_trade_flow.py (00:05 UTC)   nautilus_prefect_flow.py    │
│  dolphin_nautilus_flow (00:10 UTC)                             │
└──────────────────────────────┬─────────────────────────────────┘
                               │
┌──────────────────────────────▼─────────────────────────────────┐
│              NautilusTrader Execution Kernel                    │
│   BacktestEngine (paper) / TradingNode (live)                  │
│                                                                 │
│   ┌─────────────────────────────────────────┐                  │
│   │           DolphinActor (Strategy)        │                  │
│   │  on_start() → connect HZ, ACB listener  │                  │
│   │  on_bar()   → step_bar() per 5s tick     │                  │
│   │  on_stop()  → cleanup, HZ shutdown       │                  │
│   └──────────────────────┬──────────────────┘                  │
│                           │                                     │
│   ┌───────────────────────▼──────────────────────────────────┐ │
│   │                  NDAlphaEngine                            │ │
│   │  7-layer alpha stack (see §4)                             │ │
│   │  begin_day() / step_bar() / end_day()                     │ │
│   └───────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬─────────────────────────────────┘
                               │
┌──────────────────────────────▼─────────────────────────────────┐
│                  Hazelcast "System Memory"                      │
│  DOLPHIN_SAFETY    → posture, Rm (survival stack)              │
│  DOLPHIN_FEATURES  → ACB boost, beta, eigen scan               │
│  DOLPHIN_PNL_BLUE  → daily trade results                       │
│  DOLPHIN_STATE_BLUE→ capital state (continuity)                │
│  DOLPHIN_HEARTBEAT → liveness probes                           │
│  DOLPHIN_FEATURES_SHARD_00..09 → 400-asset feature shards     │
└────────────────────────────────────────────────────────────────┘

2. File Map

/mnt/dolphinng5_predict/
│
├── prod/
│   ├── paper_trade_flow.py         # Primary daily Prefect flow (NDAlphaEngine direct)
│   ├── nautilus_prefect_flow.py    # Nautilus BacktestEngine Prefect flow (NEW)
│   ├── run_nautilus.py             # Standalone Nautilus CLI runner
│   ├── configs/
│   │   ├── blue.yml                # Champion SHORT config (FROZEN)
│   │   └── green.yml               # Bidirectional config (pending LONG validation)
│   └── OBF_SUBSYSTEM.md           # OBF architecture reference
│
├── nautilus_dolphin/
│   └── nautilus_dolphin/
│       └── nautilus/
│           ├── dolphin_actor.py        # DolphinActor(Strategy) — Nautilus wrapper
│           ├── esf_alpha_orchestrator.py # NDAlphaEngine — 7-layer core
│           ├── proxy_boost_engine.py   # ProxyBoostEngine wrapper (ACBv6 pre-compute)
│           ├── adaptive_circuit_breaker.py  # ACBv6 — 3-scale regime sizing
│           ├── strategy.py             # DolphinExecutionStrategy (signal-level)
│           ├── strategy_config.py      # DolphinStrategyConfig (StrategyConfig subclass)
│           ├── launcher.py             # NautilusDolphinLauncher (TradingNode)
│           ├── ob_features.py          # OBFeatureEngine — order book intelligence
│           ├── hz_ob_provider.py       # HZOBProvider — HZ-backed OB data source
│           └── circuit_breaker.py      # CircuitBreakerManager
│   └── tests/
│       ├── test_0_nautilus_bootstrap.py  # 11 foundation tests
│       ├── test_dolphin_actor.py        # 35 DolphinActor lifecycle tests (NEW)
│       ├── test_strategy.py             # DolphinExecutionStrategy filter tests
│       ├── test_adaptive_circuit_breaker.py
│       ├── test_circuit_breaker.py
│       ├── test_volatility_detector.py
│       └── [12 other test files]
│
└── vbt_cache_klines/               # 5s OHLCV parquet files — daily replay source
    └── YYYY-MM-DD.parquet          # cols: vel_div, v50/v150/v300/v750, instability_*, 48 assets

3. Champion Parameters (FROZEN)

These parameters are derived from the champion backtest and must not be altered without a full re-validation run showing performance preservation.

Parameter Value Description
vel_div_threshold -0.02 Primary signal gate: vd must be ≤ this to open a position
vel_div_extreme -0.05 Extreme signal bucket threshold (max leverage tier)
fixed_tp_pct 0.0095 Take-profit at 95 bps from entry (TP sweep 2026-03-06)
max_hold_bars 120 Maximum holding period in 5s bars (= 10 minutes)
fraction 0.20 Base position size fraction of capital
min_leverage 0.5 Floor leverage (applied by AlphaBetSizer)
max_leverage 5.0 Soft leverage ceiling
abs_max_leverage 6.0 Hard leverage ceiling (Rm-scaled by Survival Stack)
leverage_convexity 3.0 Cubic exponent for convex leverage scaling
dc_lookback_bars 7 Direction confirmation lookback window
dc_min_magnitude_bps 0.75 Minimum velocity magnitude for DC trigger
min_irp_alignment 0.45 IRP asset selection threshold
sp_maker_entry_rate 0.62 SmartPlacer: 62% maker fill rate at entry
sp_maker_exit_rate 0.50 SmartPlacer: 50% maker fill rate at exit
seed 42 NumPy / numba RNG seed (reproducibility invariant)

Verification: nautilus_prefect_flow._CHAMPION_HASH is computed at import time from these values. Any config drift triggers ValueError and aborts the flow.


4. Alpha Engine — 7-Layer Stack

Layer 1: Velocity Divergence Signal Gate (AlphaSignalGenerator)

Input: vel_div = v50_lambda_max_velocity - v150_lambda_max_velocity

The primary alpha signal. v50 is the 50-window eigenvalue velocity; v150 the 150-window. Negative divergence signals short momentum.

Buckets:
  0 (extreme):  vel_div ≤ -0.075   → max leverage
  1 (strong):   vel_div ≤ -0.050   → high leverage
  2 (moderate): vel_div ≤ -0.035   → normal leverage
  3 (weak):     vel_div ≤ -0.020   → min leverage

Only fires if vel_div ≤ vel_div_threshold (-0.02). Includes direction confirmation (dc_lookback_bars=7, dc_min_magnitude_bps=0.75).

Layer 2: Volatility Regime Filter (VolatilityRegimeDetector)

Rolling 50-bar standard deviation of BTC returns. Positions are only opened when dvol > vol_p60 (60th percentile threshold = 0.000099 from 55-day champion calibration). Prevents trading in dead-market microstructure.

Layer 3: SmartPlacer Fee Model (AlphaSignalGenerator)

Models maker vs taker execution costs:

  • sp_maker_entry_rate=0.62: 62% of entries assumed as maker (0.02% fee)
  • sp_maker_exit_rate=0.50: 50% of exits as maker
  • Remaining fills incur taker fee (+0.04%)
  • Net fee per round trip ≈ 0.020.04% depending on fill mix

Fee is charged per trade in NDAlphaEngine.process_bar(). No real order routing in paper mode — fee is applied analytically.

Layer 4: OB Intelligence — 5 Sub-systems (OBFeatureEngine / HZOBProvider)

Reads from DOLPHIN_FEATURES_SHARD_{idx} or ob_cache/latest_ob_features.json:

Sub-system Key features Effect
1. Placement fill_probability, depth_quality, spread_proxy_bps Adjusts maker entry rate; gates entry if fill_probability < 0.6
2. Signal depth_asymmetry, imbalance_persistence, withdrawal_velocity OB-direction confirmation layer
3. Cross-asset agreement_pct, cascade_count, regime_signal Asset selection weighting in IRP
4. Macro macro_imbalance, macro_spread_bps Long-horizon baseline normalization
5. Raw depth bid/ask_notional_1-5pct, bid/ask_depth_1-5pct Notional depth vectors for all 5 levels

OB edge gate: ob_edge_bps=5.0, ob_confirm_rate=0.40. Entry only if OB confirms directional signal.

Layer 5: IRP Asset Selection (AlphaAssetSelector)

Inter-asset relative performance (IRP) selects which assets to trade each bar. Only assets where imbalance sign aligns with the directional view, and where irp_alignment ≥ min_irp_alignment (0.45), are traded.

Layer 6: Dynamic Cubic-Convex Leverage (AlphaBetSizer)

leverage = min_leverage + (max_leverage - min_leverage) × (signal_strength)^leverage_convexity

signal_strength = (vel_div_threshold - vel_div) / (vel_div_threshold - vel_div_extreme)
                 clamped to [0, 1]

Then scaled by regime_size_mult from ACBv6:

regime_size_mult = base_boost × (1 + beta × strength_cubic) × mc_scale

Final leverage clamped to [min_leverage, abs_max_leverage × Rm].

Layer 7: Exit Management (AlphaExitManager)

Two primary exits (no stop loss in champion):

  1. Fixed TP: Exit when price_change_pct ≥ fixed_tp_pct (0.0095) = 95 bps
  2. Max hold: Force exit at max_hold_bars (120) × 5s = 10 minutes

5. DolphinActor — Nautilus Strategy Wrapper

File: nautilus_dolphin/nautilus/dolphin_actor.py Base class: nautilus_trader.trading.strategy.Strategy Lines: 338

5.1 Initialization

class DolphinActor(Strategy):
    def __init__(self, config: dict):
        super().__init__()              # Nautilus Actor Cython init
        self.dolphin_config = config    # full YAML config dict
        self.engine = None              # NDAlphaEngine (created in on_start)
        self.hz_client = None           # HazelcastClient
        self.current_date = None        # tracks date boundary
        self.posture = 'APEX'           # Survival Stack posture
        self._processed_dates = set()
        self._pending_acb: dict | None = None  # pending ACB from HZ listener
        self._acb_lock = threading.Lock()       # guards _pending_acb
        self._stale_state_events = 0
        self.last_scan_number = -1
        self._day_data = None           # (df, asset_columns) for replay mode
        self._bar_idx_today = 0

5.2 on_start() Lifecycle

on_start():
  1. _connect_hz() → hazelcast.HazelcastClient(cluster_name="dolphin", ...)
  2. _read_posture() → reads DOLPHIN_SAFETY (CP atomic ref or map fallback)
  3. _setup_acb_listener() → add_entry_listener on DOLPHIN_FEATURES["acb_boost"]
  4. create_boost_engine(mode=boost_mode, **engine_kwargs) → NDAlphaEngine
  5. MC-Forewarner injection (gold-performance stack — enabled by default):
       mc_models_dir = config.get('mc_models_dir', _MC_MODELS_DIR_DEFAULT)
       DolphinForewarner(models_dir=mc_models_dir) → engine.set_mc_forewarner(fw, _MC_BASE_CFG)
       Graceful: logs warning + continues if models dir missing or import fails.
       Disable: set mc_models_dir=None or mc_models_dir='' in config.

HZ connection failure is non-fatal: hz_client = None, posture defaults to APEX. MC-Forewarner failure is non-fatal: logs warning, _day_mc_scale stays 1.0 (gate disabled).

5.3 on_bar() — Hot Loop

on_bar(bar: Bar):
  ① Apply pending ACB (under _acb_lock):
      pending = _pending_acb; _pending_acb = None
      if pending: engine.update_acb_boost(boost, beta)

  ② Date boundary detection:
      date_str = datetime.fromtimestamp(bar.ts_event / 1e9, UTC).strftime('%Y-%m-%d')
      if current_date != date_str:
          if current_date: engine.end_day()
          current_date = date_str
          posture = _read_posture()
          _bar_idx_today = 0
          engine.begin_day(date_str, posture=posture, direction=±1)
          if not live_mode: _load_parquet_data(date_str) → _day_data

  ③ HIBERNATE guard:
      if posture == 'HIBERNATE': return   # no position opened

  ④ Feature extraction (live HZ vs replay parquet):
      live_mode=True:  _get_latest_hz_scan() → scan dict
                       staleness check: abs(now_ns - scan_ts_ns) > 10s → warning
                       dedup: scan_num == last_scan_number → skip
      live_mode=False: if _day_data empty → return  (no step_bar with zeros)
                       elif bar_idx >= len(df) → return  (end of day)
                       else: df.iloc[_bar_idx_today] → row
                             vol_regime_ok = bar_idx >= 100 (warmup)

  ⑤ Stale-state snapshot (before):
      _snap = _GateSnap(acb_boost, acb_beta, posture, mc_gate_open)

  ⑥ Optional proxy_B pre-update (no-op for baseline engine):
      if hasattr(engine, 'pre_bar_proxy_update'): engine.pre_bar_proxy_update(...)

  ⑦ engine.step_bar(bar_idx, vel_div, prices, v50_vel, v750_vel, vol_regime_ok)
      _bar_idx_today += 1

  ⑧ Stale-state snapshot (after):
      _snap_post = _GateSnap(acb_boost, acb_beta, _read_posture(), mc_gate_open)
      if _snap != _snap_post:
          stale_state_events++
          log.warning("[STALE_STATE] ...")
          result['stale_state'] = True

  ⑨ _write_result_to_hz(date_str, result)

5.4 ACB Thread Safety — Pending-Flag Pattern

HZ listener thread:
    _on_acb_event(event):
        parsed = json.loads(event.value)   # parse OUTSIDE lock (pure CPU)
        with _acb_lock:
            _pending_acb = parsed          # atomic assign under lock

on_bar() (Nautilus event thread):
    with _acb_lock:
        pending = _pending_acb
        _pending_acb = None                # consume atomically
    if pending:
        engine.update_acb_boost(...)       # apply outside lock

This design minimizes lock hold time to a single pointer swap. There is no blocking I/O under the lock.

5.5 on_stop()

def on_stop(self):
    self._processed_dates.clear()    # prevent stale date state on restart
    self._stale_state_events = 0
    if self.hz_client:
        self.hz_client.shutdown()

6. ACBv6 — Adaptive Circuit Breaker

File: nautilus_dolphin/nautilus/adaptive_circuit_breaker.py

6.1 Three-Scale Architecture

regime_size_mult = base_boost × (1 + beta × strength_cubic) × mc_scale

Scale 1 — Daily external factors (base_boost):
  preloaded from recent 60-day w750 velocity history
  p60 threshold determines whether current w750 is "high regime"
  base_boost ∈ [0.5, 2.0] typically

Scale 2 — Per-bar meta-boost (beta × strength_cubic):
  beta: ACB sensitivity parameter from HZ DOLPHIN_FEATURES
  strength_cubic: (|vel_div| / threshold)^3 — convex response to signal strength

Scale 3 — MC-Forewarner scale (mc_scale):
  DolphinForewarner ML model predicts MC regime
  mc_scale ∈ [0.5, 1.5]

6.2 HZ Integration

ACBv6 updates are pushed to DOLPHIN_FEATURES["acb_boost"] by an external Prefect flow. DolphinActor subscribes via add_entry_listener and receives push notifications. Updates are applied at the top of the next on_bar() call (pending-flag pattern, §5.4).

6.3 Cut-to-Position-Size API

acb.apply_cut_to_position_size(position_size, cut_pct)
# cut_pct in [0.0, 0.15, 0.45, 0.55, 0.75, 0.80]
# Returns position_size × (1 - cut_pct)

7. Survival Stack (5-Sensor Posture)

HZ map: DOLPHIN_SAFETY (CP atomic reference preferred, map fallback)

Rm ∈ [0, 1]  — composite risk metric from 5 sensors

Posture       Rm threshold    Behavior
─────────     ────────────    ─────────────────────────────────────────────
APEX          Rm ≥ 0.90       Full operation; abs_max_leverage unrestricted
STALKER       Rm ≥ 0.75       max_leverage capped to 2.0
TURTLE        Rm ≥ 0.50       position sizing reduced via abs_max_leverage × Rm
HIBERNATE     Rm < 0.50       on_bar() returns immediately; no new positions

Posture is re-read on every date change. In paper_trade_flow.py, Rm is applied directly to engine.abs_max_leverage:

engine.abs_max_leverage = max(1.0, engine.abs_max_leverage × Rm)
if posture == 'STALKER':
    engine.abs_max_leverage = min(engine.abs_max_leverage, 2.0)

8. NDAlphaEngine API

File: nautilus_dolphin/nautilus/esf_alpha_orchestrator.py

8.1 Constructor Parameters

See §3 Champion Parameters. Additional non-champion params:

  • stop_pct=1.0 (effectively disabled — TP exits first)
  • lookback=100 (price history window)
  • use_alpha_layers=True (enables OB/IRP/SP layers)
  • use_dynamic_leverage=True (enables cubic-convex sizing)

8.2 Day Lifecycle API

engine.begin_day(date_str: str, posture: str, direction: int)
# Sets regime_direction, reads ACB for the day, resets per-day state

for bar in bars:
    result = engine.step_bar(
        bar_idx=int,         # 0-based index within day
        vel_div=float,       # primary alpha signal
        prices=dict,         # {symbol: float} current prices
        vol_regime_ok=bool,  # volatility gate
        v50_vel=float,       # w50 eigenvalue velocity (raw)
        v750_vel=float,      # w750 eigenvalue velocity (ACB scale)
    ) -> dict

result_dict = engine.end_day()
# Returns: {pnl, trades, capital, boost, beta, mc_status, ...}

8.3 State Fields

Field Type Description
capital float Current equity (updated after each trade)
_day_base_boost float ACB base boost for today
_day_beta float ACB beta sensitivity for today
_day_mc_scale float MC-Forewarner scale for today
_global_bar_idx int Lifetime bar counter (persists across days)
_price_histories dict Per-asset price history lists (≤500 values)
position NDPosition Current open position (None if flat)
trade_history list All closed NDTradeRecord objects
regime_size_mult float Current ACBv6 size multiplier

8.4 Setter Methods

engine.set_ob_engine(ob_engine)         # inject OBFeatureEngine
engine.set_acb(acb)                     # inject AdaptiveCircuitBreaker
engine.set_mc_forewarner(fw, base_cfg)  # inject DolphinForewarner
engine.update_acb_boost(boost, beta)    # called by DolphinActor from HZ events

9. Data Flow — Replay Mode (Paper Trading)

vbt_cache_klines/YYYY-MM-DD.parquet
  ↓  DolphinActor._load_parquet_data()
  ↓  pd.read_parquet() → DataFrame (1439 rows × ~57 cols)
     columns: timestamp, scan_number, vel_div,
              v50/v150/v300/v750_lambda_max_velocity,
              instability_50, instability_150,
              BTCUSDT, ETHUSDT, BNBUSDT, ... (48 assets)
  ↓  DolphinActor.on_bar() iterates rows via _bar_idx_today
  ↓  NDAlphaEngine.step_bar(bar_idx, vel_div, prices, ...)
  ↓  AlphaSignalGenerator → AlphaBetSizer → AlphaExitManager
  ↓  trade_history.append(NDTradeRecord)
  ↓  DolphinActor._write_result_to_hz() → DOLPHIN_PNL_BLUE[date]

9.1 Live Mode Data Flow

Binance Futures WS → OBF prefect flow → Hazelcast DOLPHIN_FEATURES_SHARD_*
Eigenvalue scanner → JSON scan files   → Hazelcast DOLPHIN_FEATURES["latest_eigen_scan"]

DolphinActor.on_bar():
  scan = _get_latest_hz_scan()
  vel_div = scan["vel_div"]
  prices = scan["asset_prices"]
  → engine.step_bar(...)

10. Hazelcast IMap Schema

Map name Key Value Writer Reader
DOLPHIN_SAFETY "latest" JSON {posture, Rm, ...} Survival stack flow DolphinActor, paper_trade_flow
DOLPHIN_FEATURES "acb_boost" JSON {boost, beta} ACB writer flow DolphinActor (listener)
DOLPHIN_FEATURES "latest_eigen_scan" JSON {vel_div, scan_number, asset_prices, ...} Eigenvalue scanner DolphinActor (live mode)
DOLPHIN_PNL_BLUE "YYYY-MM-DD" JSON result dict paper_trade_flow, DolphinActor Analytics
DOLPHIN_STATE_BLUE "latest" JSON {capital, date, pnl, ...} paper_trade_flow paper_trade_flow (restore)
DOLPHIN_STATE_BLUE "latest_nautilus" JSON {capital, param_hash, ...} nautilus_prefect_flow nautilus_prefect_flow
DOLPHIN_HEARTBEAT "nautilus_flow_heartbeat" JSON {ts, phase, ...} nautilus_prefect_flow Monitoring
DOLPHIN_FEATURES_SHARD_00..09 symbol JSON OB feature dict OBF prefect flow HZOBProvider

Shard routing: shard_idx = sum(ord(c) for c in symbol) % 10 — stable, deterministic, no config needed.


11. Prefect Integration

11.1 paper_trade_flow.py (Primary — 00:05 UTC)

Runs NDAlphaEngine directly (no Nautilus kernel). Tasks:

  • load_config — YAML config with retries=0
  • load_day_scans — parquet (preferred) or JSON fallback, retries=2
  • run_engine_day — NDAlphaEngine.begin_day/step_bar/end_day loop
  • write_hz_state — HZ persist, retries=3
  • log_pnl — disk JSONL append

11.2 nautilus_prefect_flow.py (Nautilus Supervisor — 00:10 UTC)

Wraps BacktestEngine + DolphinActor. Tasks:

  • hz_probe_task — verify HZ reachable, retries=3, timeout=30s
  • validate_champion_params — SHA256 hash check vs _CHAMPION_PARAMS, aborts on drift
  • load_bar_data_task — parquet load with validation, retries=2
  • read_posture_task — DOLPHIN_SAFETY read, retries=2
  • restore_capital_task — capital continuity from HZ state
  • run_nautilus_backtest_task — full BacktestEngine cycle, timeout=600s
  • write_hz_result_task — persist to DOLPHIN_PNL_BLUE + DOLPHIN_STATE_BLUE, retries=3
  • heartbeat_task — liveness pulse at flow_start/engine_start/flow_end

11.3 Registration

source /home/dolphin/siloqy_env/bin/activate
PREFECT_API_URL=http://localhost:4200/api

# Primary paper trade (existing):
python prod/paper_trade_flow.py --register

# Nautilus supervisor (new):
python prod/nautilus_prefect_flow.py --register
# → dolphin-nautilus-blue, daily 00:10 UTC, work_pool=dolphin

12. Nautilus Kernel Backends

12.1 BacktestEngine (Paper / Replay)

Used in run_nautilus.py and nautilus_prefect_flow.py. Processes synthetic bars (one bar per date triggers DolphinActor which then iterates over the full parquet day internally). No real exchange connectivity.

engine = BacktestEngine(config=BacktestEngineConfig(trader_id="DOLPHIN-NAUTILUS-001"))
engine.add_strategy(DolphinActor(config=config))
engine.add_venue(Venue("BINANCE"), OmsType.HEDGING, AccountType.MARGIN, ...)
engine.add_instrument(TestInstrumentProvider.default_fx_ccy("BTCUSD", venue))
engine.add_data([synthetic_bar])
engine.run()

12.2 TradingNode (Live — Future)

NautilusDolphinLauncher in launcher.py bootstraps a TradingNode with BinanceExecClientConfig. Requires Binance API keys and live WS data. Not currently active.

from nautilus_dolphin.nautilus.launcher import NautilusDolphinLauncher
launcher = NautilusDolphinLauncher(config_path="prod/configs/blue.yml")
launcher.start()  # blocking — runs until SIGTERM

12.3 Bar Type

"BTCUSD.BINANCE-5-SECOND-LAST-EXTERNAL"

EXTERNAL aggregation type: bars are not synthesized by Nautilus from ticks; they are injected directly. This is the correct type for replay from pre-aggregated parquet.


13. DolphinStrategyConfig

File: nautilus_dolphin/nautilus/strategy_config.py

class DolphinStrategyConfig(StrategyConfig, kw_only=True, frozen=True):
    vel_div_threshold: float = -0.02
    vel_div_extreme: float = -0.05
    fixed_tp_pct: float = 0.0095
    max_hold_bars: int = 120
    fraction: float = 0.20
    min_leverage: float = 0.5
    max_leverage: float = 5.0
    abs_max_leverage: float = 6.0
    leverage_convexity: float = 3.0
    dc_lookback_bars: int = 7
    dc_min_magnitude_bps: float = 0.75
    min_irp_alignment: float = 0.45
    sp_maker_entry_rate: float = 0.62
    sp_maker_exit_rate: float = 0.50
    seed: int = 42
    # ...

Factory methods:

  • create_champion_config() → excluded_assets=["TUSDUSDT","USDCUSDT"]
  • create_conservative_config() → reduced leverage/fraction
  • create_growth_config() → increased leverage
  • create_aggressive_config() → max leverage stack

14. Test Suite Summary

File Tests Coverage
test_0_nautilus_bootstrap.py 11 Import chain, NautilusKernelConfig, ACB, CircuitBreaker, launcher
test_dolphin_actor.py 35 Champion params, ACB thread-safety, HIBERNATE guard, date change, HZ degradation, replay mode, on_stop, _GateSnap
test_strategy.py 4+ DolphinExecutionStrategy signal filters
test_adaptive_circuit_breaker.py ~10 ACBv6 scale computation, cut-to-size
test_circuit_breaker.py ~6 CircuitBreakerManager is_tripped, can_open, status
test_volatility_detector.py ~6 VolatilityRegimeDetector is_high_regime
test_position_manager.py ~5 PositionManager state
test_smart_exec_algorithm.py ~6 SmartExecAlgorithm routing
test_signal_bridge.py ~4 SignalBridgeActor event handling
test_metrics_monitor.py ~4 MetricsMonitor state

Run all:

source /home/dolphin/siloqy_env/bin/activate
cd /mnt/dolphinng5_predict
python -m pytest nautilus_dolphin/tests/ -v

Run DolphinActor tests only:

python -m pytest nautilus_dolphin/tests/test_dolphin_actor.py -v  # 35/35

15. Deployment Procedures

15.1 siloqy-env Activation

All production and test commands must run in siloqy-env:

source /home/dolphin/siloqy_env/bin/activate
# Verify: python -c "import nautilus_trader; print(nautilus_trader.__version__)"
# Expected: 1.219.0

15.2 Daily Paper Trade (Manual)

source /home/dolphin/siloqy_env/bin/activate
cd /mnt/dolphinng5_predict
PREFECT_API_URL=http://localhost:4200/api \
python prod/paper_trade_flow.py --config prod/configs/blue.yml --date 2026-03-21

15.3 Nautilus BacktestEngine Run (Manual)

source /home/dolphin/siloqy_env/bin/activate
cd /mnt/dolphinng5_predict
python prod/run_nautilus.py --config prod/configs/blue.yml

15.4 Nautilus Prefect Flow (Manual)

source /home/dolphin/siloqy_env/bin/activate
cd /mnt/dolphinng5_predict
PREFECT_API_URL=http://localhost:4200/api \
python prod/nautilus_prefect_flow.py --date 2026-03-21

15.5 Dry Run (Data + Param Validation Only)

python prod/nautilus_prefect_flow.py --date 2026-03-21 --dry-run

15.6 Register Prefect Deployments

PREFECT_API_URL=http://localhost:4200/api \
python prod/paper_trade_flow.py --register       # dolphin-paper-blue, 00:05 UTC

PREFECT_API_URL=http://localhost:4200/api \
python prod/nautilus_prefect_flow.py --register  # dolphin-nautilus-blue, 00:10 UTC

15.7 Prefect Worker

source /home/dolphin/siloqy_env/bin/activate
PREFECT_API_URL=http://localhost:4200/api \
prefect worker start --pool dolphin --type process

16. HZ Sharded Feature Store

Map pattern: DOLPHIN_FEATURES_SHARD_{shard_idx} Shard count: 10 Routing:

shard_idx = sum(ord(c) for c in symbol) % SHARD_COUNT
imap_name = f"DOLPHIN_FEATURES_SHARD_{shard_idx:02d}"

The OBF flow writes per-asset OB features to the correct shard. HZOBProvider uses dynamic discovery (reads key_set from all 10 shards at startup) to find which assets are present.


17. Operational Invariants

  1. Champion param hash must match at every flow start. _CHAMPION_HASH = "..." computed from _CHAMPION_PARAMS dict. Mismatch → ValueError → flow abort.

  2. Seed=42 is mandatory for reproducibility. numba RNG uses Numba's internal PRNG initialized from seed. NumPy RandomState(42) used in NDAlphaEngine. Any change to seed invalidates backtest comparison.

  3. HIBERNATE is hard — deliberately tight (Rm < 0.50). When posture=HIBERNATE, on_bar() returns immediately, no exceptions, no logging above WARNING.

  4. Stale-state events are logged but not fatal. _stale_state_events counter increments; result dict gets stale_state=True. The trade result is written to HZ with a DO-NOT-USE flag in the log. Downstream systems must check this field.

  5. HZ unavailability is non-fatal. If HZ is unreachable at on_start, hz_client=None, posture defaults to APEX. Flow continues with local state only. The hz_probe_task retries 3× before giving up with a warning (not an error).

  6. Capital continuity. Each flow run restores capital from DOLPHIN_STATE_BLUE["latest_nautilus"]. If absent, falls back to initial_capital from config (25,000 USDT).

  7. Date boundary is ts_event-driven. The Nautilus bar's ts_event nanoseconds are the authoritative source of truth for date detection. Wall clock is not used.


18. Known Limitations and Future Work

Item Status Notes
Live TradingNode (Binance) Pending launcher.py exists; requires API keys + WS data integration
0.1s (10 Hz) resolution Blocked 3 blockers: async HZ push, timeout reduction, lookback recalibration
LONG validation (green config) Pending green.yml exists; needs backtest sign-off
ML-MC Forewarner in Nautilus flow Done Wired in DolphinActor.on_start() — auto-injects for both flows; _MC_BASE_CFG frozen constant
Full end-to-end Nautilus replay parity In progress test_nd_vs_standalone_comparison.py exists; champion param parity confirmed

Spec version 1.0 — 2026-03-22 — Nautilus-DOLPHIN Alpha Engine Core