#!/usr/bin/env python3 """ Dolphin Live Node — DolphinActor inside NT TradingNode ======================================================= Phase 1: paper_trading=True (live Binance Futures data, paper fills). Validates signal parity with nautilus_event_trader.py before live exec. To go live (Phase 2): set paper_trading=False in build_node(). """ import os import sys import asyncio from pathlib import Path PROJECT_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(PROJECT_ROOT / 'nautilus_dolphin')) sys.path.insert(0, str(PROJECT_ROOT / 'prod')) sys.path.insert(0, str(PROJECT_ROOT)) from dotenv import load_dotenv load_dotenv(PROJECT_ROOT / '.env') from nautilus_trader.live.node import TradingNode from nautilus_trader.config import TradingNodeConfig, LiveDataEngineConfig, CacheConfig from nautilus_trader.adapters.binance.config import BinanceDataClientConfig from nautilus_trader.adapters.binance.common.enums import BinanceAccountType from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory from nautilus_trader.model.identifiers import TraderId # --------------------------------------------------------------------------- # Universe — 50 OBF assets. Subscribed for live quote cache (order sizing). # Must cover the full eigen universe so _exec_submit_entry finds live quotes. # --------------------------------------------------------------------------- LIVE_ASSETS = [ "BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "XRPUSDT", "ADAUSDT", "DOGEUSDT", "TRXUSDT", "DOTUSDT", "MATICUSDT", "LTCUSDT", "AVAXUSDT", "LINKUSDT", "UNIUSDT", "ATOMUSDT", "ETCUSDT", "XLMUSDT", "BCHUSDT", "NEARUSDT", "ALGOUSDT", "VETUSDT", "FILUSDT", "APTUSDT", "OPUSDT", "ARBUSDT", "INJUSDT", "SUIUSDT", "SEIUSDT", "TIAUSDT", "ORDIUSDT", "WLDUSDT", "FETUSDT", "AGIXUSDT", "RENDERUSDT", "IOTAUSDT", "AAVEUSDT", "SNXUSDT", "CRVUSDT", "COMPUSDT", "MKRUSDT", "ENJUSDT", "MANAUSDT", "SANDUSDT", "AXSUSDT", "GALAUSDT", "ZECUSDT", "DASHUSDT", "XMRUSDT", "NEOUSDT", "QTUMUSDT", ] # --------------------------------------------------------------------------- # DolphinActor config — gold-standard params, must match nautilus_event_trader # --------------------------------------------------------------------------- DOLPHIN_CONFIG = { 'live_mode': True, 'venue': 'BINANCE', 'direction': 'short_only', 'hazelcast': { 'host': '127.0.0.1:5701', 'cluster': 'dolphin', 'state_map': 'DOLPHIN_STATE_GREEN', 'imap_pnl': 'DOLPHIN_PNL_GREEN', }, 'paper_trade': {'initial_capital': 25000.0}, 'assets': LIVE_ASSETS, 'engine': { 'boost_mode': 'd_liq', # Signal 'vel_div_threshold': -0.020, 'vel_div_extreme': -0.050, # Leverage — gold spec: 8x soft / 9x hard 'min_leverage': 0.5, 'max_leverage': 8.0, 'abs_max_leverage': 9.0, 'leverage_convexity': 3.0, 'fraction': 0.20, # Exits — gold spec: 250 bars max hold 'fixed_tp_pct': 0.0095, 'stop_pct': 1.0, 'max_hold_bars': 250, # Direction confirm '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, # Asset selection — gold spec: IRP filter disabled in live 'use_asset_selection': True, 'min_irp_alignment': 0.0, # Fees / slippage 'use_sp_fees': True, 'use_sp_slippage': True, 'sp_maker_entry_rate': 0.62, 'sp_maker_exit_rate': 0.50, # OB edge 'use_ob_edge': True, 'ob_edge_bps': 5.0, 'ob_confirm_rate': 0.40, 'ob_imbalance_bias': -0.09, 'ob_depth_scale': 1.0, # Alpha layers 'lookback': 100, 'use_alpha_layers': True, 'use_dynamic_leverage': True, 'seed': 42, # V7 RT exit engine (GREEN only) 'use_exit_v7': True, 'use_exit_v6': False, 'v6_bar_duration_sec': 5.0, 'bounce_model_path': str(PROJECT_ROOT / 'prod' / 'models' / 'bounce_detector_v3.pkl'), }, 'strategy_name': 'green', 'vol_p60': 0.00009868, } def build_node() -> TradingNode: api_key = os.environ['BINANCE_API_KEY'] api_secret = os.environ['BINANCE_API_SECRET'] data_cfg = BinanceDataClientConfig( account_type=BinanceAccountType.USDT_FUTURES, api_key=api_key, api_secret=api_secret, testnet=False, ) # Phase 1: data-only node (no exec client). # DolphinActor processes live bar data → engine step_bar() → CH trade_events. # NT order submission is gracefully skipped (instrument guard in _exec_submit_entry). # NDAlphaEngine internal P&L tracking is authoritative for Phase 1 validation. from nautilus_dolphin.nautilus.dolphin_actor import DolphinActor actor = DolphinActor(config=DOLPHIN_CONFIG) node_config = TradingNodeConfig( trader_id=TraderId("DOLPHIN-LIVE-001"), data_clients={"BINANCE": data_cfg}, data_engine=LiveDataEngineConfig(time_bars_build_with_no_updates=False), cache=CacheConfig(database=None), ) node = TradingNode(config=node_config) node.add_data_client_factory("BINANCE", BinanceLiveDataClientFactory) node.trader.add_strategy(actor) node.build() return node async def run() -> None: node = build_node() await node.run_async() if __name__ == "__main__": asyncio.run(run())