summaryrefslogtreecommitdiff
path: root/services/backtester/tests/test_simulator.py
blob: e8c80ec32398be00293b470cbf0f284b49f4c930 (plain)
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")