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.
This commit is contained in:
hjnormey
2026-04-21 16:58:38 +02:00
commit 01c19662cb
643 changed files with 260241 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
"""Tests for SignalBridgeActor.
Uses TestClock pattern from Nautilus to properly initialize Actor components.
"""
import pytest
from unittest.mock import Mock, patch, PropertyMock
from nautilus_dolphin.nautilus.signal_bridge import SignalBridgeActor, SignalBridgeConfig
class TestSignalBridgeTimestampParsing:
"""Test timestamp parsing without full Nautilus initialization."""
def test_parse_timestamp_ns_from_seconds(self):
"""Test timestamp conversion from seconds."""
config = SignalBridgeConfig(redis_url='redis://localhost')
actor = SignalBridgeActor(config)
ts_sec = 1234567890
ts_ns = actor._parse_timestamp_ns(ts_sec)
assert ts_ns == 1234567890 * 1_000_000_000
def test_parse_timestamp_ns_from_milliseconds(self):
"""Test timestamp conversion from milliseconds."""
config = SignalBridgeConfig(redis_url='redis://localhost')
actor = SignalBridgeActor(config)
ts_ms = 1234567890123
ts_ns = actor._parse_timestamp_ns(ts_ms)
assert ts_ns == 1234567890123 * 1_000
def test_parse_timestamp_ns_from_nanoseconds(self):
"""Test timestamp already in nanoseconds."""
config = SignalBridgeConfig(redis_url='redis://localhost')
actor = SignalBridgeActor(config)
ts_ns = 1234567890123456789
result = actor._parse_timestamp_ns(ts_ns)
assert result == ts_ns
class TestSignalBridgeWithNautilus:
"""Test SignalBridgeActor with proper Nautilus initialization."""
@pytest.fixture
def nautilus_actor(self):
"""Create a properly initialized SignalBridgeActor with mocked clock."""
from nautilus_trader.common.component import TestClock
config = SignalBridgeConfig(
redis_url='redis://localhost',
max_signal_age_sec=10
)
actor = SignalBridgeActor(config)
# Create TestClock and patch the clock property
clock = TestClock()
# Use patch to mock the clock property
with patch.object(
type(actor),
'clock',
new_callable=PropertyMock
) as mock_clock:
mock_clock.return_value = clock
yield actor, clock
def test_validate_signal_missing_fields(self, nautilus_actor):
"""Test signal validation rejects missing fields."""
actor, clock = nautilus_actor
signal = {'timestamp': 1234567890, 'asset': 'BTCUSDT'}
assert not actor._validate_signal(signal)
def test_validate_signal_valid(self, nautilus_actor):
"""Test signal validation accepts valid signal."""
actor, clock = nautilus_actor
# Set clock to be after signal timestamp
clock.set_time(1234567890 * 1_000_000_000 + 5_000_000_000)
signal = {
'timestamp': 1234567890,
'asset': 'BTCUSDT',
'direction': 'SHORT',
'vel_div': -0.025,
'strength': 0.75
}
assert actor._validate_signal(signal)
def test_validate_signal_stale(self, nautilus_actor):
"""Test signal validation rejects stale signals."""
actor, clock = nautilus_actor
# Set clock to be much later than signal (older than max_signal_age_sec)
clock.set_time(1234567890 * 1_000_000_000 + 20_000_000_000) # 20s later
signal = {
'timestamp': 1234567890,
'asset': 'BTCUSDT',
'direction': 'SHORT',
'vel_div': -0.025,
'strength': 0.75
}
assert not actor._validate_signal(signal)
def test_validate_signal_future(self, nautilus_actor):
"""Test signal validation rejects future signals."""
actor, clock = nautilus_actor
# Set clock to be before signal timestamp
clock.set_time(1234567890 * 1_000_000_000 - 1_000_000_000)
signal = {
'timestamp': 1234567890,
'asset': 'BTCUSDT',
'direction': 'SHORT',
'vel_div': -0.025,
'strength': 0.75
}
assert not actor._validate_signal(signal)
class TestSignalBridgeConfig:
"""Test SignalBridgeConfig initialization."""
def test_default_config(self):
"""Test default configuration values."""
config = SignalBridgeConfig()
assert config.redis_url == "redis://localhost:6379"
assert config.stream_key == "dolphin:signals:stream"
assert config.max_signal_age_sec == 10
def test_custom_config(self):
"""Test custom configuration values."""
config = SignalBridgeConfig(
redis_url="redis://custom:6380",
stream_key="custom:stream",
max_signal_age_sec=30
)
assert config.redis_url == "redis://custom:6380"
assert config.stream_key == "custom:stream"
assert config.max_signal_age_sec == 30