def test_trade_tick_with_one_tick_returns_expected_tick(self): # Arrange tick1 = TradeTick( AUDUSD_SIM.id, Price("1.00000"), Quantity(10000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH, ) tick2 = TradeTick( AUDUSD_SIM.id, Price("1.00001"), Quantity(20000), OrderSide.SELL, TradeMatchId("123456789"), UNIX_EPOCH, ) self.cache.add_trade_tick(tick1) self.cache.add_trade_tick(tick2) # Act result = self.cache.trade_tick(AUDUSD_SIM.id, index=0) # Assert self.assertEqual(2, self.cache.trade_tick_count(AUDUSD_SIM.id)) self.assertEqual(tick2, result)
def test_trade_tick_with_one_tick_returns_expected_tick(self): # Arrange tick1 = TradeTick( AUDUSD_SIM.id, Price.from_str("1.00000"), Quantity.from_int(10000), AggressorSide.BUY, "123456789", 0, 0, ) tick2 = TradeTick( AUDUSD_SIM.id, Price.from_str("1.00001"), Quantity.from_int(20000), AggressorSide.SELL, "123456789", 0, 0, ) self.cache.add_trade_tick(tick1) self.cache.add_trade_tick(tick2) # Act result = self.cache.trade_tick(AUDUSD_SIM.id, index=0) # Assert self.assertEqual(2, self.cache.trade_tick_count(AUDUSD_SIM.id)) self.assertEqual(tick2, result)
def test_process_trade_tick_fills_buy_limit_entry_with_bracket(self): # Arrange # Prepare market tick1 = TradeTick( AUDUSD_SIM.symbol, Price("1.00000"), Quantity(100000), OrderSide.SELL, TradeMatchId("123456789"), UNIX_EPOCH, ) tick2 = TradeTick( AUDUSD_SIM.symbol, Price("1.00001"), Quantity(100000), OrderSide.BUY, TradeMatchId("123456790"), UNIX_EPOCH, ) self.data_engine.process(tick1) self.data_engine.process(tick2) self.exchange.process_tick(tick1) self.exchange.process_tick(tick2) entry = self.strategy.order_factory.limit( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("0.99900"), ) bracket = self.strategy.order_factory.bracket( entry_order=entry, stop_loss=Price("0.99800"), take_profit=Price("1.100"), ) self.strategy.submit_bracket_order(bracket) # Act tick3 = TradeTick( AUDUSD_SIM.symbol, Price("0.99899"), Quantity(100000), OrderSide.BUY, # Lowers ask price TradeMatchId("123456789"), UNIX_EPOCH, ) self.exchange.process_tick(tick3) # Assert self.assertEqual(2, len( self.exchange.get_working_orders())) # SL and TP only self.assertIn(bracket.stop_loss, self.exchange.get_working_orders().values()) self.assertIn(bracket.take_profit, self.exchange.get_working_orders().values())
def test_equality_and_comparisons(self): # Arrange # These are based on timestamp for tick sorting tick1 = TradeTick( AUDUSD_SIM.id, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), 1000, ) tick2 = TradeTick( AUDUSD_SIM.id, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), 2000, ) tick3 = TradeTick( AUDUSD_SIM.id, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), 3000, ) self.assertTrue(tick1 == tick1) self.assertEqual( [tick1, tick2, tick3], sorted([tick2, tick3, tick1], key=lambda x: x.timestamp_ns), )
def test_to_dict_returns_expected_dict(self): # Arrange tick = TradeTick( AUDUSD_SIM.id, Price.from_str("1.00000"), Quantity.from_int(10000), AggressorSide.BUY, "123456789", 0, 0, ) # Act result = TradeTick.to_dict(tick) # Assert assert result == { "type": "TradeTick", "instrument_id": "AUD/USD.SIM", "price": "1.00000", "size": "10000", "aggressor_side": "BUY", "match_id": "123456789", "ts_event_ns": 0, "ts_recv_ns": 0, }
def test_handle_trade_tick_when_volume_at_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.LAST) bar_type = BarType(instrument_id, bar_spec) aggregator = VolumeBarAggregator(bar_type, handler, Logger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("1.00001"), size=Quantity.from_int(3000), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123456"), timestamp_origin_ns=0, timestamp_ns=0, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("1.00002"), size=Quantity.from_int(4000), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123457"), timestamp_origin_ns=0, timestamp_ns=0, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("1.00000"), size=Quantity.from_int(3000), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123458"), timestamp_origin_ns=0, timestamp_ns=0, ) # Act aggregator.handle_trade_tick(tick1) aggregator.handle_trade_tick(tick2) aggregator.handle_trade_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price.from_str("1.00001"), bar_store.get_store()[0].open) self.assertEqual(Price.from_str("1.00002"), bar_store.get_store()[0].high) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[0].low) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[0].close) self.assertEqual(Quantity.from_int(10000), bar_store.get_store()[0].volume)
def test_handle_trade_tick_when_volume_beyond_threshold_sends_bars_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(100000, BarAggregation.VALUE, PriceType.LAST) bar_type = BarType(instrument_id, bar_spec) aggregator = ValueBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("20.00001"), size=Quantity("3000.00"), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("20.00002"), size=Quantity("4000.00"), side=OrderSide.BUY, match_id=TradeMatchId("123457"), timestamp=UNIX_EPOCH, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("20.00000"), size=Quantity("5000.00"), side=OrderSide.BUY, match_id=TradeMatchId("123458"), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_trade_tick(tick1) aggregator.handle_trade_tick(tick2) aggregator.handle_trade_tick(tick3) # Assert self.assertEqual(2, len(bar_store.get_store())) self.assertEqual(Price("20.00001"), bar_store.get_store()[0].bar.open) self.assertEqual(Price("20.00002"), bar_store.get_store()[0].bar.high) self.assertEqual(Price("20.00001"), bar_store.get_store()[0].bar.low) self.assertEqual(Price('20.00002'), bar_store.get_store()[0].bar.close) self.assertEqual(Quantity("5000"), bar_store.get_store()[0].bar.volume) self.assertEqual(Price("20.00002"), bar_store.get_store()[1].bar.open) self.assertEqual(Price("20.00002"), bar_store.get_store()[1].bar.high) self.assertEqual(Price("20.00000"), bar_store.get_store()[1].bar.low) self.assertEqual(Price('20.00000'), bar_store.get_store()[1].bar.close) self.assertEqual(Quantity("5000.00"), bar_store.get_store()[1].bar.volume) self.assertEqual(Decimal("40000.00000"), aggregator.cum_value)
def test_handle_trade_tick_when_volume_beyond_threshold_sends_bars_to_handler(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd_fxcm() bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.LAST) bar_type = BarType(symbol, bar_spec) aggregator = VolumeBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = TradeTick( symbol=AUDUSD_SIM.symbol, price=Price("1.00001"), size=Quantity(2000), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) tick2 = TradeTick( symbol=AUDUSD_SIM.symbol, price=Price("1.00002"), size=Quantity(3000), side=OrderSide.BUY, match_id=TradeMatchId("123457"), timestamp=UNIX_EPOCH, ) tick3 = TradeTick( symbol=AUDUSD_SIM.symbol, price=Price("1.00000"), size=Quantity(25000), side=OrderSide.BUY, match_id=TradeMatchId("123458"), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_trade_tick(tick1) aggregator.handle_trade_tick(tick2) aggregator.handle_trade_tick(tick3) # Assert self.assertEqual(3, len(bar_store.get_store())) self.assertEqual(Price("1.00001"), bar_store.get_store()[0].bar.open) self.assertEqual(Price("1.00002"), bar_store.get_store()[0].bar.high) self.assertEqual(Price("1.00000"), bar_store.get_store()[0].bar.low) self.assertEqual(Price('1.00000'), bar_store.get_store()[0].bar.close) self.assertEqual(Quantity(10000), bar_store.get_store()[0].bar.volume) self.assertEqual(Price("1.00000"), bar_store.get_store()[1].bar.open) self.assertEqual(Price("1.00000"), bar_store.get_store()[1].bar.high) self.assertEqual(Price("1.00000"), bar_store.get_store()[1].bar.low) self.assertEqual(Price('1.00000'), bar_store.get_store()[1].bar.close) self.assertEqual(Quantity(10000), bar_store.get_store()[1].bar.volume) self.assertEqual(Price("1.00000"), bar_store.get_store()[2].bar.open) self.assertEqual(Price("1.00000"), bar_store.get_store()[2].bar.high) self.assertEqual(Price("1.00000"), bar_store.get_store()[2].bar.low) self.assertEqual(Price('1.00000'), bar_store.get_store()[2].bar.close) self.assertEqual(Quantity(10000), bar_store.get_store()[2].bar.volume)
def test_handle_trade_tick_when_count_at_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.LAST) bar_type = BarType(instrument_id, bar_spec) aggregator = TickBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00001"), size=Quantity(1), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00002"), size=Quantity(1), side=OrderSide.BUY, match_id=TradeMatchId("123457"), timestamp=UNIX_EPOCH, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00000"), size=Quantity(1), side=OrderSide.BUY, match_id=TradeMatchId("123458"), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_trade_tick(tick1) aggregator.handle_trade_tick(tick2) aggregator.handle_trade_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price("1.00001"), bar_store.get_store()[0].bar.open) self.assertEqual(Price("1.00002"), bar_store.get_store()[0].bar.high) self.assertEqual(Price("1.00000"), bar_store.get_store()[0].bar.low) self.assertEqual(Price("1.00000"), bar_store.get_store()[0].bar.close) self.assertEqual(Quantity(3), bar_store.get_store()[0].bar.volume)
def test_handle_trade_tick_when_volume_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd() bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.LAST) bar_type = BarType(symbol, bar_spec) aggregator = VolumeBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = TradeTick( symbol=AUDUSD_SIM.symbol, price=Price("1.00001"), size=Quantity(1), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_trade_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_process_trade_tick_when_subscriber_then_sends_to_registered_handler(self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() handler = [] subscribe = Subscribe( client_id=ClientId(BINANCE.value), data_type=DataType( TradeTick, metadata={"InstrumentId": ETHUSDT_BINANCE.id} ), handler=handler.append, command_id=self.uuid_factory.generate(), timestamp_ns=self.clock.timestamp_ns(), ) self.data_engine.execute(subscribe) tick = TradeTick( ETHUSDT_BINANCE.id, Price.from_str("1050.00000"), Quantity.from_int(100), AggressorSide.BUY, TradeMatchId("123456789"), 0, 0, ) # Act self.data_engine.process(tick) # Assert self.assertEqual([tick], handler)
def test_handle_trade_tick_when_value_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(100000, BarAggregation.VALUE, PriceType.LAST) bar_type = BarType(instrument_id, bar_spec) aggregator = ValueBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("15000.00"), size=Quantity("3.5"), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_trade_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store())) self.assertEqual(Decimal("52500.000"), aggregator.cum_value)
def _handle_market_trades( runner, instrument, ts_event_ns, ts_recv_ns, ): trade_ticks = [] for price, volume in runner.get("trd", []): if volume == 0: continue # Betfair doesn't publish trade ids, so we make our own # TODO - should we use clk here for ID instead of the hash? trade_id = hash_json(data=(ts_event_ns, price, volume)) tick = TradeTick( instrument_id=instrument.id, price=price_to_probability( price, force=True), # Already wrapping in Price size=Quantity(volume, precision=4), aggressor_side=AggressorSide.UNKNOWN, match_id=trade_id, ts_event_ns=ts_event_ns, ts_recv_ns=ts_recv_ns, ) trade_ticks.append(tick) return trade_ticks
def test_process_trade_tick_when_subscriber_then_sends_to_registered_handler(self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() handler = [] subscribe = Subscribe( provider=BINANCE.value, data_type=DataType(TradeTick, metadata={"InstrumentId": ETHUSDT_BINANCE.id}), handler=handler.append, command_id=self.uuid_factory.generate(), command_timestamp=self.clock.utc_now(), ) self.data_engine.execute(subscribe) tick = TradeTick( ETHUSDT_BINANCE.id, Price("1050.00000"), Quantity(100), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH, ) # Act self.data_engine.process(tick) # Assert self.assertEqual([tick], handler)
def _handle_market_trades(runner, instrument, timestamp_ns): trade_ticks = [] for price, volume in runner.get("trd", []): if volume == 0: continue # Betfair doesn't publish trade ids, so we make our own # TODO - should we use clk here for ID instead of the hash? trade_id = hash_json(data=( timestamp_ns, instrument.market_id, str(runner["id"]), str(runner.get("hc", "0.0")), price, volume, )) tick = TradeTick( instrument_id=instrument.id, price=Price(price_to_probability(price, force=True)), size=Quantity(volume, precision=4), side=OrderSide.BUY, match_id=TradeMatchId(trade_id), timestamp_ns=timestamp_ns, ) trade_ticks.append(tick) return trade_ticks
def test_to_serializable_returns_expected_string(self): # Arrange tick = TradeTick( AUDUSD_SIM.symbol, Price("1.00000"), Quantity(10000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH, ) # Act result = tick.to_serializable_string() # Assert self.assertEqual("1.00000,10000,BUY,123456789,0", result)
def test_handle_trade_tick_when_value_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(100000, BarAggregation.VALUE, PriceType.LAST) bar_type = BarType(instrument_id, bar_spec) aggregator = ValueBarAggregator( AUDUSD_SIM, bar_type, handler, Logger(TestClock()), ) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("15000.00"), size=Quantity.from_str("3.5"), aggressor_side=AggressorSide.BUY, match_id="123456", ts_event_ns=0, ts_recv_ns=0, ) # Act aggregator.handle_trade_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store())) self.assertEqual(Decimal("52500.000"), aggregator.get_cumulative_value())
def test_from_serializable_string_given_valid_string_returns_expected_tick(self): # Arrange tick = TradeTick( AUDUSD_SIM.id, Price("1.00000"), Quantity(10000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH, ) # Act result = TradeTick.from_serializable_str(AUDUSD_SIM.id, tick.to_serializable_str()) # Assert self.assertEqual(tick, result)
def test_handle_trade_tick_when_volume_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument = AUDUSD_SIM bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.LAST) bar_type = BarType(instrument.id, bar_spec) aggregator = VolumeBarAggregator( instrument, bar_type, handler, Logger(TestClock()), ) tick1 = TradeTick( instrument_id=instrument.id, price=Price.from_str("1.00001"), size=Quantity.from_int(1), aggressor_side=AggressorSide.BUY, match_id="123456", ts_event_ns=0, ts_recv_ns=0, ) # Act aggregator.handle_trade_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_parse_trade_tick_from_string(self): # Arrange tick = TradeTick( AUDUSD_FXCM, Price("1.00000"), Quantity(10000), Maker.BUYER, MatchId("123456789"), UNIX_EPOCH, ) # Act result = TradeTick.from_serializable_string(AUDUSD_FXCM, tick.to_serializable_string()) # Assert self.assertEqual(tick, result)
def test_to_serializable_returns_expected_string(self): # Arrange tick = TradeTick( AUDUSD_SIM.id, Price.from_str("1.00000"), Quantity.from_int(10000), AggressorSide.BUY, TradeMatchId("123456789"), 0, 0, ) # Act result = tick.to_serializable_str() # Assert self.assertEqual("1.00000,10000,BUY,123456789,0,0", result)
def test_from_dict_returns_expected_tick(self): # Arrange tick = TradeTick( AUDUSD_SIM.id, Price.from_str("1.00000"), Quantity.from_int(10000), AggressorSide.BUY, "123456789", 0, 0, ) # Act result = TradeTick.from_dict(TradeTick.to_dict(tick)) # Assert assert tick == result
def trade_tick_5decimal(symbol) -> TradeTick: return TradeTick( symbol, Price("1.00001"), Quantity(100000), Maker.BUYER, MatchId("123456"), UNIX_EPOCH, )
def trade_tick_5decimal(symbol=None) -> TradeTick: return TradeTick( symbol if symbol is not None else TestStubs.symbol_audusd_fxcm(), Price("1.00001"), Quantity(100000), OrderSide.BUY, TradeMatchId("123456"), UNIX_EPOCH, )
def trade_tick_5decimal(instrument_id=None, price=None) -> TradeTick: return TradeTick( instrument_id if instrument_id is not None else TestStubs.audusd_id(), price if price is not None else Price("1.00001"), Quantity(100000), OrderSide.BUY, TradeMatchId("123456"), UNIX_EPOCH, )
def trade_tick_5decimal(instrument_id=None, price=None, aggressor_side=None, quantity=None) -> TradeTick: return TradeTick( instrument_id or TestStubs.audusd_id(), price or Price("1.00001"), quantity or Quantity(100000), aggressor_side or AggressorSide.BUY, TradeMatchId("123456"), 0, )
def test_equality_and_comparisons(self): # Arrange # These are based on timestamp for tick sorting tick1 = TradeTick( AUDUSD_SIM.symbol, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH + timedelta(seconds=1), ) tick2 = TradeTick( AUDUSD_SIM.symbol, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH + timedelta(seconds=2), ) tick3 = TradeTick( AUDUSD_SIM.symbol, Price("1.00000"), Quantity(50000), OrderSide.BUY, TradeMatchId("123456789"), UNIX_EPOCH + timedelta(seconds=3), ) self.assertTrue(tick1 == tick1) self.assertTrue(tick1 != tick2) self.assertTrue(tick1 <= tick1) self.assertTrue(tick1 <= tick2) self.assertTrue(tick1 < tick2) self.assertTrue(tick3 > tick2) self.assertTrue(tick3 >= tick2) self.assertTrue(tick3 >= tick3) self.assertEqual([tick1, tick2, tick3], sorted([tick2, tick3, tick1]))
def trade_tick_5decimal(instrument_id=None, price=None, aggressor_side=None, quantity=None) -> TradeTick: return TradeTick( instrument_id=instrument_id or TestStubs.audusd_id(), price=price or Price.from_str("1.00001"), size=quantity or Quantity.from_int(100000), aggressor_side=aggressor_side or AggressorSide.BUY, match_id="123456", ts_event_ns=0, ts_recv_ns=0, )
def parse_line(d): if "status" in d: return {} elif "close_price" in d: # return {'timestamp': d['remote_timestamp'], "close_price": d['close_price']} return {} if "trade" in d: return { "timestamp": d["remote_timestamp"], "op": "trade", "trade": TradeTick( instrument_id=InstrumentId(Symbol("TEST"), Venue("BETFAIR")), price=Price(d["trade"]["price"], 4), size=Quantity(d["trade"]["volume"], 4), aggressor_side=d["trade"]["side"], match_id=TradeMatchId(d["trade"]["trade_id"]), timestamp_origin_ns=millis_to_nanos( pd.Timestamp(d["remote_timestamp"]).timestamp()), timestamp_ns=millis_to_nanos( pd.Timestamp(d["remote_timestamp"]).timestamp( ) # TODO(cs): Hardcoded identical for now ), ), } elif "level" in d and d["level"]["orders"][0]["volume"] == 0: op = "delete" else: op = "update" order_like = d["level"]["orders"][0] if op != "trade" else d[ "trade"] return { "timestamp": d["remote_timestamp"], "op": op, "order": Order( price=Price(order_like["price"], precision=6), volume=Quantity(abs(order_like["volume"]), precision=4), # Betting sides are reversed side={ 2: OrderSide.BUY, 1: OrderSide.SELL }[order_like["side"]], id=str(order_like["order_id"]), ), }
def test_handle_trade_tick_sends_to_data_engine(self): # Arrange tick = TradeTick( AUDUSD_SIM.symbol, Price("1.00050"), Quantity(1), OrderSide.BUY, TradeMatchId("123456"), UNIX_EPOCH, ) # Act self.client._handle_trade_tick_py(tick) # Assert self.assertEqual(1, self.data_engine.data_count)