def test_instantiate_with_various_bar_specs(self, bar_spec, expected): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd_fxcm() bar_type = BarType(symbol, bar_spec) # Act aggregator = TimeBarAggregator(bar_type, handler, True, clock, TestLogger(clock)) # Assert self.assertEqual(expected, aggregator.next_close)
def test_can_unsubscribe_from_bar_data(self): # Arrange data_receiver = ObjectStorer() bar_type = TestStubs.bartype_audusd_1min_bid() # Act self.data_client.subscribe_bars(bar_type, handler=data_receiver.store_2) self.data_client.unsubscribe_bars(bar_type, handler=data_receiver.store_2) # Assert self.assertNotIn(bar_type, self.data_client.subscribed_ticks())
def test_process_bar_when_subscriber_then_sends_to_registered_handler( self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() bar_spec = BarSpecification(1000, BarAggregation.TICK, PriceType.MID) bar_type = BarType(ETHUSDT_BINANCE.symbol, bar_spec, is_internal_aggregation=True) handler = ObjectStorer() subscribe = Subscribe( venue=BINANCE, data_type=Bar, metadata={"BarType": bar_type}, handler=handler.store_2, command_id=self.uuid_factory.generate(), command_timestamp=self.clock.utc_now(), ) self.data_engine.execute(subscribe) bar = Bar( Price("1051.00000"), Price("1055.00000"), Price("1050.00000"), Price("1052.00000"), Quantity(100), UNIX_EPOCH, ) data = BarData(bar_type, bar) # Act self.data_engine.process(data) # Assert self.assertEqual([(bar_type, bar)], handler.get_store())
def test_process_bar_when_subscriber_then_sends_to_registered_handler( self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() bar_spec = BarSpecification(1000, BarAggregation.TICK, PriceType.MID) bar_type = BarType(ETHUSDT_BINANCE.id, bar_spec, internal_aggregation=True) handler = ObjectStorer() subscribe = Subscribe( client_id=ClientId(BINANCE.value), data_type=DataType(Bar, metadata={"bar_type": bar_type}), handler=handler.store, command_id=self.uuid_factory.generate(), timestamp_ns=self.clock.timestamp_ns(), ) self.data_engine.execute(subscribe) bar = Bar( bar_type, Price.from_str("1051.00000"), Price.from_str("1055.00000"), Price.from_str("1050.00000"), Price.from_str("1052.00000"), Quantity.from_int(100), 0, 0, ) # Act self.data_engine.process(bar) # Assert self.assertEqual([bar], handler.get_store())
def test_handle_quote_tick_when_volume_at_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument = AUDUSD_SIM bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.BID) bar_type = BarType(instrument.id, bar_spec) aggregator = VolumeBarAggregator( instrument, bar_type, handler, Logger(TestClock()), ) tick1 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00001"), ask=Price.from_str("1.00004"), bid_size=Quantity.from_int(3000), ask_size=Quantity.from_int(2000), ts_event=0, ts_init=0, ) tick2 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00002"), ask=Price.from_str("1.00005"), bid_size=Quantity.from_int(4000), ask_size=Quantity.from_int(2000), ts_event=0, ts_init=0, ) tick3 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00000"), ask=Price.from_str("1.00003"), bid_size=Quantity.from_int(3000), ask_size=Quantity.from_int(2000), ts_event=0, ts_init=0, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert assert len(bar_store.get_store()) == 1 assert bar_store.get_store()[0].open == Price.from_str("1.00001") assert bar_store.get_store()[0].high == Price.from_str("1.00002") assert bar_store.get_store()[0].low == Price.from_str("1.00000") assert bar_store.get_store()[0].close == Price.from_str("1.00000") assert bar_store.get_store()[0].volume == Quantity.from_int(10000)
def test_handle_trade_tick_when_volume_at_threshold_sends_bar_to_handler( 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(3000), aggressor_side=AggressorSide.BUY, trade_id="123456", ts_event=0, ts_init=0, ) tick2 = TradeTick( instrument_id=instrument.id, price=Price.from_str("1.00002"), size=Quantity.from_int(4000), aggressor_side=AggressorSide.BUY, trade_id="123457", ts_event=0, ts_init=0, ) tick3 = TradeTick( instrument_id=instrument.id, price=Price.from_str("1.00000"), size=Quantity.from_int(3000), aggressor_side=AggressorSide.BUY, trade_id="123458", ts_event=0, ts_init=0, ) # Act aggregator.handle_trade_tick(tick1) aggregator.handle_trade_tick(tick2) aggregator.handle_trade_tick(tick3) # Assert assert len(bar_store.get_store()) == 1 assert bar_store.get_store()[0].open == Price.from_str("1.00001") assert bar_store.get_store()[0].high == Price.from_str("1.00002") assert bar_store.get_store()[0].low == Price.from_str("1.00000") assert bar_store.get_store()[0].close == Price.from_str("1.00000") assert bar_store.get_store()[0].volume == Quantity.from_int(10000)
def test_handle_quote_tick_when_volume_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.BID) bar_type = BarType(instrument_id, bar_spec) aggregator = VolumeBarAggregator(bar_type, handler, Logger(TestClock())) tick1 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(3000), ask_size=Quantity(2000), timestamp_ns=0, ) # Act aggregator.handle_quote_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_handle_trade_tick_when_count_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd_fxcm() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.LAST) bar_type = BarType(symbol, bar_spec) aggregator = TickBarAggregator(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_handle_quote_tick_when_count_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd_fxcm() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.MID) bar_type = BarType(symbol, bar_spec) aggregator = TickBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_quote_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_handle_trade_tick_when_volume_below_threshold_updates(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("1.00001"), size=Quantity(1), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp_ns=0, ) # Act aggregator.handle_trade_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_update_timed_with_test_clock_sends_single_bar_to_handler(self): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd_fxcm() bar_spec = BarSpecification(1, BarAggregation.MINUTE, PriceType.MID) bar_type = BarType(symbol, bar_spec) aggregator = TimeBarAggregator(bar_type, handler, True, TestClock(), TestLogger(clock)) stop_time = UNIX_EPOCH + timedelta(minutes=2) tick1 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) tick2 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) tick3 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=stop_time, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price("1.000025"), bar_store.get_store()[0].bar.open) self.assertEqual(Price("1.000035"), bar_store.get_store()[0].bar.high) self.assertEqual(Price("1.000025"), bar_store.get_store()[0].bar.low) self.assertEqual(Price("1.000035"), bar_store.get_store()[0].bar.close) self.assertEqual(Quantity(2), bar_store.get_store()[0].bar.volume) self.assertEqual(datetime(1970, 1, 1, 0, 1, tzinfo=pytz.utc), bar_store.get_store()[0].bar.timestamp)
def test_update_timed_with_test_clock_sends_single_bar_to_handler(self): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(1, BarAggregation.MINUTE, PriceType.MID) bar_type = BarType(instrument_id, bar_spec) aggregator = TimeBarAggregator( bar_type, handler, True, TestClock(), Logger(clock) ) tick1 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp_ns=0, ) tick2 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp_ns=0, ) tick3 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp_ns=2 * 60 * 1_000_000_000, # 2 minutes in nanoseconds ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price("1.000025"), bar_store.get_store()[0].open) self.assertEqual(Price("1.000035"), bar_store.get_store()[0].high) self.assertEqual(Price("1.000025"), bar_store.get_store()[0].low) self.assertEqual(Price("1.000035"), bar_store.get_store()[0].close) self.assertEqual(Quantity(2), bar_store.get_store()[0].volume) self.assertEqual(60_000_000_000, bar_store.get_store()[0].timestamp_ns)
def test_can_request_tick_data(self): # Arrange data_receiver = ObjectStorer() # Act self.data_client.request_ticks(AUDUSD_FXCM, UNIX_EPOCH.date(), UNIX_EPOCH.date(), limit=0, callback=data_receiver.store) time.sleep(0.2) # Assert self.assertEqual(1, len(self.data_server_sink)) self.assertEqual(DataRequest, type(self.data_server_sink[0]))
def test_handle_quote_tick_when_count_below_threshold_updates(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.MID) bar_type = BarType(instrument_id, bar_spec) aggregator = TickBarAggregator(bar_type, handler, Logger(TestClock())) tick1 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price.from_str("1.00001"), ask=Price.from_str("1.00004"), bid_size=Quantity.from_int(1), ask_size=Quantity.from_int(1), timestamp_origin_ns=0, timestamp_ns=0, ) # Act aggregator.handle_quote_tick(tick1) # Assert self.assertEqual(0, len(bar_store.get_store()))
def test_given_list_of_ticks_aggregates_tick_bars(self): # Arrange instrument = TestInstrumentProvider.default_fx_ccy("USD/JPY") wrangler = QuoteTickDataWrangler(instrument) provider = TestDataProvider() ticks = wrangler.process( provider.read_csv_ticks("truefx-usdjpy-ticks.csv")) bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.usdjpy_id() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.MID) bar_type = BarType(instrument_id, bar_spec) clock = TestClock() logger = Logger(clock) builder = BulkTickBarBuilder(instrument, bar_type, logger, handler) # Act builder.receive(ticks) # Assert assert len(bar_store.get_store()[0]) == 333
def test_handle_quote_tick_when_value_beyond_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(100000, BarAggregation.VALUE, PriceType.BID) bar_type = BarType(instrument_id, bar_spec) aggregator = ValueBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(20000), ask_size=Quantity(20000), timestamp=UNIX_EPOCH, ) tick2 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(60000), ask_size=Quantity(20000), timestamp=UNIX_EPOCH, ) tick3 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(30500), ask_size=Quantity(20000), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_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("99999"), bar_store.get_store()[0].bar.volume) self.assertEqual(Decimal("10501.00000"), aggregator.cum_value)
def test_instantiate_given_invalid_bar_spec_raises_value_error(self): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store instrument = AUDUSD_SIM bar_spec = BarSpecification(100, BarAggregation.TICK, PriceType.MID) bar_type = BarType(instrument.id, bar_spec) # Act, Assert with pytest.raises(ValueError): TimeBarAggregator( instrument, bar_type, handler, clock, Logger(clock), )
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, TestLogger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00001"), size=Quantity(3000), side=OrderSide.BUY, match_id=TradeMatchId("123456"), timestamp=UNIX_EPOCH, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00002"), size=Quantity(4000), side=OrderSide.BUY, match_id=TradeMatchId("123457"), timestamp=UNIX_EPOCH, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00000"), size=Quantity(3000), 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(10000), bar_store.get_store()[0].bar.volume)
def test_handle_quote_tick_when_volume_at_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store symbol = TestStubs.symbol_audusd() bar_spec = BarSpecification(10000, BarAggregation.VOLUME, PriceType.BID) bar_type = BarType(symbol, bar_spec) aggregator = VolumeBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(3000), ask_size=Quantity(2000), timestamp=UNIX_EPOCH, ) tick2 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(4000), ask_size=Quantity(2000), timestamp=UNIX_EPOCH, ) tick3 = QuoteTick( symbol=AUDUSD_SIM.symbol, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(3000), ask_size=Quantity(2000), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_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(10000), bar_store.get_store()[0].bar.volume)
def test_instantiate_with_various_bar_specs(self, bar_spec, expected): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_type = BarType(instrument_id, bar_spec) # Act aggregator = TimeBarAggregator( AUDUSD_SIM, bar_type, handler, clock, Logger(clock), ) # Assert assert aggregator.next_close_ns == expected
def test_run_trade_ticks_through_aggregator_results_in_expected_bars(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store bar_spec = BarSpecification(10000, BarAggregation.VALUE, PriceType.LAST) bar_type = BarType(ETHUSDT_BINANCE.id, bar_spec) aggregator = ValueBarAggregator(bar_type, handler, Logger(TestClock())) wrangler = TradeTickDataWrangler( instrument=ETHUSDT_BINANCE, data=TestDataProvider.ethusdt_trades(), ) wrangler.pre_process(0) ticks = wrangler.build_ticks() # Act for tick in ticks: aggregator.handle_trade_tick(tick)
def test_handle_quote_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.MID) bar_type = BarType(instrument_id, bar_spec) aggregator = TickBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) tick2 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) tick3 = QuoteTick( instrument_id=AUDUSD_SIM.id, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price("1.000025"), bar_store.get_store()[0].bar.open) self.assertEqual(Price("1.000035"), bar_store.get_store()[0].bar.high) self.assertEqual(Price("1.000015"), bar_store.get_store()[0].bar.low) self.assertEqual(Price("1.000015"), bar_store.get_store()[0].bar.close) self.assertEqual(Quantity(3), bar_store.get_store()[0].bar.volume)
async def run_test(): # Arrange with open(TEST_PATH + "res_instruments.json") as response: instruments = json.load(response) with open(TEST_PATH + "res_trades.json") as response: trades = json.load(response) self.mock_ccxt.markets = instruments self.mock_ccxt.fetch_trades = trades self.data_engine.start() await asyncio.sleep(0.1) # Allow engine message queue to start handler = ObjectStorer() request = DataRequest( venue=BINANCE, data_type=TradeTick, metadata={ "Symbol": ETHUSDT, "FromDateTime": None, "ToDateTime": None, "Limit": 100, }, callback=handler.store, request_id=self.uuid_factory.generate(), request_timestamp=self.clock.utc_now(), ) # Act self.data_engine.send(request) await asyncio.sleep(1) # Assert self.assertEqual(2, self.data_engine.response_count) self.assertEqual(1, handler.count) # Tear Down self.data_engine.stop() await self.data_engine.get_run_queue_task()
def test_instantiate_given_invalid_bar_spec_raises_value_error(self): # Arrange clock = TestClock() bar_store = ObjectStorer() handler = bar_store.store instrument_id = TestStubs.audusd_id() bar_spec = BarSpecification(100, BarAggregation.TICK, PriceType.MID) bar_type = BarType(instrument_id, bar_spec) # Act # Assert self.assertRaises( ValueError, TimeBarAggregator, bar_type, handler, True, clock, TestLogger(clock), )
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, Logger(TestClock())) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00001"), size=Quantity(1), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123456"), timestamp_ns=0, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00002"), size=Quantity(1), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123457"), timestamp_ns=0, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price("1.00000"), size=Quantity(1), aggressor_side=AggressorSide.BUY, match_id=TradeMatchId("123458"), 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("1.00001"), bar_store.get_store()[0].open) self.assertEqual(Price("1.00002"), bar_store.get_store()[0].high) self.assertEqual(Price("1.00000"), bar_store.get_store()[0].low) self.assertEqual(Price("1.00000"), bar_store.get_store()[0].close) self.assertEqual(Quantity(3), bar_store.get_store()[0].volume)
def test_subscribe_bar_type_then_subscribes(self): # Arrange self.data_engine.register_client(self.binance_client) self.binance_client.connect() bar_spec = BarSpecification(1000, BarAggregation.TICK, PriceType.MID) bar_type = BarType(ETHUSDT_BINANCE.id, bar_spec, internal_aggregation=True) handler = ObjectStorer() subscribe = Subscribe( provider=BINANCE.value, data_type=DataType(Bar, metadata={"BarType": bar_type}), handler=handler.store_2, command_id=self.uuid_factory.generate(), command_timestamp=self.clock.utc_now(), ) # Act self.data_engine.execute(subscribe) # Assert self.assertEqual([bar_type], self.data_engine.subscribed_bars)
def test_update_sends_bar_to_handler(self): # Arrange bar_store = ObjectStorer() handler = bar_store.store_2 symbol = TestStubs.symbol_audusd_fxcm() bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.MID) bar_type = BarType(symbol, bar_spec) aggregator = TickBarAggregator(bar_type, handler, TestLogger(TestClock())) tick1 = QuoteTick(symbol=AUDUSD_FXCM, bid=Price("1.00001"), ask=Price("1.00004"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH) tick2 = QuoteTick(symbol=AUDUSD_FXCM, bid=Price("1.00002"), ask=Price("1.00005"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH) tick3 = QuoteTick(symbol=AUDUSD_FXCM, bid=Price("1.00000"), ask=Price("1.00003"), bid_size=Quantity(1), ask_size=Quantity(1), timestamp=UNIX_EPOCH) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price("1.000025"), bar_store.get_store()[0][1].open) self.assertEqual(Price("1.000035"), bar_store.get_store()[0][1].high) self.assertEqual(Price("1.000015"), bar_store.get_store()[0][1].low) self.assertEqual(Price('1.000015'), bar_store.get_store()[0][1].close) self.assertEqual(Quantity(6), bar_store.get_store()[0][1].volume)
def test_handle_trade_tick_when_volume_beyond_threshold_sends_bars_to_handler( 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(2000), aggressor_side=AggressorSide.BUY, match_id="123456", ts_event_ns=0, ts_recv_ns=0, ) tick2 = TradeTick( instrument_id=instrument.id, price=Price.from_str("1.00002"), size=Quantity.from_int(3000), aggressor_side=AggressorSide.BUY, match_id="123457", ts_event_ns=0, ts_recv_ns=0, ) tick3 = TradeTick( instrument_id=instrument.id, price=Price.from_str("1.00000"), size=Quantity.from_int(25000), aggressor_side=AggressorSide.BUY, match_id="123458", ts_event_ns=0, ts_recv_ns=0, ) # 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.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) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[1].open) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[1].high) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[1].low) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[1].close) self.assertEqual(Quantity.from_int(10000), bar_store.get_store()[1].volume) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[2].open) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[2].high) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[2].low) self.assertEqual(Price.from_str("1.00000"), bar_store.get_store()[2].close) self.assertEqual(Quantity.from_int(10000), bar_store.get_store()[2].volume)
def test_handle_quote_tick_when_count_at_threshold_sends_bar_to_handler( self): # Arrange bar_store = ObjectStorer() handler = bar_store.store instrument = AUDUSD_SIM bar_spec = BarSpecification(3, BarAggregation.TICK, PriceType.MID) bar_type = BarType(instrument.id, bar_spec) aggregator = TickBarAggregator( instrument, bar_type, handler, Logger(TestClock()), ) tick1 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00001"), ask=Price.from_str("1.00004"), bid_size=Quantity.from_int(1), ask_size=Quantity.from_int(1), ts_event_ns=0, ts_recv_ns=0, ) tick2 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00002"), ask=Price.from_str("1.00005"), bid_size=Quantity.from_int(1), ask_size=Quantity.from_int(1), ts_event_ns=0, ts_recv_ns=0, ) tick3 = QuoteTick( instrument_id=instrument.id, bid=Price.from_str("1.00000"), ask=Price.from_str("1.00003"), bid_size=Quantity.from_int(1), ask_size=Quantity.from_int(1), ts_event_ns=0, ts_recv_ns=0, ) # Act aggregator.handle_quote_tick(tick1) aggregator.handle_quote_tick(tick2) aggregator.handle_quote_tick(tick3) # Assert self.assertEqual(1, len(bar_store.get_store())) self.assertEqual(Price.from_str("1.000025"), bar_store.get_store()[0].open) self.assertEqual(Price.from_str("1.000035"), bar_store.get_store()[0].high) self.assertEqual(Price.from_str("1.000015"), bar_store.get_store()[0].low) self.assertEqual(Price.from_str("1.000015"), bar_store.get_store()[0].close) self.assertEqual(Quantity.from_int(3), 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( AUDUSD_SIM, bar_type, handler, Logger(TestClock()), ) tick1 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("20.00001"), size=Quantity.from_str("3000.00"), aggressor_side=AggressorSide.BUY, match_id="123456", ts_event_ns=0, ts_recv_ns=0, ) tick2 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("20.00002"), size=Quantity.from_str("4000.00"), aggressor_side=AggressorSide.BUY, match_id="123457", ts_event_ns=0, ts_recv_ns=0, ) tick3 = TradeTick( instrument_id=AUDUSD_SIM.id, price=Price.from_str("20.00000"), size=Quantity.from_str("5000.00"), aggressor_side=AggressorSide.BUY, match_id="123458", ts_event_ns=0, ts_recv_ns=0, ) # 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.from_str("20.00001"), bar_store.get_store()[0].open) self.assertEqual(Price.from_str("20.00002"), bar_store.get_store()[0].high) self.assertEqual(Price.from_str("20.00001"), bar_store.get_store()[0].low) self.assertEqual(Price.from_str("20.00002"), bar_store.get_store()[0].close) self.assertEqual(Quantity.from_str("5000.00"), bar_store.get_store()[0].volume) self.assertEqual(Price.from_str("20.00002"), bar_store.get_store()[1].open) self.assertEqual(Price.from_str("20.00002"), bar_store.get_store()[1].high) self.assertEqual(Price.from_str("20.00000"), bar_store.get_store()[1].low) self.assertEqual(Price.from_str("20.00000"), bar_store.get_store()[1].close) self.assertEqual(Quantity.from_str("5000.00"), bar_store.get_store()[1].volume) self.assertEqual( Decimal("40000.11000"), aggregator.get_cumulative_value()) # TODO: WIP - Should be 40000