136 lines
4.3 KiB
Python
136 lines
4.3 KiB
Python
|
|
#!/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())
|