portfolio-engine / tests /test_risk_monitor.py
engineportf's picture
Initial Deployment from Local Engine
208fbf8 verified
Raw
History Blame Contribute Delete
1.67 kB
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