import pytest import sys import os sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from safety import RiskMonitor from core_types import PortfolioState class MockPosition: def __init__(self, contracts, margin_requirement): self.contracts = contracts self.margin_requirement = margin_requirement def test_risk_monitor_intraday_drawdown(monkeypatch): monitor = RiskMonitor(intraday_drawdown_limit=0.05) # Track if emergency liquidation was called liquidation_called = False def mock_emergency_liquidate(state): nonlocal liquidation_called liquidation_called = True monkeypatch.setattr(monitor, 'emergency_liquidate', mock_emergency_liquidate) peak_nav = 100_000.0 # 2% drawdown (safe) tripped = monitor.check_intraday_drawdown(current_nav=98_000.0, peak_nav=peak_nav) assert not tripped assert not liquidation_called # 6% drawdown (unsafe) tripped = monitor.check_intraday_drawdown(current_nav=94_000.0, peak_nav=peak_nav) assert tripped assert liquidation_called def test_risk_monitor_margin_ratio(): monitor = RiskMonitor(margin_ratio_limit=0.80) futures_pos = [ MockPosition(contracts=5, margin_requirement=12000.0) # Total 60,000 margin ] # Cash is 100,000. Ratio = 60,000 / 100,000 = 0.60 (safe) ratio = monitor.check_margin_ratio(futures_pos, cash_balance=100_000.0) assert ratio == 0.60 # Cash drops to 70,000. Ratio = 60,000 / 70,000 = 0.857 (unsafe) ratio = monitor.check_margin_ratio(futures_pos, cash_balance=70_000.0) assert ratio > 0.80