258 lines
8.1 KiB
Python
258 lines
8.1 KiB
Python
|
|
"""
|
||
|
|
Test 0: Nautilus Bootstrap - Sine Qua Non
|
||
|
|
=========================================
|
||
|
|
|
||
|
|
This test MUST pass before any other Nautilus-Dolphin tests.
|
||
|
|
It verifies that:
|
||
|
|
1. Nautilus Trader is installed and functional
|
||
|
|
2. Basic Nautilus components can be imported
|
||
|
|
3. All N-Dolphin Nautilus-dependent components can be imported
|
||
|
|
|
||
|
|
This is the foundation test - if this fails, nothing else will work.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import pytest
|
||
|
|
import sys
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_trader_installed():
|
||
|
|
"""
|
||
|
|
Test 0.0: Verify Nautilus Trader is installed.
|
||
|
|
|
||
|
|
This is the most basic check - can we import Nautilus?
|
||
|
|
"""
|
||
|
|
try:
|
||
|
|
import nautilus_trader
|
||
|
|
from nautilus_trader.common.component import LiveClock, Logger
|
||
|
|
from nautilus_trader.common import Environment
|
||
|
|
from nautilus_trader.system.kernel import NautilusKernel
|
||
|
|
from nautilus_trader.system.config import NautilusKernelConfig
|
||
|
|
from nautilus_trader.model.identifiers import TraderId
|
||
|
|
from nautilus_trader.core.uuid import UUID4
|
||
|
|
print("[Test 0.0] Nautilus Trader imports: SUCCESS")
|
||
|
|
print(f"[Test 0.0] Nautilus Trader version: {nautilus_trader.__version__}")
|
||
|
|
except ImportError as e:
|
||
|
|
pytest.fail(f"Nautilus Trader not installed: {e}. Run: pip install nautilus_trader")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_basic_config():
|
||
|
|
"""
|
||
|
|
Test 0.1: Verify NautilusKernel config can be created.
|
||
|
|
"""
|
||
|
|
from nautilus_trader.common import Environment
|
||
|
|
from nautilus_trader.model.identifiers import TraderId
|
||
|
|
from nautilus_trader.system.config import NautilusKernelConfig
|
||
|
|
|
||
|
|
config = NautilusKernelConfig(
|
||
|
|
environment=Environment.BACKTEST,
|
||
|
|
trader_id=TraderId("DOLPHIN-001"),
|
||
|
|
)
|
||
|
|
|
||
|
|
assert config is not None
|
||
|
|
assert config.environment == Environment.BACKTEST
|
||
|
|
print("[Test 0.1] NautilusKernelConfig creation: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_dolphin_core_imports():
|
||
|
|
"""
|
||
|
|
Test 0.2: Import all N-Dolphin core components.
|
||
|
|
|
||
|
|
These components don't depend on Nautilus.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.circuit_breaker import CircuitBreakerManager
|
||
|
|
from nautilus_dolphin.nautilus.metrics_monitor import MetricsMonitor
|
||
|
|
from nautilus_dolphin.nautilus.adaptive_circuit_breaker import (
|
||
|
|
AdaptiveCircuitBreaker, ACBConfig, ACBPositionSizer
|
||
|
|
)
|
||
|
|
|
||
|
|
# Verify they work
|
||
|
|
acb = AdaptiveCircuitBreaker()
|
||
|
|
sizer = ACBPositionSizer()
|
||
|
|
|
||
|
|
assert acb is not None
|
||
|
|
assert sizer is not None
|
||
|
|
print("[Test 0.2] N-Dolphin core component imports: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_dolphin_strategy_import():
|
||
|
|
"""
|
||
|
|
Test 0.3: Import DolphinExecutionStrategy class.
|
||
|
|
|
||
|
|
Note: Instantiation requires Nautilus StrategyConfig.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.strategy import DolphinExecutionStrategy
|
||
|
|
|
||
|
|
assert DolphinExecutionStrategy is not None
|
||
|
|
print("[Test 0.3] DolphinExecutionStrategy import: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_dolphin_signal_bridge_import():
|
||
|
|
"""
|
||
|
|
Test 0.4: Import SignalBridgeActor class.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.signal_bridge import SignalBridgeActor
|
||
|
|
|
||
|
|
assert SignalBridgeActor is not None
|
||
|
|
print("[Test 0.4] SignalBridgeActor import: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_dolphin_exec_algorithm_import():
|
||
|
|
"""
|
||
|
|
Test 0.5: Import SmartExecAlgorithm class.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.smart_exec_algorithm import SmartExecAlgorithm
|
||
|
|
|
||
|
|
assert SmartExecAlgorithm is not None
|
||
|
|
print("[Test 0.5] SmartExecAlgorithm import: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_nautilus_dolphin_other_imports():
|
||
|
|
"""
|
||
|
|
Test 0.6: Import remaining Nautilus-dependent components.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.position_manager import PositionManager
|
||
|
|
from nautilus_dolphin.nautilus.volatility_detector import VolatilityRegimeDetector
|
||
|
|
from nautilus_dolphin.nautilus.data_adapter import JSONEigenvalueDataAdapter, BacktestDataLoader
|
||
|
|
|
||
|
|
print("[Test 0.6] Other Nautilus component imports: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_acb_functionality():
|
||
|
|
"""
|
||
|
|
Test 0.7: Verify ACB works independently.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.adaptive_circuit_breaker import (
|
||
|
|
AdaptiveCircuitBreaker, ACBPositionSizer
|
||
|
|
)
|
||
|
|
|
||
|
|
acb = AdaptiveCircuitBreaker()
|
||
|
|
sizer = ACBPositionSizer()
|
||
|
|
|
||
|
|
# Test cut calculation for a date
|
||
|
|
final_size, acb_info = acb.apply_cut_to_position_size(
|
||
|
|
base_size=1000.0,
|
||
|
|
date_str="2025-01-01"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Verify cut rate is valid
|
||
|
|
assert final_size >= 0
|
||
|
|
assert acb_info['cut'] in [0.0, 0.15, 0.45, 0.55, 0.75, 0.8]
|
||
|
|
|
||
|
|
# Test position sizing with ACB
|
||
|
|
sized_size, sizing_info = sizer.calculate_size(
|
||
|
|
base_size=1000.0,
|
||
|
|
date_str="2025-01-01"
|
||
|
|
)
|
||
|
|
|
||
|
|
assert sized_size >= 0
|
||
|
|
assert sized_size <= 1000.0 # Should be reduced by cut
|
||
|
|
|
||
|
|
print("[Test 0.7] ACB functionality: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_circuit_breaker_functionality():
|
||
|
|
"""
|
||
|
|
Test 0.8: Verify CircuitBreaker works independently.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.circuit_breaker import CircuitBreakerManager
|
||
|
|
|
||
|
|
cb = CircuitBreakerManager()
|
||
|
|
|
||
|
|
# Test basic functionality
|
||
|
|
assert not cb.is_tripped() # Should not be tripped initially
|
||
|
|
|
||
|
|
# Test position opening (returns tuple[bool, str])
|
||
|
|
can_open, reason = cb.can_open_position(
|
||
|
|
asset="BTCUSDT",
|
||
|
|
current_balance=10000.0
|
||
|
|
)
|
||
|
|
assert isinstance(can_open, bool)
|
||
|
|
assert isinstance(reason, str)
|
||
|
|
|
||
|
|
# Test status
|
||
|
|
status = cb.get_status()
|
||
|
|
assert 'is_tripped' in status
|
||
|
|
assert 'active_positions' in status
|
||
|
|
|
||
|
|
print("[Test 0.8] CircuitBreaker functionality: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_launcher_import():
|
||
|
|
"""
|
||
|
|
Test 0.9: Verify launcher is importable.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin.nautilus.launcher import NautilusDolphinLauncher
|
||
|
|
|
||
|
|
assert NautilusDolphinLauncher is not None
|
||
|
|
print("[Test 0.9] Launcher import: SUCCESS")
|
||
|
|
|
||
|
|
|
||
|
|
def test_full_import_chain():
|
||
|
|
"""
|
||
|
|
Test 0.10: Full import chain - all components from top-level.
|
||
|
|
"""
|
||
|
|
from nautilus_dolphin import (
|
||
|
|
# Core
|
||
|
|
CircuitBreakerManager,
|
||
|
|
MetricsMonitor,
|
||
|
|
AdaptiveCircuitBreaker,
|
||
|
|
ACBConfig,
|
||
|
|
ACBPositionSizer,
|
||
|
|
# Nautilus-dependent classes
|
||
|
|
SignalBridgeActor,
|
||
|
|
DolphinExecutionStrategy,
|
||
|
|
SmartExecAlgorithm,
|
||
|
|
PositionManager,
|
||
|
|
VolatilityRegimeDetector,
|
||
|
|
# Launcher
|
||
|
|
NautilusDolphinLauncher,
|
||
|
|
)
|
||
|
|
|
||
|
|
print("[Test 0.10] Full import chain: SUCCESS")
|
||
|
|
print("\n" + "=" * 80)
|
||
|
|
print("ALL TESTS PASSED - NAUTILUS-DOLPHIN SYSTEM IS BOOTABLE")
|
||
|
|
print("=" * 80)
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
print("=" * 80)
|
||
|
|
print("NAUTILUS-DOLPHIN BOOTSTRAP TEST (Test 0)")
|
||
|
|
print("=" * 80)
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Run tests in sequence
|
||
|
|
tests = [
|
||
|
|
("0.0", test_nautilus_trader_installed, "Nautilus Trader installed"),
|
||
|
|
("0.1", test_nautilus_basic_config, "Nautilus kernel config"),
|
||
|
|
("0.2", test_nautilus_dolphin_core_imports, "Core component imports"),
|
||
|
|
("0.3", test_nautilus_dolphin_strategy_import, "Strategy import"),
|
||
|
|
("0.4", test_nautilus_dolphin_signal_bridge_import, "SignalBridge import"),
|
||
|
|
("0.5", test_nautilus_dolphin_exec_algorithm_import, "ExecAlgorithm import"),
|
||
|
|
("0.6", test_nautilus_dolphin_other_imports, "Other component imports"),
|
||
|
|
("0.7", test_acb_functionality, "ACB functionality"),
|
||
|
|
("0.8", test_circuit_breaker_functionality, "CircuitBreaker functionality"),
|
||
|
|
("0.9", test_launcher_import, "Launcher import"),
|
||
|
|
("0.10", test_full_import_chain, "Full import chain"),
|
||
|
|
]
|
||
|
|
|
||
|
|
passed = 0
|
||
|
|
failed = 0
|
||
|
|
|
||
|
|
for num, test_func, desc in tests:
|
||
|
|
try:
|
||
|
|
test_func()
|
||
|
|
print(f"[PASS] Test {num}: {desc}")
|
||
|
|
passed += 1
|
||
|
|
except Exception as e:
|
||
|
|
print(f"[FAIL] Test {num}: {desc}")
|
||
|
|
print(f" Error: {e}")
|
||
|
|
failed += 1
|
||
|
|
|
||
|
|
print()
|
||
|
|
print("=" * 80)
|
||
|
|
print(f"RESULTS: {passed} passed, {failed} failed")
|
||
|
|
print("=" * 80)
|
||
|
|
|
||
|
|
if failed > 0:
|
||
|
|
sys.exit(1)
|