"""Tests for the OrderSimulator.""" from decimal import Decimal from shared.models import Signal, OrderSide from backtester.simulator import OrderSimulator def make_signal( symbol: str, side: OrderSide, price: str, quantity: str, strategy: str = "test", ) -> Signal: return Signal( strategy=strategy, symbol=symbol, side=side, price=Decimal(price), quantity=Decimal(quantity), reason="test", ) def test_simulator_initial_balance(): sim = OrderSimulator(Decimal("10000")) assert sim.balance == Decimal("10000") def test_simulator_buy_reduces_balance(): sim = OrderSimulator(Decimal("10000")) signal = make_signal("BTCUSDT", OrderSide.BUY, "50000", "0.1") result = sim.execute(signal) assert result is True assert sim.balance == Decimal("5000") assert sim.positions["BTCUSDT"] == Decimal("0.1") def test_simulator_sell_increases_balance(): sim = OrderSimulator(Decimal("10000")) buy_signal = make_signal("BTCUSDT", OrderSide.BUY, "50000", "0.1") sim.execute(buy_signal) balance_after_buy = sim.balance sell_signal = make_signal("BTCUSDT", OrderSide.SELL, "55000", "0.1") result = sim.execute(sell_signal) assert result is True assert sim.balance > balance_after_buy # Profit: sold at 55000, bought at 50000 → gain 500 assert sim.balance == Decimal("10000") - Decimal("5000") + Decimal("5500") def test_simulator_reject_buy_insufficient_balance(): sim = OrderSimulator(Decimal("100")) signal = make_signal("BTCUSDT", OrderSide.BUY, "50000", "0.1") result = sim.execute(signal) assert result is False assert sim.balance == Decimal("100") assert sim.positions.get("BTCUSDT", Decimal("0")) == Decimal("0") def test_simulator_trade_history(): sim = OrderSimulator(Decimal("10000")) signal = make_signal("BTCUSDT", OrderSide.BUY, "50000", "0.1") sim.execute(signal) assert len(sim.trades) == 1 trade = sim.trades[0] assert trade.symbol == "BTCUSDT" assert trade.side == OrderSide.BUY assert trade.price == Decimal("50000") assert trade.quantity == Decimal("0.1")