def test_can_receive_tick_data(self): # Arrange data_receiver = ObjectStorer() self.data_client.request_ticks(AUDUSD_FXCM, UNIX_EPOCH.date(), UNIX_EPOCH.date(), limit=0, callback=data_receiver.store) time.sleep(0.2) tick = Tick(AUDUSD_FXCM, Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), UNIX_EPOCH) ticks = [tick, tick, tick, tick, tick] tick_data = self.data_mapper.map_ticks(ticks) data = self.data_serializer.serialize(tick_data) data_response = DataResponse(data, 'Tick[]', 'BSON', self.data_client.last_request_id, GUID(uuid.uuid4()), UNIX_EPOCH) # Act self.data_server.send_response(data_response, self.data_client.client_id) time.sleep(0.1) response = data_receiver.get_store()[0] # Assert self.assertEqual(ticks, response)
def test_position_filled_with_buy_order_returns_expected_attributes(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order_filled = OrderFilled( self.account_id, order.id, ExecutionId('E123456'), PositionIdBroker('T123456'), order.symbol, order.side, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) last = Tick(AUDUSD_FXCM, Price(1.00050, 5), Price(1.00048, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act position = Position(PositionId('P-123456'), order_filled) # Assert self.assertEqual(OrderId('O-19700101-000000-001-001-1'), position.from_order_id) self.assertEqual(Quantity(100000), position.quantity) self.assertEqual(Quantity(100000), position.peak_quantity) self.assertEqual(OrderSide.BUY, position.entry_direction) self.assertEqual(MarketPosition.LONG, position.market_position) self.assertEqual(UNIX_EPOCH, position.opened_time) self.assertIsNone(position.open_duration) self.assertEqual(1.00001, position.average_open_price) self.assertEqual(1, position.event_count) self.assertEqual([order.id], position.get_order_ids()) self.assertEqual([ExecutionId('E123456')], position.get_execution_ids()) self.assertEqual(ExecutionId('E123456'), position.last_execution_id) self.assertEqual(PositionIdBroker('T123456'), position.id_broker) self.assertTrue(position.is_long) self.assertFalse(position.is_short) self.assertFalse(position.is_closed) self.assertEqual(0.0, position.realized_points) self.assertEqual(0.0, position.realized_return) self.assertEqual(Money(0, Currency.USD), position.realized_pnl) self.assertEqual(0.0004899999999998794, position.unrealized_points(last)) self.assertEqual(0.0004899951000488789, position.unrealized_return(last)) self.assertEqual(Money(49.00, Currency.USD), position.unrealized_pnl(last)) self.assertEqual(0.0004899999999998794, position.total_points(last)) self.assertEqual(0.0004899951000488789, position.total_return(last)) self.assertEqual(Money(49.00, Currency.USD), position.total_pnl(last))
def test_position_filled_with_sell_order_returns_expected_attributes(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000)) order_filled = OrderFilled( self.account_id, order.id, ExecutionId('E123456'), PositionIdBroker('T123456'), order.symbol, order.side, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) last = Tick(AUDUSD_FXCM, Price(1.00050, 5), Price(1.00048, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act position = Position(PositionId('P-123456'), order_filled) # Assert self.assertEqual(Quantity(100000), position.quantity) self.assertEqual(Quantity(100000), position.peak_quantity) self.assertEqual(MarketPosition.SHORT, position.market_position) self.assertEqual(UNIX_EPOCH, position.opened_time) self.assertEqual(1.00001, position.average_open_price) self.assertEqual(1, position.event_count) self.assertEqual(ExecutionId('E123456'), position.last_execution_id) self.assertEqual(PositionIdBroker('T123456'), position.id_broker) self.assertFalse(position.is_long) self.assertTrue(position.is_short) self.assertFalse(position.is_closed) self.assertEqual(0.0, position.realized_points) self.assertEqual(0.0, position.realized_return) self.assertEqual(Money(0, Currency.USD), position.realized_pnl) self.assertEqual(-0.00046999999999997044, position.unrealized_points(last)) self.assertEqual(-0.0004699953000469699, position.unrealized_return(last)) self.assertEqual(Money(-47.00, Currency.USD), position.unrealized_pnl(last)) self.assertEqual(-0.00046999999999997044, position.total_points(last)) self.assertEqual(-0.0004699953000469699, position.total_return(last)) self.assertEqual(Money(-47.00, Currency.USD), position.total_pnl(last))
def test_can_parse_tick_from_string(self): # Arrange tick = Tick(AUDUSD_FXCM, Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act result = Tick.py_from_string(AUDUSD_FXCM.value + ',' + str(tick)) # Assert self.assertEqual(tick, result)
def test_can_get_tick(self): strategy = TradingStrategy(order_id_tag='001') tick = Tick(Symbol('AUDUSD', Venue('FXCM')), Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), datetime(2018, 1, 1, 19, 59, 1, 0, timezone.utc)) strategy.handle_tick(tick) # Act result = strategy.tick(AUDUSD_FXCM, 0) # Assert self.assertEqual(tick, result)
def test_get_exchange_rate_returns_correct_rate(self): # Arrange tick = Tick(USDJPY_FXCM, Price(110.80000, 5), Price(110.80010, 5), Volume(1), Volume(1), datetime(2018, 1, 1, 19, 59, 1, 0, timezone.utc)) self.client._handle_tick(tick) # Act result = self.client.get_exchange_rate(Currency.JPY, Currency.USD) # Assert self.assertEqual(0.009025266685348969, result)
def test_can_get_exchange_rate_with_no_conversion(self): # Arrange tick = Tick(AUDUSD_FXCM, Price(0.80000, 5), Price(0.80010, 5), Volume(1), Volume(1), datetime(2018, 1, 1, 19, 59, 1, 0, timezone.utc)) self.client._handle_tick(tick) # Act result = self.client.get_exchange_rate(Currency.AUD, Currency.USD) # Assert self.assertEqual(0.80005, result)
def test_can_request_bar_data(self): # Arrange data_receiver = ObjectStorer() bar_type = TestStubs.bartype_audusd_1min_bid() self.data_client.request_bars(bar_type, UNIX_EPOCH.date(), UNIX_EPOCH.date(), limit=0, callback=data_receiver.store_2) time.sleep(0.1) bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH) bars = [bar, bar, bar, bar, bar] bar_data = self.data_mapper.map_bars(bars, bar_type) data = self.data_serializer.serialize(bar_data) data_response = DataResponse(data, 'Bar[]', 'BSON', self.data_client.last_request_id, GUID(uuid.uuid4()), UNIX_EPOCH) # Act self.data_server.send_response(data_response, self.data_client.client_id) time.sleep(0.2) response = data_receiver.get_store()[0] # Assert self.assertEqual(bar_type, response[0]) self.assertEqual(bars, response[1])
def test_tick_str_and_repr(self): # Arrange tick = Tick(AUDUSD_FXCM, Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act result0 = str(tick) result1 = repr(tick) # Assert self.assertEqual('1.00000,1.00001,1,1,1970-01-01T00:00:00.000Z', result0) self.assertTrue(result1.startswith('<Tick(AUDUSD.FXCM,1.00000,1.00001,1,1,1970-01-01T00:00:00.000Z) object at')) self.assertTrue(result1.endswith('>'))
def build_bar_no_checking(): bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH, check=False)
def build_bar_with_checking(): bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH, check=True)
def test_can_serialize_and_deserialize_ticks(self): # Arrange tick = Tick(AUDUSD_FXCM, Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), UNIX_EPOCH) data = self.mapper.map_ticks([tick]) # Act serialized = self.serializer.serialize(data) print(type(data)) print(data) print(type(serialized)) deserialized = self.serializer.deserialize(serialized) print(deserialized) # Assert self.assertEqual(data, deserialized)
def test_can_receive_published_tick_data(self): # Arrange data_receiver = ObjectStorer() tick = Tick(AUDUSD_FXCM, Price(1.00000, 5), Price(1.00001, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act self.data_client.subscribe_ticks(AUDUSD_FXCM, handler=data_receiver.store) time.sleep(0.1) self.tick_publisher.publish(AUDUSD_FXCM.value, Utf8TickSerializer.py_serialize(tick)) time.sleep(0.1) # Assert self.assertEqual(1, len(data_receiver.get_store())) self.assertEqual(tick, data_receiver.get_store()[0])
def test_getting_bar_at_out_of_range_index_raises_exception(self): # Arrange strategy = TradingStrategy(order_id_tag='001') bar_type = TestStubs.bartype_gbpusd_1sec_mid() bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), datetime(1970, 1, 1, 00, 00, 0, 0, timezone.utc)) strategy.handle_bar(bar_type, bar) # Act # Assert self.assertRaises(IndexError, strategy.bar, bar_type, -2)
def test_can_get_bar(self): strategy = TradingStrategy(order_id_tag='001') bar_type = TestStubs.bartype_gbpusd_1sec_mid() bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), datetime(1970, 1, 1, 00, 00, 0, 0, timezone.utc)) strategy.handle_bar(bar_type, bar) # Act result = strategy.bar(bar_type, 0) # Assert self.assertEqual(bar, result)
def test_can_update_bars_and_indicators(self): # Arrange bar_type = TestStubs.bartype_gbpusd_1sec_mid() strategy = TestStrategy1(bar_type) bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), datetime(1970, 1, 1, 00, 00, 0, 0, timezone.utc)) # Act strategy.handle_bar(bar_type, bar) # Assert self.assertEqual(1, len(strategy.bars(bar_type))) self.assertEqual(1, strategy.ema1.count) self.assertEqual(1, strategy.ema2.count) self.assertEqual(0, len(strategy.object_storer.get_store()))
def test_can_serialize_and_deserialize_bars(self): # Arrange bar_type = TestStubs.bartype_audusd_1min_bid() bar1 = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH) data = self.mapper.map_bars([bar1, bar1], bar_type) # Act serialized = self.serializer.serialize(data) print(type(data)) print(data) print(type(serialized)) deserialized = self.serializer.deserialize(serialized) print(deserialized) # Assert self.assertEqual(data, deserialized)
def test_can_receive_published_bar_data(self): # Arrange self.data_client.connect() data_receiver = ObjectStorer() bar_type = TestStubs.bartype_audusd_1min_bid() bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH) # Act self.data_client.subscribe_bars(bar_type, handler=data_receiver.store_2) time.sleep(0.1) self.data_publisher.publish('Bar:' + str(bar_type), Utf8BarSerializer.py_serialize(bar)) time.sleep(0.1) # Assert self.assertEqual(1, len(data_receiver.get_store())) self.assertEqual((bar_type, bar), data_receiver.get_store()[0])
def test_can_deserialize_bar_data_response_from_csharp(self): # Arrange # Base64 bytes string from C# MsgPack.Cli bar_type = TestStubs.bartype_audusd_1min_bid() bar1 = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), UNIX_EPOCH) data = self.mapper.map_bars([bar1, bar1], bar_type) # Act serialized = self.serializer.serialize(data) print(type(data)) print(data) print(type(serialized)) deserialized = self.serializer.deserialize(serialized) print(deserialized) # Assert self.assertEqual(data, deserialized)
def test_can_reset_strategy(self): # Arrange bar_type = TestStubs.bartype_audusd_1min_bid() strategy = TestStrategy1(bar_type) bar_type = TestStubs.bartype_gbpusd_1sec_mid() bar = Bar(Price(1.00001, 5), Price(1.00004, 5), Price(1.00002, 5), Price(1.00003, 5), Volume(100000), datetime(1970, 1, 1, 00, 00, 0, 0, timezone.utc)) strategy.handle_bar(bar_type, bar) # Act strategy.reset() # Assert self.assertFalse(strategy.is_running) self.assertEqual(0, strategy.ema1.count) self.assertEqual(0, strategy.ema2.count) self.assertTrue( 'custom reset logic' in strategy.object_storer.get_store())
def test_position_filled_with_buy_order_then_sell_order_returns_expected_attributes(self): # Arrange order = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order_filled1 = OrderFilled( self.account_id, order.id, ExecutionId('E1'), PositionIdBroker('T123456'), order.symbol, OrderSide.BUY, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) position = Position(PositionId('P-123456'), order_filled1) order_filled2 = OrderFilled( self.account_id, order.id, ExecutionId('E2'), PositionIdBroker('T123456'), order.symbol, OrderSide.SELL, order.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH + timedelta(minutes=1), GUID(uuid.uuid4()), UNIX_EPOCH) last = Tick(AUDUSD_FXCM, Price(1.00050, 5), Price(1.00048, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act position.apply(order_filled2) # Assert self.assertEqual(Quantity(), position.quantity) self.assertEqual(MarketPosition.FLAT, position.market_position) self.assertEqual(UNIX_EPOCH, position.opened_time) self.assertEqual(timedelta(minutes=1), position.open_duration) self.assertEqual(1.00001, position.average_open_price) self.assertEqual(2, position.event_count) self.assertEqual(ExecutionId('E2'), position.last_execution_id) self.assertEqual(PositionIdBroker('T123456'), position.id_broker) self.assertEqual(datetime.datetime(1970, 1, 1, 0, 1, tzinfo=datetime.timezone.utc), position.closed_time) self.assertEqual(1.00001, position.average_close_price) self.assertFalse(position.is_long) self.assertFalse(position.is_short) self.assertTrue(position.is_closed) self.assertEqual(0.0, position.realized_points) self.assertEqual(0.0, position.realized_return) self.assertEqual(Money(0, Currency.USD), position.realized_pnl) self.assertEqual(0.0, position.unrealized_points(last)) self.assertEqual(0.0, position.unrealized_return(last)) self.assertEqual(Money(0, Currency.USD), position.unrealized_pnl(last)) self.assertEqual(0.0, position.total_points(last)) self.assertEqual(0.0, position.total_return(last)) self.assertEqual(Money(0, Currency.USD), position.total_pnl(last))
def test_position_filled_with_sell_order_then_buy_order_returns_expected_attributes(self): # Arrange order1 = self.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(100000)) order2 = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order_filled1 = OrderFilled( self.account_id, order1.id, ExecutionId('E123456'), PositionIdBroker('T123456'), order1.symbol, order1.side, order1.quantity, Price(1.00000, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) position = Position(PositionId('P-123456'), order_filled1) order_filled2 = OrderPartiallyFilled( self.account_id, order2.id, ExecutionId('E1234561'), PositionIdBroker('T123456'), order2.symbol, order2.side, Quantity(50000), Quantity(50000), Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) order_filled3 = OrderPartiallyFilled( self.account_id, order2.id, ExecutionId('E1234562'), PositionIdBroker('T123456'), order2.symbol, order2.side, Quantity(100000), Quantity(), Price(1.00003, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) last = Tick(AUDUSD_FXCM, Price(1.00050, 5), Price(1.00048, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act position.apply(order_filled2) position.apply(order_filled3) # Assert self.assertEqual(Quantity(), position.quantity) self.assertEqual(MarketPosition.FLAT, position.market_position) self.assertEqual(UNIX_EPOCH, position.opened_time) self.assertEqual(1.0, position.average_open_price) self.assertEqual(3, position.event_count) self.assertEqual([order1.id, order2.id], position.get_order_ids()) self.assertEqual(ExecutionId('E1234562'), position.last_execution_id) self.assertEqual(PositionIdBroker('T123456'), position.id_broker) self.assertEqual(UNIX_EPOCH, position.closed_time) self.assertEqual(1.00003, position.average_close_price) self.assertFalse(position.is_long) self.assertFalse(position.is_short) self.assertTrue(position.is_closed) self.assertEqual(-2.999999999997449e-05, position.realized_points) self.assertEqual(-2.999999999997449e-05, position.realized_return) self.assertEqual(Money(-3.000, Currency.USD), position.realized_pnl) self.assertEqual(0.0, position.unrealized_points(last)) self.assertEqual(0.0, position.unrealized_return(last)) self.assertEqual(Money(00, Currency.USD), position.unrealized_pnl(last)) self.assertEqual(-2.999999999997449e-05, position.total_points(last)) self.assertEqual(-2.999999999997449e-05, position.total_return(last)) self.assertEqual(Money(-3.000, Currency.USD), position.total_pnl(last))
def test_position_long_with_multiple_filled_orders_returns_expected_attributes(self): # Arrange order1 = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order2 = self.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) order3 = self.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(200000)) order1_filled = OrderFilled( self.account_id, order1.id, ExecutionId('E1'), PositionIdBroker('T123456'), order1.symbol, order1.side, order1.quantity, Price(1.00000, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) order2_filled = OrderFilled( self.account_id, order2.id, ExecutionId('E2'), PositionIdBroker('T123456'), order2.symbol, order2.side, order2.quantity, Price(1.00001, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) order3_filled = OrderFilled( self.account_id, order3.id, ExecutionId('E3'), PositionIdBroker('T123456'), order3.symbol, order3.side, order3.quantity, Price(1.00010, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) last = Tick(AUDUSD_FXCM, Price(1.00050, 5), Price(1.00048, 5), Volume(1), Volume(1), UNIX_EPOCH) # Act position = Position(PositionId('P-123456'), order1_filled) position.apply(order2_filled) position.apply(order3_filled) # Assert self.assertEqual(Quantity(), position.quantity) self.assertEqual(MarketPosition.FLAT, position.market_position) self.assertEqual(UNIX_EPOCH, position.opened_time) self.assertEqual(1.000005, position.average_open_price) self.assertEqual(3, position.event_count) self.assertEqual([order1.id, order2.id, order3.id], position.get_order_ids()) self.assertEqual(ExecutionId('E3'), position.last_execution_id) self.assertEqual(PositionIdBroker('T123456'), position.id_broker) self.assertEqual(UNIX_EPOCH, position.closed_time) self.assertEqual(1.0001, position.average_close_price) self.assertFalse(position.is_long) self.assertFalse(position.is_short) self.assertTrue(position.is_closed) self.assertEqual(9.499999999995623e-05, position.realized_points) self.assertEqual(9.499952500233122e-05, position.realized_return) self.assertEqual(Money(19.000, Currency.USD), position.realized_pnl) self.assertEqual(0.0, position.unrealized_points(last)) self.assertEqual(0.0, position.unrealized_return(last)) self.assertEqual(Money(00, Currency.USD), position.unrealized_pnl(last)) self.assertEqual(9.499999999995623e-05, position.total_points(last)) self.assertEqual(9.499952500233122e-05, position.total_return(last)) self.assertEqual(Money(19.000, Currency.USD), position.total_pnl(last))