45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
import os
|
|
import tempfile
|
|
|
|
import pytest
|
|
|
|
from aitrader.config import Settings
|
|
from aitrader.storage.models import EquitySnapshot, Trade
|
|
from aitrader.storage import db as dbm
|
|
from aitrader.trader import risk
|
|
|
|
|
|
@pytest.fixture
|
|
def settings(tmp_path):
|
|
s = Settings(starting_equity_eur=10000.0, db_path=str(tmp_path / "t.db"))
|
|
# init DB
|
|
dbm.get_engine(s.db_path)
|
|
return s
|
|
|
|
|
|
def test_blocks_non_trade(settings):
|
|
r = risk.evaluate(settings, "HOLD", 0.5, 100.0)
|
|
assert not r.allow
|
|
|
|
|
|
def test_allows_within_caps(settings):
|
|
r = risk.evaluate(settings, "BUY", 1.0, 100.0)
|
|
assert r.allow
|
|
assert r.qty_eur == settings.starting_equity_eur * settings.risk.max_position_pct
|
|
|
|
|
|
def test_blocks_below_min_order(settings):
|
|
r = risk.evaluate(settings, "BUY", 0.001, 100.0)
|
|
assert not r.allow
|
|
assert r.reason == "below_min_order"
|
|
|
|
|
|
def test_blocks_max_open_positions(settings):
|
|
with dbm.session(settings.db_path) as s:
|
|
for i in range(settings.risk.max_open_positions):
|
|
s.add(Trade(symbol=f"X{i}/EUR", side="buy", qty=1.0, entry_price=100.0, status="open"))
|
|
s.commit()
|
|
r = risk.evaluate(settings, "BUY", 1.0, 100.0)
|
|
assert not r.allow
|
|
assert r.reason == "max_open_positions"
|