class TestTrader: def setup(self): # Fixture Setup self.clock = TestClock() self.logger = Logger(self.clock) self.trader_id = TestStubs.trader_id() self.account_id = TestStubs.account_id() self.msgbus = MessageBus( trader_id=self.trader_id, clock=self.clock, logger=self.logger, ) self.cache = TestStubs.cache() self.portfolio = Portfolio( msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.data_engine = DataEngine( msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.data_engine.process(USDJPY_SIM) self.exec_engine = ExecutionEngine( msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.exchange = SimulatedExchange( venue=Venue("SIM"), venue_type=VenueType.ECN, oms_type=OMSType.HEDGING, account_type=AccountType.MARGIN, base_currency=USD, starting_balances=[Money(1_000_000, USD)], default_leverage=Decimal(50), leverages={}, is_frozen_account=False, cache=self.cache, instruments=[USDJPY_SIM], modules=[], fill_model=FillModel(), clock=self.clock, logger=self.logger, ) self.data_client = BacktestMarketDataClient( client_id=ClientId("SIM"), msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.exec_client = BacktestExecClient( exchange=self.exchange, account_id=self.account_id, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.risk_engine = RiskEngine( portfolio=self.portfolio, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) # Wire up components self.data_engine.register_client(self.data_client) self.exec_engine.register_client(self.exec_client) self.trader = Trader( trader_id=self.trader_id, msgbus=self.msgbus, cache=self.cache, portfolio=self.portfolio, data_engine=self.data_engine, risk_engine=self.risk_engine, exec_engine=self.exec_engine, clock=self.clock, logger=self.logger, ) def test_initialize_trader(self): # Arrange, Act, Assert assert self.trader.id == TraderId("TESTER-000") assert self.trader.is_initialized assert len(self.trader.strategy_states()) == 0 def test_add_strategy(self): # Arrange, Act self.trader.add_strategy(TradingStrategy()) # Assert assert self.trader.strategy_states() == { StrategyId("TradingStrategy-000"): "INITIALIZED" } def test_add_strategies(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="001")), TradingStrategy(TradingStrategyConfig(order_id_tag="002")), ] # Act self.trader.add_strategies(strategies) # Assert assert self.trader.strategy_states() == { StrategyId("TradingStrategy-001"): "INITIALIZED", StrategyId("TradingStrategy-002"): "INITIALIZED", } def test_clear_strategies(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="001")), TradingStrategy(TradingStrategyConfig(order_id_tag="002")), ] self.trader.add_strategies(strategies) # Act self.trader.clear_strategies() # Assert assert self.trader.strategy_states() == {} def test_add_actor(self): # Arrange config = ActorConfig(component_id="MyPlugin-01") actor = Actor(config) # Act self.trader.add_actor(actor) # Assert assert self.trader.actor_ids() == [ComponentId("MyPlugin-01")] def test_add_actors(self): # Arrange actors = [ Actor(ActorConfig(component_id="MyPlugin-01")), Actor(ActorConfig(component_id="MyPlugin-02")), ] # Act self.trader.add_actors(actors) # Assert assert self.trader.actor_ids() == [ ComponentId("MyPlugin-01"), ComponentId("MyPlugin-02"), ] def test_clear_actors(self): # Arrange actors = [ Actor(ActorConfig(component_id="MyPlugin-01")), Actor(ActorConfig(component_id="MyPlugin-02")), ] self.trader.add_actors(actors) # Act self.trader.clear_actors() # Assert assert self.trader.actor_ids() == [] def test_get_strategy_states(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="001")), TradingStrategy(TradingStrategyConfig(order_id_tag="002")), ] self.trader.add_strategies(strategies) # Act status = self.trader.strategy_states() # Assert assert StrategyId("TradingStrategy-001") in status assert StrategyId("TradingStrategy-002") in status assert status[StrategyId("TradingStrategy-001")] == "INITIALIZED" assert status[StrategyId("TradingStrategy-002")] == "INITIALIZED" assert len(status) == 2 def test_change_strategies(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="003")), TradingStrategy(TradingStrategyConfig(order_id_tag="004")), ] # Act self.trader.add_strategies(strategies) # Assert assert strategies[0].id in self.trader.strategy_states() assert strategies[1].id in self.trader.strategy_states() assert len(self.trader.strategy_states()) == 2 def test_start_a_trader(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="001")), TradingStrategy(TradingStrategyConfig(order_id_tag="002")), ] self.trader.add_strategies(strategies) # Act self.trader.start() strategy_states = self.trader.strategy_states() # Assert assert self.trader.is_running assert strategy_states[StrategyId("TradingStrategy-001")] == "RUNNING" assert strategy_states[StrategyId("TradingStrategy-002")] == "RUNNING" def test_stop_a_running_trader(self): # Arrange strategies = [ TradingStrategy(TradingStrategyConfig(order_id_tag="001")), TradingStrategy(TradingStrategyConfig(order_id_tag="002")), ] self.trader.add_strategies(strategies) self.trader.start() # Act self.trader.stop() strategy_states = self.trader.strategy_states() # Assert assert self.trader.is_stopped assert strategy_states[StrategyId("TradingStrategy-001")] == "STOPPED" assert strategy_states[StrategyId("TradingStrategy-002")] == "STOPPED" def test_subscribe_to_msgbus_topic_adds_subscription(self): # Arrange consumer = [] # Act self.trader.subscribe("events*", consumer.append) # Assert assert len(self.msgbus.subscriptions("events*")) == 6 assert "events*" in self.msgbus.topics() assert self.msgbus.subscriptions( "events*")[-1].handler == consumer.append def test_unsubscribe_from_msgbus_topic_removes_subscription(self): # Arrange consumer = [] self.trader.subscribe("events*", consumer.append) # Act self.trader.unsubscribe("events*", consumer.append) # Assert assert len(self.msgbus.subscriptions("events*")) == 5
class TraderTests(unittest.TestCase): def setUp(self): # Fixture Setup clock = TestClock() logger = Logger(clock) trader_id = TraderId("TESTER", "000") account_id = TestStubs.account_id() self.portfolio = Portfolio( clock=clock, logger=logger, ) self.data_engine = DataEngine( portfolio=self.portfolio, clock=clock, logger=logger, config={"use_previous_close": False}, ) self.portfolio.register_cache(self.data_engine.cache) self.analyzer = PerformanceAnalyzer() self.exec_db = BypassExecutionDatabase( trader_id=trader_id, logger=logger, ) self.exec_engine = ExecutionEngine( database=self.exec_db, portfolio=self.portfolio, clock=clock, logger=logger, ) self.exchange = SimulatedExchange( venue=Venue("SIM"), oms_type=OMSType.HEDGING, is_frozen_account=False, starting_balances=[Money(1_000_000, USD)], exec_cache=self.exec_engine.cache, instruments=[USDJPY_SIM], modules=[], fill_model=FillModel(), clock=clock, logger=logger, ) self.data_client = BacktestMarketDataClient( instruments=[USDJPY_SIM], client_id=ClientId("SIM"), engine=self.data_engine, clock=clock, logger=logger, ) self.data_engine.register_client(self.data_client) self.exec_client = BacktestExecClient( exchange=self.exchange, account_id=account_id, engine=self.exec_engine, clock=clock, logger=logger, ) self.risk_engine = RiskEngine( exec_engine=self.exec_engine, portfolio=self.portfolio, clock=clock, logger=logger, ) self.exec_engine.register_risk_engine(self.risk_engine) self.exec_engine.register_client(self.exec_client) strategies = [ TradingStrategy("001"), TradingStrategy("002"), ] self.trader = Trader( trader_id=trader_id, strategies=strategies, portfolio=self.portfolio, data_engine=self.data_engine, exec_engine=self.exec_engine, risk_engine=self.risk_engine, clock=clock, logger=logger, ) def test_initialize_trader(self): # Arrange # Act trader_id = self.trader.id # Assert self.assertEqual(TraderId("TESTER", "000"), trader_id) self.assertEqual(IdTag("000"), trader_id.tag) self.assertEqual(ComponentState.INITIALIZED, self.trader.state) self.assertEqual(2, len(self.trader.strategy_states())) def test_get_strategy_states(self): # Arrange # Act status = self.trader.strategy_states() # Assert self.assertTrue(StrategyId("TradingStrategy", "001") in status) self.assertTrue(StrategyId("TradingStrategy", "002") in status) self.assertEqual("INITIALIZED", status[StrategyId("TradingStrategy", "001")]) self.assertEqual("INITIALIZED", status[StrategyId("TradingStrategy", "002")]) self.assertEqual(2, len(status)) def test_change_strategies(self): # Arrange strategies = [ TradingStrategy("003"), TradingStrategy("004"), ] # Act self.trader.initialize_strategies(strategies, warn_no_strategies=True) # Assert self.assertTrue(strategies[0].id in self.trader.strategy_states()) self.assertTrue(strategies[1].id in self.trader.strategy_states()) self.assertEqual(2, len(self.trader.strategy_states())) def test_trader_detects_duplicate_identifiers(self): # Arrange strategies = [ TradingStrategy("000"), TradingStrategy("000"), ] # Act self.assertRaises( ValueError, self.trader.initialize_strategies, strategies, True, ) def test_start_a_trader(self): # Arrange # Act self.trader.start() strategy_states = self.trader.strategy_states() # Assert self.assertEqual(ComponentState.RUNNING, self.trader.state) self.assertEqual("RUNNING", strategy_states[StrategyId("TradingStrategy", "001")]) self.assertEqual("RUNNING", strategy_states[StrategyId("TradingStrategy", "002")]) def test_stop_a_running_trader(self): # Arrange self.trader.start() # Act self.trader.stop() strategy_states = self.trader.strategy_states() # Assert self.assertEqual(ComponentState.STOPPED, self.trader.state) self.assertEqual("STOPPED", strategy_states[StrategyId("TradingStrategy", "001")]) self.assertEqual("STOPPED", strategy_states[StrategyId("TradingStrategy", "002")])
class TraderTests(unittest.TestCase): def setUp(self): # Fixture Setup usdjpy = InstrumentLoader.default_fx_ccy( TestStubs.symbol_usdjpy_fxcm()) data = BacktestDataContainer() data.add_instrument(usdjpy) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.BID, TestDataProvider.usdjpy_1min_bid()[:2000]) data.add_bars(usdjpy.symbol, BarAggregation.MINUTE, PriceType.ASK, TestDataProvider.usdjpy_1min_ask()[:2000]) clock = TestClock() uuid_factory = TestUUIDFactory() logger = TestLogger(clock) trader_id = TraderId("TESTER", "000") account_id = TestStubs.account_id() self.portfolio = Portfolio( clock=clock, uuid_factory=uuid_factory, logger=logger, ) data_engine = BacktestDataEngine( data=data, tick_capacity=1000, bar_capacity=1000, portfolio=self.portfolio, clock=clock, logger=logger, ) self.analyzer = PerformanceAnalyzer() self.exec_db = BypassExecutionDatabase( trader_id=trader_id, logger=logger, ) self.exec_engine = ExecutionEngine( database=self.exec_db, portfolio=self.portfolio, clock=clock, uuid_factory=uuid_factory, logger=logger, ) self.market = SimulatedMarket( venue=Venue("FXCM"), oms_type=OMSType.HEDGING, generate_position_ids=True, exec_cache=self.exec_engine.cache, instruments={usdjpy.symbol: usdjpy}, config=BacktestConfig(), fill_model=FillModel(), commission_model=GenericCommissionModel(), clock=clock, uuid_factory=TestUUIDFactory(), logger=logger, ) self.exec_client = BacktestExecClient( market=self.market, account_id=account_id, engine=self.exec_engine, logger=logger, ) self.exec_engine.register_client(self.exec_client) strategies = [ EmptyStrategy("001"), EmptyStrategy("002"), ] self.trader = Trader( trader_id=trader_id, strategies=strategies, data_engine=data_engine, exec_engine=self.exec_engine, clock=clock, uuid_factory=uuid_factory, logger=logger, ) def test_initialize_trader(self): # Arrange # Act trader_id = self.trader.id # Assert self.assertEqual(TraderId("TESTER", "000"), trader_id) self.assertEqual(IdTag("000"), trader_id.tag) self.assertEqual(ComponentState.INITIALIZED, self.trader.state()) self.assertEqual(2, len(self.trader.strategy_states())) def test_get_strategy_states(self): # Arrange # Act status = self.trader.strategy_states() # Assert self.assertTrue(StrategyId("EmptyStrategy", "001") in status) self.assertTrue(StrategyId("EmptyStrategy", "002") in status) self.assertEqual('INITIALIZED', status[StrategyId("EmptyStrategy", "001")]) self.assertEqual('INITIALIZED', status[StrategyId("EmptyStrategy", "002")]) self.assertEqual(2, len(status)) def test_change_strategies(self): # Arrange strategies = [EmptyStrategy("003"), EmptyStrategy("004")] # Act self.trader.initialize_strategies(strategies) # Assert self.assertTrue(strategies[0].id in self.trader.strategy_states()) self.assertTrue(strategies[1].id in self.trader.strategy_states()) self.assertEqual(2, len(self.trader.strategy_states())) def test_trader_detects_none_unique_identifiers(self): # Arrange strategies = [EmptyStrategy("000"), EmptyStrategy("000")] # Act self.assertRaises(ValueError, self.trader.initialize_strategies, strategies) def test_start_a_trader(self): # Arrange # Act self.trader.start() strategy_states = self.trader.strategy_states() # Assert self.assertEqual(ComponentState.RUNNING, self.trader.state()) self.assertEqual('RUNNING', strategy_states[StrategyId("EmptyStrategy", "001")]) self.assertEqual('RUNNING', strategy_states[StrategyId("EmptyStrategy", "002")]) def test_stop_a_running_trader(self): # Arrange self.trader.start() # Act self.trader.stop() strategy_states = self.trader.strategy_states() # Assert self.assertEqual(ComponentState.STOPPED, self.trader.state()) self.assertEqual('STOPPED', strategy_states[StrategyId("EmptyStrategy", "001")]) self.assertEqual('STOPPED', strategy_states[StrategyId("EmptyStrategy", "002")])