#!/usr/bin/env python3 """ DOLPHIN Paper Trading with Hazelcast Data Feed =============================================== Uses DolphinNG6 Hazelcast data (5s pulse) instead of direct Binance feed. This version uses DolphinActor which reads from: - DOLPHIN_FEATURES: Latest scan data (price + eigenvalues) - DOLPHIN_SAFETY: Posture/mode data - ACB boost updates via Hazelcast listeners """ import asyncio import os import sys import logging from pathlib import Path from dotenv import load_dotenv # Add project root and package to path PROJECT_ROOT = Path(__file__).parent.parent sys.path.insert(0, str(PROJECT_ROOT / 'nautilus_dolphin')) sys.path.insert(0, str(PROJECT_ROOT)) # Load credentials load_dotenv(PROJECT_ROOT / '.env') from nautilus_trader.model.objects import Money from nautilus_trader.config import TradingNodeConfig, ImportableStrategyConfig from nautilus_trader.live.node import TradingNode from nautilus_trader.model.identifiers import TraderId # Configure Logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger("PaperPortfolio-HZ") # --------------------------------------------------------------------------- # PAPER TRADING CONFIGURATION (Hazelcast Data Feed) # --------------------------------------------------------------------------- PAPER_CONFIG = { 'venue': 'BINANCE_FUTURES', 'environment': 'PAPER', 'trader_id': 'DOLPHIN-HZ-01', # Hazelcast connection (for data feed) 'hazelcast': { 'cluster_name': 'dolphin', 'host': 'localhost:5701', }, # Strategy config for DolphinActor 'strategy': { 'venue': 'BINANCE_FUTURES', 'engine': { 'boost_mode': 'd_liq', # GOLD engine 'max_leverage': 5.0, 'capital_fraction': 0.20, }, 'paper_trade': { 'initial_capital': 25000.0, 'data_source': 'hazelcast', # Read from HZ instead of Binance }, 'hazelcast': { 'imap_state': 'DOLPHIN_STATE_BLUE', 'imap_pnl': 'DOLPHIN_PNL_BLUE', } }, 'execution': { 'testnet': False, 'use_sandbox': True, # Paper trading 'account_type': 'FUTURES_USDT', }, } async def launch(): logger.info("=" * 60) logger.info("DOLPHIN Paper Trading (Hazelcast Data Feed)") logger.info("=" * 60) logger.info(f"Trader ID: {PAPER_CONFIG['trader_id']}") logger.info(f"Venue: {PAPER_CONFIG['venue']}") logger.info(f"Data Source: Hazelcast (DolphinNG6)") logger.info(f"Pulse: 5s") logger.info("=" * 60) try: # Import DolphinActor from nautilus_dolphin.nautilus.dolphin_actor import DolphinActor logger.info("[OK] DolphinActor imported") # Create strategy config for DolphinActor strategy_config = ImportableStrategyConfig( strategy_path='nautilus_dolphin.nautilus.dolphin_actor:DolphinActor', config_path='nautilus_dolphin.nautilus.dolphin_actor:DolphinActor', config=PAPER_CONFIG['strategy'] ) # Create TradingNode config trader_id = TraderId(PAPER_CONFIG['trader_id']) node_config = TradingNodeConfig( trader_id=trader_id, strategies=[strategy_config], # No data_clients needed - DolphinActor reads from Hazelcast directly exec_clients={}, # Paper trading - sandbox mode ) logger.info("[OK] TradingNodeConfig created") # Create and build TradingNode node = TradingNode(config=node_config) node.build() logger.info("[OK] TradingNode built") # Start the node logger.info("[OK] Starting trading node...") await node.start() # Keep running logger.info("[OK] Paper trader RUNNING - Reading from Hazelcast") logger.info("Press Ctrl+C to stop") # Run until interrupted while True: await asyncio.sleep(1) except KeyboardInterrupt: logger.info("Stopping portfolio...") if 'node' in locals(): await node.stop() except Exception as e: logger.error(f"Failed to launch: {e}") import traceback traceback.print_exc() if __name__ == "__main__": asyncio.run(launch())