def test_execute_command(self): order = self.strategy.order_factory.market( BTCUSDT_BINANCE.symbol, OrderSide.BUY, Quantity("1.00000000"), ) command = SubmitOrder( order.symbol.venue, self.trader_id, self.account_id, self.strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.utc_now(), ) def execute_command(): self.exec_engine.execute(command) PerformanceHarness.profile_function(execute_command, 10000, 1)
async def run_test(): # Arrange self.risk_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER-000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order = strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) submit_order = SubmitOrder( self.trader_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.timestamp_ns(), ) # Act self.risk_engine.execute(submit_order) await asyncio.sleep(0.1) # Assert assert self.risk_engine.qsize() == 0 assert self.risk_engine.command_count == 1 # Tear Down self.risk_engine.stop()
def test_submit_order_when_block_all_orders_true_then_denies_order(self): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order = strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), ) submit_order = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.utc_now(), ) self.risk_engine.set_block_all_orders() # Act self.exec_engine.execute(submit_order) # Assert assert self.exec_client.calls == ['connect'] assert self.exec_engine.event_count == 1
def test_submit_order_when_not_connected_logs_and_does_not_send(self): # Arrange strategy = TradingStrategy("000") order = self.order_factory.market( ETHUSDT_BINANCE.id, OrderSide.BUY, Quantity.from_int(100), ) command = SubmitOrder( self.trader_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.timestamp_ns(), ) # Act self.exec_client.submit_order(command) # Assert assert order.state == OrderState.INITIALIZED
def test_can_submit_order(self): # Arrange strategy = TradingStrategy(order_id_tag='001') strategy.change_clock(self.clock) self.exec_engine.register_strategy(strategy) position_id = strategy.position_id_generator.generate() order = strategy.order_factory.market(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000)) submit_order = SubmitOrder(self.trader_id, self.account_id, strategy.id, position_id, order, self.guid_factory.generate(), self.clock.time_now()) # Act self.exec_engine.execute_command(submit_order) # Assert self.assertIn(submit_order, self.exec_client.received_commands) self.assertTrue(self.exec_db.order_exists(order.id)) self.assertEqual(position_id, self.exec_db.get_position_id(order.id))
def test_submit_order(self): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order = strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) submit_order = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.utc_now(), ) # Act self.exec_engine.execute(submit_order) # Assert self.assertIn(submit_order, self.exec_client.commands) self.assertTrue(self.cache.order_exists(order.cl_ord_id))
def submit_order_command(): return SubmitOrder( client_id=BetfairTestStubs.instrument_id().venue.client_id, trader_id=BetfairTestStubs.trader_id(), account_id=BetfairTestStubs.account_id(), strategy_id=BetfairTestStubs.strategy_id(), position_id=BetfairTestStubs.position_id(), order=LimitOrder( client_order_id=ClientOrderId( f"O-20210410-022422-001-001-{BetfairTestStubs.strategy_id().value}" ), strategy_id=BetfairTestStubs.strategy_id(), instrument_id=BetfairTestStubs.instrument_id(), order_side=OrderSide.BUY, quantity=Quantity(10), price=Price(0.33, 5), time_in_force=TimeInForce.GTC, expire_time=None, init_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), ), command_id=BetfairTestStubs.uuid(), timestamp_ns=BetfairTestStubs.clock().timestamp_ns(), )
def test_handle_order_fill_event(self): # Arrange strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), clock=self.clock, uuid_factory=TestUUIDFactory(), logger=self.logger, ) self.exec_engine.register_strategy(strategy) order = strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) submit_order = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.py_null(), order, self.uuid_factory.generate(), self.clock.utc_now(), ) self.exec_engine.execute(submit_order) # Act self.exec_engine.process(TestStubs.event_order_submitted(order)) self.exec_engine.process(TestStubs.event_order_accepted(order)) self.exec_engine.process(TestStubs.event_order_filled(order)) expected_position_id = PositionId( "O-19700101-000000-000-001-1") # Stubbed from order id? # Assert self.assertTrue(self.cache.position_exists(expected_position_id)) self.assertTrue(self.cache.is_position_open(expected_position_id)) self.assertFalse(self.cache.is_position_closed(expected_position_id)) self.assertFalse( self.exec_engine.cache.is_flat(strategy_id=strategy.id)) self.assertFalse(self.exec_engine.cache.is_flat()) self.assertEqual(Position, type(self.cache.position(expected_position_id))) self.assertTrue(expected_position_id in self.cache.position_ids()) self.assertTrue( expected_position_id not in self.cache.position_closed_ids( strategy_id=strategy.id)) self.assertTrue( expected_position_id not in self.cache.position_closed_ids()) self.assertTrue(expected_position_id in self.cache.position_open_ids( strategy_id=strategy.id)) self.assertTrue(expected_position_id in self.cache.position_open_ids()) self.assertEqual(1, self.cache.positions_total_count()) self.assertEqual(1, self.cache.positions_open_count()) self.assertEqual(0, self.cache.positions_closed_count()) self.assertTrue(self.cache.position_exists_for_order(order.cl_ord_id))
def test_flip_position_on_opposite_filled_same_position_buy(self): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order1 = strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), ) order2 = strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(150000), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) position_id = PositionId("P-000-AUD/USD.SIM-1") self.exec_engine.execute(submit_order1) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, AUDUSD_SIM, position_id)) submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, position_id, order2, self.uuid_factory.generate(), self.clock.utc_now(), ) # Act self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, AUDUSD_SIM, position_id)) position_id_flipped = PositionId("P-000-AUD/USD.SIM-1F") # Assert position_flipped = self.cache.position(position_id_flipped) self.assertEqual(50000, position_flipped.relative_quantity) self.assertTrue(self.cache.position_exists(position_id)) self.assertTrue(self.cache.position_exists(position_id_flipped)) self.assertTrue(self.cache.is_position_closed(position_id)) self.assertTrue(self.cache.is_position_open(position_id_flipped)) self.assertIn(position_id, self.cache.position_ids()) self.assertIn(position_id, self.cache.position_ids(strategy_id=strategy.id)) self.assertIn(position_id_flipped, self.cache.position_ids()) self.assertIn(position_id_flipped, self.cache.position_ids(strategy_id=strategy.id)) self.assertEqual(2, self.cache.positions_total_count()) self.assertEqual(1, self.cache.positions_open_count()) self.assertEqual(1, self.cache.positions_closed_count())
def test_multiple_strategy_positions_one_active_one_closed(self): # Arrange self.exec_engine.start() strategy1 = TradingStrategy(order_id_tag="001") strategy1.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) strategy2 = TradingStrategy(order_id_tag="002") strategy2.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy1) self.exec_engine.register_strategy(strategy2) order1 = strategy1.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order2 = strategy1.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), Price("1.00000"), ) order3 = strategy2.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy1.id, PositionId.null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) position_id1 = PositionId('P-1') submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy1.id, position_id1, order2, self.uuid_factory.generate(), self.clock.utc_now(), ) submit_order3 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy2.id, PositionId.null(), order3, self.uuid_factory.generate(), self.clock.utc_now(), ) position_id2 = PositionId('P-2') # Act self.exec_engine.execute(submit_order1) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, AUDUSD_SIM, position_id1)) self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, AUDUSD_SIM, position_id1)) self.exec_engine.execute(submit_order3) self.exec_engine.process(TestStubs.event_order_submitted(order3)) self.exec_engine.process(TestStubs.event_order_accepted(order3)) self.exec_engine.process( TestStubs.event_order_filled(order3, AUDUSD_SIM, position_id2)) # Assert # Already tested .is_position_active and .is_position_closed above self.assertTrue(self.cache.position_exists(position_id1)) self.assertTrue(self.cache.position_exists(position_id2)) self.assertIn(position_id1, self.cache.position_ids(strategy_id=strategy1.id)) self.assertIn(position_id2, self.cache.position_ids(strategy_id=strategy2.id)) self.assertIn(position_id1, self.cache.position_ids()) self.assertIn(position_id2, self.cache.position_ids()) self.assertEqual( 0, len(self.cache.positions_open(strategy_id=strategy1.id))) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy2.id))) self.assertEqual(1, len(self.cache.positions_open())) self.assertEqual(1, len(self.cache.positions_closed())) self.assertEqual(2, len(self.cache.positions())) self.assertNotIn( position_id1, self.cache.position_open_ids(strategy_id=strategy1.id)) self.assertIn(position_id2, self.cache.position_open_ids(strategy_id=strategy2.id)) self.assertNotIn(position_id1, self.cache.position_open_ids()) self.assertIn(position_id2, self.cache.position_open_ids()) self.assertIn(position_id1, self.cache.position_closed_ids(strategy_id=strategy1.id)) self.assertNotIn( position_id2, self.cache.position_closed_ids(strategy_id=strategy2.id)) self.assertIn(position_id1, self.cache.position_closed_ids()) self.assertNotIn(position_id2, self.cache.position_closed_ids()) self.assertEqual(2, self.cache.positions_total_count()) self.assertEqual(1, self.cache.positions_open_count()) self.assertEqual(1, self.cache.positions_closed_count())
def test_close_position_on_order_fill(self): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order1 = strategy.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order2 = strategy.order_factory.stop_market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), Price("1.00000"), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) position_id = PositionId("P-1") self.exec_engine.execute(submit_order1) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, AUDUSD_SIM, position_id)) submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, position_id, order2, self.uuid_factory.generate(), self.clock.utc_now(), ) # Act self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, AUDUSD_SIM, position_id)) # # Assert self.assertTrue(self.cache.position_exists(position_id)) self.assertFalse(self.cache.is_position_open(position_id)) self.assertTrue(self.cache.is_position_closed(position_id)) self.assertEqual(position_id, self.cache.position(position_id).id) self.assertEqual(position_id, self.cache.positions(strategy_id=strategy.id)[0].id) self.assertEqual(position_id, self.cache.positions()[0].id) self.assertEqual( 0, len(self.cache.positions_open(strategy_id=strategy.id))) self.assertEqual(0, len(self.cache.positions_open())) self.assertEqual( position_id, self.cache.positions_closed(strategy_id=strategy.id)[0].id) self.assertEqual(position_id, self.cache.positions_closed()[0].id) self.assertNotIn(position_id, self.cache.position_open_ids(strategy_id=strategy.id)) self.assertNotIn(position_id, self.cache.position_open_ids()) self.assertEqual(1, self.cache.positions_total_count()) self.assertEqual(0, self.cache.positions_open_count()) self.assertEqual(1, self.cache.positions_closed_count())
def test_add_to_existing_position_on_order_fill(self): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order1 = strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) order2 = strategy.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) self.exec_engine.execute(submit_order1) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, AUDUSD_SIM)) expected_position_id = PositionId( "O-19700101-000000-000-001-1") # Stubbed from order id? submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, expected_position_id, order2, self.uuid_factory.generate(), self.clock.utc_now(), ) # Act self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, AUDUSD_SIM, expected_position_id)) # Assert self.assertTrue( self.cache.position_exists( TestStubs.event_order_filled( order1, AUDUSD_SIM, ).position_id)) self.assertTrue(self.cache.is_position_open(expected_position_id)) self.assertFalse(self.cache.is_position_closed(expected_position_id)) self.assertEqual(Position, type(self.cache.position(expected_position_id))) self.assertEqual( 0, len(self.cache.positions_closed(strategy_id=strategy.id))) self.assertEqual(0, len(self.cache.positions_closed())) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy.id))) self.assertEqual(1, len(self.cache.positions_open())) self.assertEqual(1, self.cache.positions_total_count()) self.assertEqual(1, self.cache.positions_open_count()) self.assertEqual(0, self.cache.positions_closed_count())
async def run_test(): # Arrange self.engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), self.clock, self.logger, ) self.engine.register_strategy(strategy) order = strategy.order_factory.limit( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) submit_order = SubmitOrder( AUDUSD_SIM.id, self.trader_id, self.account_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.timestamp_ns(), ) self.engine.execute(submit_order) self.engine.process(TestStubs.event_order_submitted(order)) self.engine.process(TestStubs.event_order_accepted(order)) report = OrderStatusReport( client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), # <-- from stub event order_state=OrderState.FILLED, filled_qty=Quantity(100000), timestamp_ns=0, ) trade1 = ExecutionReport( execution_id=ExecutionId("1"), client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), last_qty=Decimal(50000), last_px=Decimal("1.00000"), commission_amount=Decimal("5.0"), commission_currency="USD", liquidity_side=LiquiditySide.MAKER, execution_ns=0, timestamp_ns=0, ) trade2 = ExecutionReport( execution_id=ExecutionId("2"), client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), last_qty=Decimal(50000), last_px=Decimal("1.00000"), commission_amount=Decimal("2.0"), commission_currency="USD", liquidity_side=LiquiditySide.MAKER, execution_ns=0, timestamp_ns=0, ) self.client.add_order_status_report(report) self.client.add_trades_list(VenueOrderId("1"), [trade1, trade2]) await asyncio.sleep(0.01) # Act result = await self.engine.reconcile_state() self.engine.stop() # Assert assert result
def test_multiple_strategy_positions_opened(self): # Arrange strategy1 = TradingStrategy(order_id_tag="001") strategy1.register_trader( TraderId("TESTER", "000"), clock=self.clock, uuid_factory=TestUUIDFactory(), logger=self.logger, ) strategy2 = TradingStrategy(order_id_tag="002") strategy2.register_trader( TraderId("TESTER", "000"), clock=self.clock, uuid_factory=TestUUIDFactory(), logger=self.logger, ) self.exec_engine.register_strategy(strategy1) self.exec_engine.register_strategy(strategy2) order1 = strategy1.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order2 = strategy2.order_factory.stop( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy1.id, PositionId.py_null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy2.id, PositionId.py_null(), order2, self.uuid_factory.generate(), self.clock.utc_now(), ) position1_id = PositionId('P-1') position2_id = PositionId('P-2') # Act self.exec_engine.execute(submit_order1) self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, position1_id)) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, position2_id)) # Assert self.assertTrue(self.cache.position_exists(position1_id)) self.assertTrue(self.cache.position_exists(position2_id)) self.assertTrue(self.cache.is_position_open(position1_id)) self.assertTrue(self.cache.is_position_open(position2_id)) self.assertFalse(self.cache.is_position_closed(position1_id)) self.assertFalse(self.cache.is_position_closed(position2_id)) self.assertFalse(self.cache.is_flat(strategy_id=strategy1.id)) self.assertFalse(self.cache.is_flat(strategy_id=strategy2.id)) self.assertFalse(self.cache.is_flat()) self.assertEqual(Position, type(self.cache.position(position1_id))) self.assertEqual(Position, type(self.cache.position(position2_id))) self.assertTrue(position1_id in self.cache.position_ids( strategy_id=strategy1.id)) self.assertTrue(position2_id in self.cache.position_ids( strategy_id=strategy2.id)) self.assertTrue(position1_id in self.cache.position_ids()) self.assertTrue(position2_id in self.cache.position_ids()) self.assertEqual(2, len(self.cache.position_open_ids())) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy1.id))) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy2.id))) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy2.id))) self.assertEqual(2, len(self.cache.positions_open())) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy1.id))) self.assertEqual( 1, len(self.cache.positions_open(strategy_id=strategy2.id))) self.assertTrue(position1_id in self.cache.position_open_ids( strategy_id=strategy1.id)) self.assertTrue(position2_id in self.cache.position_open_ids( strategy_id=strategy2.id)) self.assertTrue(position1_id in self.cache.position_open_ids()) self.assertTrue(position2_id in self.cache.position_open_ids()) self.assertTrue(position1_id not in self.cache.position_closed_ids( strategy_id=strategy1.id)) self.assertTrue(position2_id not in self.cache.position_closed_ids( strategy_id=strategy2.id)) self.assertTrue(position1_id not in self.cache.position_closed_ids()) self.assertTrue(position2_id not in self.cache.position_closed_ids()) self.assertEqual(2, self.cache.positions_total_count()) self.assertEqual(2, self.cache.positions_open_count()) self.assertEqual(0, self.cache.positions_closed_count())
async def run_test(): # Arrange self.exec_engine.start() strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER-000"), self.clock, self.logger, ) self.exec_engine.register_strategy(strategy) order = strategy.order_factory.limit( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), Price.from_str("1.00000"), ) submit_order = SubmitOrder( self.trader_id, strategy.id, PositionId.null(), order, self.uuid_factory.generate(), self.clock.timestamp_ns(), ) self.exec_engine.execute(submit_order) self.exec_engine.process(TestStubs.event_order_submitted(order)) self.exec_engine.process(TestStubs.event_order_accepted(order)) report = OrderStatusReport( client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), # <-- from stub event order_state=OrderState.PARTIALLY_FILLED, filled_qty=Quantity.from_int(70000), timestamp_ns=0, ) trade1 = ExecutionReport( client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), execution_id=ExecutionId("1"), last_qty=Quantity.from_int(50000), last_px=Price.from_str("1.00000"), commission=Money(5.00, USD), liquidity_side=LiquiditySide.MAKER, ts_filled_ns=0, timestamp_ns=0, ) trade2 = ExecutionReport( client_order_id=order.client_order_id, venue_order_id=VenueOrderId("1"), execution_id=ExecutionId("2"), last_qty=Quantity.from_int(20000), last_px=Price.from_str("1.00000"), commission=Money(2.00, USD), liquidity_side=LiquiditySide.MAKER, ts_filled_ns=0, timestamp_ns=0, ) self.client.add_order_status_report(report) self.client.add_trades_list(VenueOrderId("1"), [trade1, trade2]) await asyncio.sleep(0.01) # Act result = await self.exec_engine.reconcile_state(timeout_secs=10) self.exec_engine.stop() # Assert assert result
def test_multiple_strategy_positions_one_active_one_closed(self): # Arrange strategy1 = TradingStrategy(order_id_tag='001') strategy2 = TradingStrategy(order_id_tag='002') position_id1 = strategy1.position_id_generator.generate() position_id2 = strategy2.position_id_generator.generate() self.exec_engine.register_strategy(strategy1) self.exec_engine.register_strategy(strategy2) order1 = strategy1.order_factory.stop(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) order2 = strategy1.order_factory.stop(AUDUSD_FXCM, OrderSide.SELL, Quantity(100000), Price(1.00000, 5)) order3 = strategy2.order_factory.stop(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) submit_order1 = SubmitOrder(self.trader_id, self.account_id, strategy1.id, position_id1, order1, self.guid_factory.generate(), self.clock.time_now()) submit_order2 = SubmitOrder(self.trader_id, self.account_id, strategy1.id, position_id1, order2, self.guid_factory.generate(), self.clock.time_now()) submit_order3 = SubmitOrder(self.trader_id, self.account_id, strategy2.id, position_id2, order3, self.guid_factory.generate(), self.clock.time_now()) order1_filled = TestStubs.event_order_filled(order1) order2_filled = TestStubs.event_order_filled(order2) order3_filled = OrderFilled(self.account_id, order3.id, ExecutionId('E3'), PositionIdBroker('T3'), AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5), Currency.USD, UNIX_EPOCH, GUID(uuid.uuid4()), UNIX_EPOCH) # Act self.exec_engine.execute_command(submit_order1) self.exec_engine.execute_command(submit_order2) self.exec_engine.execute_command(submit_order3) self.exec_engine.handle_event(order1_filled) self.exec_engine.handle_event(order2_filled) self.exec_engine.handle_event(order3_filled) # Assert # Already tested .is_position_active and .is_position_closed above self.assertTrue(self.exec_db.position_exists(position_id1)) self.assertTrue(self.exec_db.position_exists(position_id2)) self.assertTrue(self.exec_engine.is_strategy_flat(strategy1.id)) self.assertFalse(self.exec_engine.is_strategy_flat(strategy2.id)) self.assertFalse(self.exec_engine.is_flat()) self.assertTrue( position_id1 in self.exec_db.get_positions(strategy1.id)) self.assertTrue( position_id2 in self.exec_db.get_positions(strategy2.id)) self.assertTrue(position_id1 in self.exec_db.get_positions()) self.assertTrue(position_id2 in self.exec_db.get_positions()) self.assertEqual(0, len(self.exec_db.get_positions_open(strategy1.id))) self.assertEqual(1, len(self.exec_db.get_positions_open(strategy2.id))) self.assertEqual(1, len(self.exec_db.get_positions_open())) self.assertEqual(1, len(self.exec_db.get_positions_closed())) self.assertEqual(2, len(self.exec_db.get_positions())) self.assertTrue( position_id1 not in self.exec_db.get_positions_open(strategy1.id)) self.assertTrue( position_id2 in self.exec_db.get_positions_open(strategy2.id)) self.assertTrue(position_id1 not in self.exec_db.get_positions_open()) self.assertTrue(position_id2 in self.exec_db.get_positions_open()) self.assertTrue( position_id1 in self.exec_db.get_positions_closed(strategy1.id)) self.assertTrue(position_id2 not in self.exec_db.get_positions_closed( strategy2.id)) self.assertTrue(position_id1 in self.exec_db.get_positions_closed()) self.assertTrue( position_id2 not in self.exec_db.get_positions_closed()) self.assertEqual(2, self.exec_db.count_positions_total()) self.assertEqual(1, self.exec_db.count_positions_open()) self.assertEqual(1, self.exec_db.count_positions_closed())
def test_multiple_strategy_positions_opened(self): # Arrange strategy1 = TradingStrategy(order_id_tag='001') strategy2 = TradingStrategy(order_id_tag='002') position1_id = strategy1.position_id_generator.generate() position2_id = strategy2.position_id_generator.generate() self.exec_engine.register_strategy(strategy1) self.exec_engine.register_strategy(strategy2) order1 = strategy1.order_factory.stop(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) order2 = strategy2.order_factory.stop(AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), Price(1.00000, 5)) submit_order1 = SubmitOrder(self.trader_id, self.account_id, strategy1.id, position1_id, order1, self.guid_factory.generate(), self.clock.time_now()) submit_order2 = SubmitOrder(self.trader_id, self.account_id, strategy2.id, position2_id, order2, self.guid_factory.generate(), self.clock.time_now()) order1_filled = TestStubs.event_order_filled(order1) order2_filled = TestStubs.event_order_filled(order2) # Act self.exec_engine.execute_command(submit_order1) self.exec_engine.execute_command(submit_order2) self.exec_engine.handle_event(order1_filled) self.exec_engine.handle_event(order2_filled) # Assert self.assertTrue(self.exec_db.position_exists(position1_id)) self.assertTrue(self.exec_db.position_exists(position2_id)) self.assertTrue(self.exec_db.is_position_open(position1_id)) self.assertTrue(self.exec_db.is_position_open(position2_id)) self.assertFalse(self.exec_db.is_position_closed(position1_id)) self.assertFalse(self.exec_db.is_position_closed(position2_id)) self.assertFalse(self.exec_engine.is_strategy_flat(strategy1.id)) self.assertFalse(self.exec_engine.is_strategy_flat(strategy2.id)) self.assertFalse(self.exec_engine.is_flat()) self.assertEqual(Position, type(self.exec_db.get_position(position1_id))) self.assertEqual(Position, type(self.exec_db.get_position(position2_id))) self.assertTrue( position1_id in self.exec_db.get_positions(strategy1.id)) self.assertTrue( position2_id in self.exec_db.get_positions(strategy2.id)) self.assertTrue(position1_id in self.exec_db.get_positions()) self.assertTrue(position2_id in self.exec_db.get_positions()) self.assertEqual(1, len(self.exec_db.get_positions_open(strategy1.id))) self.assertEqual(1, len(self.exec_db.get_positions_open(strategy2.id))) self.assertEqual(2, len(self.exec_db.get_positions_open())) self.assertEqual(1, len(self.exec_db.get_positions_open(strategy1.id))) self.assertEqual(1, len(self.exec_db.get_positions_open(strategy2.id))) self.assertTrue( position1_id in self.exec_db.get_positions_open(strategy1.id)) self.assertTrue( position2_id in self.exec_db.get_positions_open(strategy2.id)) self.assertTrue(position1_id in self.exec_db.get_positions_open()) self.assertTrue(position2_id in self.exec_db.get_positions_open()) self.assertTrue(position1_id not in self.exec_db.get_positions_closed( strategy1.id)) self.assertTrue(position2_id not in self.exec_db.get_positions_closed( strategy2.id)) self.assertTrue( position1_id not in self.exec_db.get_positions_closed()) self.assertTrue( position2_id not in self.exec_db.get_positions_closed()) self.assertEqual(2, self.exec_db.count_positions_total()) self.assertEqual(2, self.exec_db.count_positions_open()) self.assertEqual(0, self.exec_db.count_positions_closed())
def test_flip_position_on_opposite_filled_same_position(self): # Arrange strategy = TradingStrategy(order_id_tag="001") strategy.register_trader( TraderId("TESTER", "000"), clock=self.clock, uuid_factory=TestUUIDFactory(), logger=self.logger, ) self.exec_engine.register_strategy(strategy) order1 = strategy.order_factory.market( AUDUSD_FXCM, OrderSide.BUY, Quantity(100000), ) order2 = strategy.order_factory.market( AUDUSD_FXCM, OrderSide.SELL, Quantity(150000), ) submit_order1 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, PositionId.py_null(), order1, self.uuid_factory.generate(), self.clock.utc_now(), ) position_id = PositionId("P-000-AUD/USD.FXCM-1") self.exec_engine.execute(submit_order1) self.exec_engine.process(TestStubs.event_order_submitted(order1)) self.exec_engine.process(TestStubs.event_order_accepted(order1)) self.exec_engine.process( TestStubs.event_order_filled(order1, position_id)) submit_order2 = SubmitOrder( self.venue, self.trader_id, self.account_id, strategy.id, position_id, order2, self.uuid_factory.generate(), self.clock.utc_now(), ) # Act self.exec_engine.execute(submit_order2) self.exec_engine.process(TestStubs.event_order_submitted(order2)) self.exec_engine.process(TestStubs.event_order_accepted(order2)) self.exec_engine.process( TestStubs.event_order_filled(order2, position_id)) position_id_flipped = PositionId("P-000-AUD/USD.FXCM-1F") order_id_flipped = ClientOrderId(order2.cl_ord_id.value + 'F') # Assert self.assertTrue(self.cache.position_exists(position_id)) self.assertTrue(self.cache.position_exists(position_id_flipped)) self.assertTrue(self.cache.is_position_closed(position_id)) self.assertTrue(self.cache.is_position_open(position_id_flipped)) self.assertFalse(self.cache.is_flat(strategy_id=strategy.id)) self.assertTrue(position_id in self.cache.position_ids()) self.assertTrue(position_id in self.cache.position_ids( strategy_id=strategy.id)) self.assertTrue(position_id_flipped in self.cache.position_ids()) self.assertTrue(position_id_flipped in self.cache.position_ids( strategy_id=strategy.id)) self.assertTrue(order_id_flipped, self.cache.position_exists_for_order(order_id_flipped)) self.assertEqual(2, self.cache.positions_total_count()) self.assertEqual(1, self.cache.positions_open_count()) self.assertEqual(1, self.cache.positions_closed_count())