From 9efb0e50d5e2d7025bbe83aaff039ba93beff520 Mon Sep 17 00:00:00 2001 From: TheSiahxyz <164138827+TheSiahxyz@users.noreply.github.com> Date: Thu, 2 Apr 2026 09:06:30 +0900 Subject: feat(risk): add portfolio exposure, correlation risk, and VaR checks --- services/order-executor/tests/test_risk_manager.py | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'services/order-executor/tests') diff --git a/services/order-executor/tests/test_risk_manager.py b/services/order-executor/tests/test_risk_manager.py index efabe73..4bd5761 100644 --- a/services/order-executor/tests/test_risk_manager.py +++ b/services/order-executor/tests/test_risk_manager.py @@ -198,3 +198,40 @@ def test_position_size_without_scaling(): base = Decimal("10000") * Decimal("0.1") assert size == base + + +# --- Portfolio exposure tests --- + + +def test_portfolio_exposure_check_passes(): + rm = RiskManager(max_position_size=Decimal("0.5"), stop_loss_pct=Decimal("5"), daily_loss_limit_pct=Decimal("10"), max_portfolio_exposure=0.8) + positions = {"BTCUSDT": Position(symbol="BTCUSDT", quantity=Decimal("0.01"), avg_entry_price=Decimal("50000"), current_price=Decimal("50000"))} + result = rm.check_portfolio_exposure(positions, Decimal("10000")) + assert result.allowed # 500/10000 = 5% < 80% + + +def test_portfolio_exposure_check_rejects(): + rm = RiskManager(max_position_size=Decimal("0.5"), stop_loss_pct=Decimal("5"), daily_loss_limit_pct=Decimal("10"), max_portfolio_exposure=0.3) + positions = {"BTCUSDT": Position(symbol="BTCUSDT", quantity=Decimal("1"), avg_entry_price=Decimal("50000"), current_price=Decimal("50000"))} + result = rm.check_portfolio_exposure(positions, Decimal("10000")) + assert not result.allowed # 50000/10000 = 500% > 30% + + +def test_correlation_calculation(): + rm = RiskManager(max_position_size=Decimal("0.5"), stop_loss_pct=Decimal("5"), daily_loss_limit_pct=Decimal("10")) + # Feed identical price histories — correlation should be ~1.0 + for i in range(20): + rm.update_price("A", Decimal(str(100 + i))) + rm.update_price("B", Decimal(str(100 + i))) + corr = rm.calculate_correlation("A", "B") + assert corr is not None + assert corr > 0.9 + + +def test_var_calculation(): + rm = RiskManager(max_position_size=Decimal("0.5"), stop_loss_pct=Decimal("5"), daily_loss_limit_pct=Decimal("10")) + for i in range(30): + rm.update_price("BTCUSDT", Decimal(str(100 + (i % 5) - 2))) + positions = {"BTCUSDT": Position(symbol="BTCUSDT", quantity=Decimal("1"), avg_entry_price=Decimal("100"), current_price=Decimal("100"))} + var = rm.calculate_portfolio_var(positions, Decimal("10000")) + assert var >= 0 # Non-negative -- cgit v1.2.3