Files
DOLPHIN/prod/stress_extreme.py

120 lines
4.3 KiB
Python
Raw Normal View History

import os
import sys
import time
import json
import random
import unittest
import numpy as np
from pathlib import Path
from unittest.mock import MagicMock
# Correct sys.path
ROOT_DIR = Path(__file__).parent.parent
sys.path.insert(0, str(ROOT_DIR / "nautilus_dolphin"))
sys.path.insert(0, str(ROOT_DIR))
from nautilus_dolphin.nautilus.ob_features import OBFeatureEngine, NEUTRAL_PLACEMENT
from nautilus_dolphin.nautilus.ob_provider import OBSnapshot
# Mock memory monitor
try:
import psutil
_HAS_PSUTIL = True
except ImportError:
_HAS_PSUTIL = False
class FastMockProvider:
def __init__(self):
self.snap = None
def get_snapshot(self, asset, ts):
return self.snap
def get_assets(self):
return ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "XRPUSDT"]
class ExtremeStressTester:
def __init__(self, iterations=180000, fuzz_rate=0.05):
self.iterations = iterations
self.fuzz_rate = fuzz_rate
self.assets = ["BTCUSDT", "ETHUSDT", "SOLUSDT", "BNBUSDT", "XRPUSDT"]
self.provider = FastMockProvider()
self.engine = OBFeatureEngine(self.provider)
def create_valid_snap(self, asset):
return OBSnapshot(
timestamp=time.time(),
asset=asset,
bid_notional=np.random.rand(5) * 10000,
ask_notional=np.random.rand(5) * 10000,
bid_depth=np.random.rand(5),
ask_depth=np.random.rand(5)
)
def create_fuzzed_snap(self, asset):
# Return various 'bad' flavors
choice = random.choice(["NONE", "EMPTY_LISTS", "NAN_VALS", "WRONG_TYPE"])
if choice == "NONE":
return None
if choice == "EMPTY_LISTS":
return OBSnapshot(time.time(), asset, np.array([]), np.array([]), np.array([]), np.array([]))
if choice == "NAN_VALS":
return OBSnapshot(time.time(), asset, np.array([np.nan]*5), np.array([np.nan]*5), np.array([0.0]*5), np.array([0.0]*5))
if choice == "WRONG_TYPE":
# Test shape mismatch or zeroing
return OBSnapshot(time.time(), asset, np.array([1.0, 2.0]), np.array([1.0]), np.array([0]), np.array([0]))
return None
def run(self):
# 180,000 iterations = 30 minutes of 100Hz
self.iterations = 180000
print(f"STARTING EXTREME STRESS: {self.iterations} iterations, {self.fuzz_rate*100}% fuzz rate")
process = psutil.Process(os.getpid()) if _HAS_PSUTIL else None
mem_start = process.memory_info().rss / (1024*1024) if process else 0
start_time = time.time()
fuzz_counts = 0
success_counts = 0
for i in range(self.iterations):
for asset in self.assets:
if random.random() < self.fuzz_rate:
snap = self.create_fuzzed_snap(asset)
fuzz_counts += 1
else:
snap = self.create_valid_snap(asset)
self.provider.snap = snap
try:
self.engine.step_live(self.assets, i)
success_counts += 1
except Exception as e:
# Malformed data might trigger errors in kernels if not jitted with guards
# but we handle it gracefully
fuzz_counts += 1
if i % 20000 == 0 and i > 0:
mem_now = process.memory_info().rss / (1024*1024) if process else 0
print(f" - Progress: {i}/{self.iterations} | Mem: {mem_now:.2f}MB | Fuzz: {fuzz_counts}")
end_time = time.time()
duration = end_time - start_time
mem_end = process.memory_info().rss / (1024*1024) if process else 0
print("\n" + "="*60)
print("EXTREME STRESS COMPLETED SUCCESSFULY")
print(f"Duration: {duration:.2f}s (~{self.iterations/duration:.2f} Hz)")
print(f"Fuzz Events Handled: {fuzz_counts}")
print(f"Final Memory Delta: {mem_end - mem_start:.2f}MB")
print("="*60)
if mem_end - mem_start > 500: # 500MB allowance for long run + buffers
print("CRITICAL: Significant memory leak detected.")
sys.exit(2)
sys.exit(0)
if __name__ == "__main__":
tester = ExtremeStressTester(iterations=100000, fuzz_rate=0.10)
tester.run()