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
|
"""Test that strategy engine processes multiple symbols concurrently."""
import asyncio
import sys
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock
import pytest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "src"))
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from strategy_engine.engine import StrategyEngine
from shared.events import CandleEvent
from shared.models import Candle, OrderSide
from decimal import Decimal
from datetime import datetime, timezone
@pytest.mark.asyncio
async def test_engine_processes_multiple_streams():
"""Verify engine can process candles from different streams."""
broker = AsyncMock()
candle_btc = Candle(
symbol="BTCUSDT", timeframe="1m",
open_time=datetime(2025, 1, 1, tzinfo=timezone.utc),
open=Decimal("50000"), high=Decimal("51000"),
low=Decimal("49000"), close=Decimal("50000"),
volume=Decimal("10"),
)
candle_eth = Candle(
symbol="ETHUSDT", timeframe="1m",
open_time=datetime(2025, 1, 1, tzinfo=timezone.utc),
open=Decimal("3000"), high=Decimal("3100"),
low=Decimal("2900"), close=Decimal("3000"),
volume=Decimal("10"),
)
btc_events = [CandleEvent(data=candle_btc).to_dict()]
eth_events = [CandleEvent(data=candle_eth).to_dict()]
# First call returns BTC event, second ETH, then empty
call_count = {"btc": 0, "eth": 0}
async def mock_read(stream, **kwargs):
if "BTC" in stream:
call_count["btc"] += 1
return btc_events if call_count["btc"] == 1 else []
elif "ETH" in stream:
call_count["eth"] += 1
return eth_events if call_count["eth"] == 1 else []
return []
broker.read = AsyncMock(side_effect=mock_read)
strategy = MagicMock()
strategy.on_candle = MagicMock(return_value=None)
engine = StrategyEngine(broker=broker, strategies=[strategy])
# Process both streams
await engine.process_once("candles.BTCUSDT", "$")
await engine.process_once("candles.ETHUSDT", "$")
# Strategy should have been called with both candles
assert strategy.on_candle.call_count == 2
|