#!/usr/bin/env python3 """ DOLPHIN Paper Trading - High Performance Binance Feed ====================================================== Uses Nautilus Rust-backed Binance adapter for maximum performance. Benefits over Hazelcast: - Lower latency (~1-5ms vs ~5-10ms) - Higher throughput (native Rust WebSocket) - Direct market data (no intermediate layer) - Zero-copy message passing """ import asyncio import os import sys import logging from pathlib import Path from dotenv import load_dotenv # Add project root 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') # Configure Logging logging.basicConfig(level=logging.INFO) logger = logging.getLogger("PaperPortfolio-Binance") # --------------------------------------------------------------------------- # HIGH-PERFORMANCE BINANCE CONFIGURATION # --------------------------------------------------------------------------- # Symbols to trade (top liquid futures) SYMBOLS = [ "BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "ADAUSDT", ] async def launch(): logger.info("=" * 60) logger.info("DOLPHIN Paper Trading (Binance Rust Feed)") logger.info("=" * 60) logger.info(f"Venue: BINANCE_FUTURES") logger.info(f"Data Feed: WebSocket (Rust-backed)") logger.info(f"Latency Target: ~1-5ms") logger.info(f"Symbols: {len(SYMBOLS)}") logger.info("=" * 60) try: from nautilus_trader.config import TradingNodeConfig, ImportableStrategyConfig from nautilus_trader.live.node import TradingNode from nautilus_trader.model.identifiers import TraderId from nautilus_trader.adapters.binance.config import BinanceDataClientConfig, BinanceExecClientConfig from nautilus_trader.adapters.binance.common.enums import BinanceAccountType from nautilus_trader.adapters.binance.factories import BinanceLiveDataClientFactory, BinanceLiveExecClientFactory # Get API credentials api_key = os.getenv('BINANCE_API_KEY') or os.getenv('MRS_BINANCE_API_KEY') api_secret = os.getenv('BINANCE_API_SECRET') or os.getenv('MRS_BINANCE_SECRET_KEY') if not api_key or not api_secret: logger.error("API credentials not found in environment!") logger.error("Set BINANCE_API_KEY and BINANCE_API_SECRET") return logger.info(f"[OK] API credentials loaded: {api_key[:10]}...") # Configure HIGH-PERFORMANCE Binance data client # Uses Rust-backed WebSocket for maximum throughput data_client_config = BinanceDataClientConfig( account_type=BinanceAccountType.FUTURES, testnet=False, # Use mainnet for real data api_key=api_key, api_secret=api_secret, # Performance settings use_adjusted_prices=True, log_wiring=True, ) # Configure execution client (paper trading) exec_client_config = BinanceExecClientConfig( account_type=BinanceAccountType.FUTURES, testnet=False, api_key=api_key, api_secret=api_secret, paper_trading=True, # Paper trading mode ) logger.info("[OK] Binance clients configured") # Import and configure DolphinActor from nautilus_dolphin.nautilus.dolphin_actor import DolphinActor strategy_config_dict = { 'venue': 'BINANCE_FUTURES', 'engine': { 'boost_mode': 'd_liq', 'max_leverage': 5.0, 'capital_fraction': 0.20, }, 'paper_trade': { 'initial_capital': 25000.0, 'data_source': 'binance_websocket', }, 'hazelcast': { 'imap_state': 'DOLPHIN_STATE_BLUE', 'imap_pnl': 'DOLPHIN_PNL_BLUE', }, # Subscribe to symbols 'symbols': SYMBOLS, } strategy_config = ImportableStrategyConfig( strategy_path='nautilus_dolphin.nautilus.dolphin_actor:DolphinActor', config_path='nautilus_dolphin.nautilus.dolphin_actor:DolphinActor', config=strategy_config_dict ) # Create TradingNode config with HIGH-PERFORMANCE adapters trader_id = TraderId("DOLPHIN-BINANCE-01") node_config = TradingNodeConfig( trader_id=trader_id, strategies=[strategy_config], # Rust-backed Binance adapters data_clients={"BINANCE": data_client_config}, exec_clients={"BINANCE": exec_client_config}, # Performance tuning cache={"database": None, "encoding": "msgpack"}, message_bus={"encoding": "msgpack"}, ) logger.info("[OK] TradingNodeConfig created") # Create and build TradingNode node = TradingNode(config=node_config) # Register client factories (required for live adapters) node.add_data_client_factory("BINANCE", BinanceLiveDataClientFactory) node.add_exec_client_factory("BINANCE", BinanceLiveExecClientFactory) node.build() logger.info("[OK] TradingNode built with Rust adapters") # Start the node logger.info("[OK] Starting trading node...") await node.start() logger.info("=" * 60) logger.info("🚀 PAPER TRADER RUNNING - Rust WebSocket Feed") logger.info("=" * 60) logger.info("Press Ctrl+C to stop") # Keep running 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())