Add risk management features: implement loss limits, trade limits, and pre-trade validation; update settings and tests
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime, timedelta
|
||||
|
||||
import pytest
|
||||
|
||||
from arbitrade.risk.loss_limits import LossLimitGuard
|
||||
|
||||
|
||||
def test_loss_limit_guard_tracks_daily_and_cumulative_pnl() -> None:
|
||||
guard = LossLimitGuard(daily_loss_limit=100.0, cumulative_loss_limit=200.0)
|
||||
t0 = datetime.now(UTC)
|
||||
|
||||
guard.register_realized_pnl(-40.0, at=t0)
|
||||
guard.register_realized_pnl(10.0, at=t0)
|
||||
|
||||
assert guard.cumulative_pnl == -30.0
|
||||
assert guard.daily_pnl(t0.date()) == -30.0
|
||||
assert not guard.is_halted
|
||||
|
||||
|
||||
def test_loss_limit_guard_halts_on_daily_limit() -> None:
|
||||
guard = LossLimitGuard(daily_loss_limit=50.0)
|
||||
t0 = datetime.now(UTC)
|
||||
|
||||
guard.register_realized_pnl(-30.0, at=t0)
|
||||
guard.register_realized_pnl(-25.0, at=t0)
|
||||
|
||||
assert guard.is_halted
|
||||
assert guard.halted_reason == "daily_loss_limit_breached"
|
||||
|
||||
|
||||
def test_loss_limit_guard_halts_on_cumulative_limit_across_days() -> None:
|
||||
guard = LossLimitGuard(cumulative_loss_limit=60.0)
|
||||
t0 = datetime.now(UTC)
|
||||
|
||||
guard.register_realized_pnl(-40.0, at=t0)
|
||||
guard.register_realized_pnl(-25.0, at=t0 + timedelta(days=1))
|
||||
|
||||
assert guard.is_halted
|
||||
assert guard.halted_reason == "cumulative_loss_limit_breached"
|
||||
|
||||
|
||||
def test_loss_limit_guard_rejects_invalid_limits() -> None:
|
||||
with pytest.raises(ValueError, match="daily_loss_limit"):
|
||||
LossLimitGuard(daily_loss_limit=0.0)
|
||||
|
||||
with pytest.raises(ValueError, match="cumulative_loss_limit"):
|
||||
LossLimitGuard(cumulative_loss_limit=-1.0)
|
||||
Reference in New Issue
Block a user