1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
"""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")
|