Files
DOLPHIN/prod/clean_arch/main.py
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

137 lines
4.8 KiB
Python
Executable File

#!/usr/bin/env python3
"""
CLEAN ARCHITECTURE - DOLPHIN PAPER TRADER
==========================================
🙏 God bless clean code and synchronized data 🙏
Architecture:
┌──────────────────────────────────────────────┐
│ CORE: TradingEngine (pure Python) │
│ - Business logic only │
│ - No external dependencies │
│ - Ready for Rust rewrite │
└──────────────────┬───────────────────────────┘
│ uses PORT
┌──────────────────────────────────────────────┐
│ PORT: DataFeedPort (interface) │
│ - Abstract interface │
│ - Easy to swap implementations │
└──────────────────┬───────────────────────────┘
│ implemented by
┌──────────────────────────────────────────────┐
│ ADAPTER: HazelcastDataFeed │
│ - Current implementation │
│ - Single source: DolphinNG6 → Hazelcast │
│ - No sync issues │
└──────────────────────────────────────────────┘
Evolution Path:
Phase 1 (NOW): HazelcastDataFeed (this file)
Phase 2: BinanceWebsocketFeed (direct connection)
Phase 3: RustKernelFeed (in-kernel, zero-copy)
Usage:
python clean_arch/main.py
"""
import asyncio
import sys
import logging
from pathlib import Path
# Setup paths
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT / 'nautilus_dolphin'))
sys.path.insert(0, str(PROJECT_ROOT))
sys.path.insert(0, str(Path(__file__).parent))
# Logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger("DOLPHIN-CLEAN-ARCH")
# Import clean architecture components
from adapters.hazelcast_feed import HazelcastDataFeed
from core.trading_engine import TradingEngine
# =============================================================================
# CONFIGURATION
# =============================================================================
CONFIG = {
'trader_id': 'DOLPHIN-CLEAN-01',
'venue': 'BINANCE_FUTURES',
# Hazelcast configuration (current adapter)
'hazelcast': {
'cluster': 'dolphin',
'host': 'localhost:5701',
},
# Trading parameters
'initial_capital': 25000.0,
'max_leverage': 5.0,
'capital_fraction': 0.20,
'min_irp_alignment': 0.45,
'vel_div_threshold': -0.02,
}
async def main():
"""
Main entry point - wires clean architecture together.
"""
logger.info("=" * 70)
logger.info("🐬 DOLPHIN CLEAN ARCHITECTURE")
logger.info("=" * 70)
logger.info(f"Trader ID: {CONFIG['trader_id']}")
logger.info(f"Venue: {CONFIG['venue']}")
logger.info(f"Data Feed: Hazelcast (DolphinNG6)")
logger.info(f"Architecture: Clean / Hexagonal")
logger.info(f"Evolution Ready: Yes (in-kernel future)")
logger.info("=" * 70)
# =================================================================
# WIRE COMPONENTS
# =================================================================
# 1. Create Data Feed Adapter (ADAPTER layer)
# - Currently: Hazelcast
# - Future: Can swap to BinanceWebsocket or RustKernel
logger.info("[1/3] Creating data feed adapter...")
data_feed = HazelcastDataFeed(CONFIG)
logger.info(" ✓ Hazelcast adapter created")
# 2. Create Trading Engine (CORE layer)
# - Pure business logic
# - No knowledge of Hazelcast
# - Works with ANY DataFeedPort implementation
logger.info("[2/3] Creating trading engine...")
engine = TradingEngine(data_feed, CONFIG)
logger.info(" ✓ Trading engine created")
logger.info(" ✓ Core is adapter-agnostic")
# 3. Start system
logger.info("[3/3] Starting system...")
logger.info("=" * 70)
try:
await engine.start()
except KeyboardInterrupt:
logger.info("\nShutdown requested...")
await engine.stop()
except Exception as e:
logger.error(f"Fatal error: {e}")
await engine.stop()
raise
if __name__ == "__main__":
asyncio.run(main())