class MsgPackCommandSerializerTests(unittest.TestCase): def setUp(self): # Fixture Setup self.venue = Venue("SIM") self.trader_id = TestStubs.trader_id() self.account_id = TestStubs.account_id() self.serializer = MsgPackCommandSerializer() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S", "001"), clock=TestClock(), ) def test_serialize_and_deserialize_submit_order_commands(self): # Arrange order = self.order_factory.market(AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000)) command = SubmitOrder( self.venue, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), PositionId("P-123456"), order, uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) self.assertEqual(order, deserialized.order) print(command) print(len(serialized)) print(serialized) print(b64encode(serialized)) def test_serialize_and_deserialize_submit_bracket_order_no_take_profit_commands( self): # Arrange entry_order = self.order_factory.market(AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000)) bracket_order = self.order_factory.bracket( entry_order, stop_loss=Price("0.99900"), ) command = SubmitBracketOrder( self.venue, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), bracket_order, uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) self.assertEqual(bracket_order, deserialized.bracket_order) print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_submit_bracket_order_with_take_profit_commands( self): # Arrange entry_order = self.order_factory.limit( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) bracket_order = self.order_factory.bracket( entry_order, stop_loss=Price("0.99900"), take_profit=Price("1.00010"), ) command = SubmitBracketOrder( self.venue, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), bracket_order, uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) self.assertEqual(bracket_order, deserialized.bracket_order) print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_modify_order_commands(self): # Arrange command = ModifyOrder( self.venue, self.trader_id, self.account_id, ClientOrderId("O-123456"), Quantity(100000), Price("1.00001"), uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_cancel_order_commands(self): # Arrange command = CancelOrder( self.venue, self.trader_id, self.account_id, ClientOrderId("O-123456"), uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(command, deserialized) print(b64encode(serialized)) print(command)
class LiveExecutionTests(unittest.TestCase): def setUp(self): # Fixture Setup trader_id = TraderId('TESTER', '000') account_id = TestStubs.account_id() clock = LiveClock() guid_factory = LiveGuidFactory() logger = LiveLogger() self.command_server = MessageServer( server_id=ServerId("CommandServer-001"), recv_port=TEST_COMMANDS_REQ_PORT, send_port=TEST_COMMANDS_REP_PORT, header_serializer=MsgPackDictionarySerializer(), request_serializer=MsgPackRequestSerializer(), response_serializer=MsgPackResponseSerializer(), compressor=CompressorBypass(), encryption=EncryptionSettings(), clock=clock, guid_factory=guid_factory, logger=LoggerAdapter('CommandServer', logger)) self.command_serializer = MsgPackCommandSerializer() self.command_server_sink = [] self.command_server.register_handler(MessageType.COMMAND, self.command_handler) self.command_server.start() time.sleep(0.1) self.portfolio = Portfolio( currency=Currency.USD, clock=clock, guid_factory=guid_factory, logger=logger) self.analyzer = PerformanceAnalyzer() self.exec_db = InMemoryExecutionDatabase( trader_id=trader_id, logger=logger) self.exec_engine = LiveExecutionEngine( trader_id=trader_id, account_id=account_id, database=self.exec_db, portfolio=self.portfolio, clock=clock, guid_factory=guid_factory, logger=logger) self.exec_engine.handle_event(TestStubs.account_event()) self.exec_client = LiveExecClient( exec_engine=self.exec_engine, host=LOCALHOST, command_req_port=TEST_COMMANDS_REQ_PORT, command_res_port=TEST_COMMANDS_REP_PORT, event_pub_port=TEST_EVENTS_PUB_PORT, compressor=CompressorBypass(), encryption=EncryptionSettings(), command_serializer=MsgPackCommandSerializer(), header_serializer=MsgPackDictionarySerializer(), request_serializer=MsgPackRequestSerializer(), response_serializer=MsgPackResponseSerializer(), event_serializer=MsgPackEventSerializer(), clock=clock, guid_factory=guid_factory, logger=logger) self.exec_engine.register_client(self.exec_client) self.exec_client.connect() time.sleep(0.1) self.bar_type = TestStubs.bartype_audusd_1min_bid() self.strategy = TestStrategy1(self.bar_type, id_tag_strategy='001') self.strategy.change_logger(logger) self.exec_engine.register_strategy(self.strategy) def tearDown(self): # Tear Down self.exec_client.disconnect() self.command_server.stop() # Allowing the garbage collector to clean up resources avoids threading # errors caused by the continuous disposal of sockets. Thus for testing # we're avoiding calling .dispose() on the sockets. def command_handler(self, message): command = self.command_serializer.deserialize(message) self.command_server_sink.append(command) def test_can_send_submit_order_command(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Act self.strategy.submit_order(order, self.strategy.position_id_generator.generate()) time.sleep(0.3) # # Assert self.assertEqual(order, self.strategy.order(order.id)) self.assertEqual(2, self.command_server.recv_count) self.assertEqual(1, self.command_server.sent_count) self.assertEqual(SubmitOrder, type(self.command_server_sink[0])) def test_can_send_submit_atomic_order(self): # Arrange atomic_order = self.strategy.order_factory.atomic_market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(0.99900, 5)) # Act self.strategy.submit_atomic_order(atomic_order, self.strategy.position_id_generator.generate()) time.sleep(0.3) # Assert self.assertEqual(atomic_order.entry, self.strategy.order(atomic_order.entry.id)) self.assertEqual(atomic_order.stop_loss, self.strategy.order(atomic_order.stop_loss.id)) self.assertEqual(2, self.command_server.recv_count) self.assertEqual(1, self.command_server.sent_count) self.assertEqual(SubmitAtomicOrder, type(self.command_server_sink[0])) def test_can_send_cancel_order_command(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) # Act self.strategy.submit_order(order, self.strategy.position_id_generator.generate()) self.strategy.cancel_order(order, 'SIGNAL_GONE') time.sleep(0.3) # Assert self.assertEqual(order, self.strategy.order(order.id)) self.assertEqual(3, self.command_server.recv_count) self.assertEqual(1, self.command_server.sent_count) self.assertEqual(SubmitOrder, type(self.command_server_sink[0])) self.assertEqual(CancelOrder, type(self.command_server_sink[1])) def test_can_send_modify_order_command(self): # Arrange order = self.strategy.order_factory.limit( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) # Act self.strategy.submit_order(order, self.strategy.position_id_generator.generate()) self.strategy.modify_order(order, Quantity(110000), Price(1.00001, 5)) time.sleep(0.3) # Assert self.assertEqual(order, self.strategy.order(order.id)) self.assertEqual(3, self.command_server.recv_count) self.assertEqual(1, self.command_server.sent_count) self.assertEqual(SubmitOrder, type(self.command_server_sink[0])) self.assertEqual(ModifyOrder, type(self.command_server_sink[1])) def test_can_send_account_inquiry_command(self): # Arrange # Act self.strategy.account_inquiry() time.sleep(0.3) # Assert self.assertEqual(2, self.command_server.recv_count) self.assertEqual(1, self.command_server.sent_count) self.assertEqual(AccountInquiry, type(self.command_server_sink[0]))
class MessageClientTests(unittest.TestCase): def setUp(self): # Fixture Setup clock = LiveClock() guid_factory = LiveGuidFactory() logger = LiveLogger() self.context = zmq.Context() self.client_sink = [] self.server_sink = [] self.server = MessageServer( ServerId("Server-001"), TEST_RECV_PORT, TEST_SEND_PORT, MsgPackDictionarySerializer(), MsgPackRequestSerializer(), MsgPackResponseSerializer(), CompressorBypass(), EncryptionSettings(), clock, guid_factory, LoggerAdapter('MessageServer', logger)) # Register test handlers self.server.register_handler(MessageType.STRING, self.server_sink.append) self.server.start() self.command_serializer = MsgPackCommandSerializer() self.server.register_handler(MessageType.COMMAND, self.command_handler) self.client = MessageClient( ClientId("Trader-001"), LOCALHOST, TEST_RECV_PORT, TEST_SEND_PORT, MsgPackDictionarySerializer(), MsgPackRequestSerializer(), MsgPackResponseSerializer(), CompressorBypass(), EncryptionSettings(), clock, guid_factory, LoggerAdapter('MessageClient', logger)) self.client.register_handler(self.client_sink.append) def tearDown(self): # Tear Down self.client.disconnect() self.server.stop() # Allowing the garbage collector to clean up resources avoids threading # errors caused by the continuous disposal of sockets. Thus for testing # we're avoiding calling .dispose() on the sockets. def command_handler(self, message): command = self.command_serializer.deserialize(message) self.server_sink.append(command) def test_can_connect_to_server_and_receive_response(self): # Arrange # Act self.client.connect() time.sleep(0.1) # Assert self.assertTrue(self.client.is_connected()) def test_can_send_one_string_message(self): # Arrange self.client.connect() # Act self.client.send_string('hello') time.sleep(0.1) # Assert self.assertEqual(2, self.client.sent_count) self.assertEqual(2, self.client.recv_count) self.assertEqual(2, self.server.sent_count) self.assertEqual(2, self.server.recv_count) self.assertEqual(1, len(self.client_sink)) self.assertEqual(1, len(self.server_sink)) self.assertEqual('hello', self.server_sink[0]) self.assertEqual('OK', self.client_sink[0]) def test_can_send_multiple_messages_and_receive_correctly_ordered_responses(self): # Arrange self.client.connect() # Act self.client.send_string('hello1') self.client.send_string('hello2') self.client.send_string('hello3') time.sleep(0.1) # Assert self.assertEqual(4, self.client.sent_count) self.assertEqual(4, self.client.recv_count) self.assertEqual(4, self.server.sent_count) self.assertEqual(4, self.server.recv_count) self.assertEqual(3, len(self.client_sink)) self.assertEqual(3, len(self.server_sink)) self.assertEqual('hello1', self.server_sink[0]) self.assertEqual('hello2', self.server_sink[1]) self.assertEqual('hello3', self.server_sink[2]) self.assertEqual('OK', self.client_sink[0]) self.assertEqual('OK', self.client_sink[1]) self.assertEqual('OK', self.client_sink[2])
class TestMsgPackCommandSerializer: def setup(self): # Fixture Setup self.venue = Venue("SIM") self.trader_id = TestStubs.trader_id() self.account_id = TestStubs.account_id() self.serializer = MsgPackCommandSerializer() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S", "001"), clock=TestClock(), ) def test_serialize_and_deserialize_submit_order_commands(self): # Arrange order = self.order_factory.market(AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000)) command = SubmitOrder( order.instrument_id.venue.client_id, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), PositionId("P-123456"), order, uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command assert deserialized.order == order print(command) print(len(serialized)) print(serialized) print(b64encode(serialized)) def test_serialize_and_deserialize_submit_bracket_order_no_take_profit_commands( self, ): # Arrange entry_order = self.order_factory.market(AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000)) bracket_order = self.order_factory.bracket( entry_order, stop_loss=Price("0.99900"), take_profit=Price("1.00100"), ) command = SubmitBracketOrder( entry_order.instrument_id.venue.client_id, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), bracket_order, uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command assert deserialized.bracket_order == bracket_order print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_submit_bracket_order_with_take_profit_commands( self, ): # Arrange entry_order = self.order_factory.limit( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) bracket_order = self.order_factory.bracket( entry_order, stop_loss=Price("0.99900"), take_profit=Price("1.00010"), ) command = SubmitBracketOrder( entry_order.instrument_id.venue.client_id, self.trader_id, self.account_id, StrategyId("SCALPER", "01"), bracket_order, uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command assert deserialized.bracket_order == bracket_order print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_amend_order_commands(self): # Arrange command = UpdateOrder( AUDUSD_SIM.id.venue.client_id, self.trader_id, self.account_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), Quantity(100000), Price("1.00001"), uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command print(b64encode(serialized)) print(command) def test_serialize_and_deserialize_cancel_order_commands(self): # Arrange command = CancelOrder( AUDUSD_SIM.id.venue.client_id, self.trader_id, self.account_id, AUDUSD_SIM.id, ClientOrderId("O-123456"), VenueOrderId("001"), uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command print(b64encode(serialized)) print(command)