Files
DOLPHIN/prod/test_acb_wiring.py

101 lines
4.2 KiB
Python
Raw Normal View History

import sys
import os
import json
import math
import signal
from unittest.mock import MagicMock, patch
if not hasattr(signal, 'SIGHUP'):
signal.SIGHUP = 1
# Configure pathing for local test execution
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../nautilus_dolphin')))
from nautilus_dolphin.nautilus.adaptive_circuit_breaker import AdaptiveCircuitBreaker, ACBConfig
# 1. TEST ACB INTERNAL FUNCTIONING (Internal Logic Validity)
def test_acb_internal_functioning():
print("\n--- Running ACBv6 Internal Unit Tests ---")
acb = AdaptiveCircuitBreaker()
# Simulate a HZ snapshot with some bearish values
mock_snapshot = {
'funding_btc': -0.0002, # Very Bearish -> 1 signal
'dvol_btc': 85.0, # Extreme -> 1 signal
'fng': 20.0, # Extreme Fear -> 1 signal
'taker': 0.7, # Very high selling -> 1 signal
'_staleness_s': {'funding_btc': 100}
}
# Calculate boost from these factors (which should generate max signal count = 4.0)
info = acb.get_dynamic_boost_from_hz("2026-04-10", mock_snapshot, w750_velocity=0.005)
assert info['cut'] == 0.0, "ACBv6 inverse mode should never cut position"
assert info['signals'] == 4.0, f"Expected 4.0 signals, got {info['signals']}"
# Mathematical confirmation of log_0.5 inverse boost curve expectations
expected_boost = 1.0 + 0.5 * math.log1p(info['signals']) # 1.0 + 0.5 * ln(5) == 1.804
assert math.isclose(info['boost'], expected_boost, rel_tol=1e-3), (
f"Boost math failure. Expected '{expected_boost:.3f}', got '{info['boost']:.3f}'"
)
# Test w750 velocity fallback/caching
# Should be pre-cached now
assert acb._w750_vel_cache["2026-04-10"] == 0.005, "w750_velocity should be correctly stored"
print(f"ACB internal functions properly handle HZ conversion and log_0.5 boost (Yields ~{expected_boost:.3f}x leverage multiplier on 4-signal stress).")
# 2. TEST NAUTILUS EVENT TRADER WIRING (Structural Pipeline Validation)
def test_trader_acb_wiring():
print("\n--- Running DolphinLiveTrader ACB Wiring Tests ---")
# We must patch thread pools and hz client to test DolphinLiveTrader in isolation
with patch('concurrent.futures.ThreadPoolExecutor'):
with patch('prod.nautilus_event_trader.create_d_liq_engine'):
# Mock the Linux-only exit handler module so it imports locally on Windows
mock_exit = MagicMock()
sys.modules['dolphin_exit_handler'] = mock_exit
import prod.nautilus_event_trader as net
# Instantiate trader
trader = net.DolphinLiveTrader()
# Setup mock engine
trader.eng = MagicMock()
trader.current_day = "2026-04-10"
trader.eng_lock = MagicMock()
trader.acb = MagicMock()
# Trigger exF listener manually
mock_exf_snapshot = json.dumps({'dvol_btc': 55.0, 'taker': 0.8})
class MockEvent:
def __init__(self, val): self.value = val
trader.last_w750_vel = 0.001
trader.on_exf_update(MockEvent(mock_exf_snapshot))
# Ensure acb.get_dynamic_boost_from_hz was called with parameters
trader.acb.get_dynamic_boost_from_hz.assert_called_once_with(
date_str="2026-04-10",
exf_snapshot={'dvol_btc': 55.0, 'taker': 0.8},
w750_velocity=0.001
)
# Ensure engine.update_acb_boost was called
if hasattr(trader.eng, 'update_acb_boost'):
trader.eng.update_acb_boost.assert_called_once()
print("ACB pipeline successfully routes live EXF data into the engine loop.")
if __name__ == "__main__":
try:
test_acb_internal_functioning()
test_trader_acb_wiring()
print("\nALL UNIT TESTS PASSED SUCCESSFULLY! ACBv6 is securely wired.")
except AssertionError as e:
print(f"FAILED: {e}")
except Exception as e:
print(f"ERROR: {e}")