def test_order_initialized(self): # Arrange uuid = uuid4() event = OrderInitialized(cl_ord_id=ClientOrderId("O-2020872378423"), strategy_id=StrategyId("SCALPER", "001"), symbol=Symbol("BTC/USDT", Exchange("BINANCE")), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, quantity=Quantity("0.561000"), time_in_force=TimeInForce.DAY, event_id=uuid, event_timestamp=UNIX_EPOCH, options={"Price": "15200.10"}) # Act # Assert self.assertEqual( f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})", str(event)) self.assertEqual( f"OrderInitialized(cl_ord_id=O-2020872378423, id={uuid})", repr(event))
def test_calculate_pnl_when_given_position_side_flat_returns_zero(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.symbol, OrderSide.BUY, Quantity(12), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("10500.00"), ) position = Position(fill) # Act result = position.calculate_pnl(Price("10500.00"), Price("10500.00"), Quantity(100000)) # Assert self.assertEqual(Money(0, USDT), result)
def test_calculate_pnl_for_inverse2(self): # Arrange order = self.order_factory.market( ETHUSD_BITMEX.id, OrderSide.SELL, Quantity.from_int(100000), ) fill = TestStubs.event_order_filled( order, instrument=ETHUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("375.95"), ) position = Position(instrument=ETHUSD_BITMEX, fill=fill) # Act, Assert self.assertEqual(Money(4.27745208, ETH), position.unrealized_pnl(Price.from_str("370.00"))) self.assertEqual(Money(270.27027027, ETH), position.notional_value(Price.from_str("370.00")))
def test_order_serializer_methods_raise_not_implemented_error(self): # Arrange order_factory = OrderFactory( trader_id=TraderId("TESTER-000"), strategy_id=StrategyId("S-001"), clock=TestClock(), ) order = order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000, precision=0), ) serializer = OrderSerializer() # Act # Assert with pytest.raises(NotImplementedError): serializer.serialize(order) with pytest.raises(NotImplementedError): serializer.deserialize(bytes())
def test_serialize_and_deserialize_stop_orders_with_expire_time(self): # Arrange order = StopMarketOrder( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH, init_id=uuid4(), timestamp=UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(order) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(order, deserialized) print(b64encode(serialized)) print(order)
def test_order_denied_event_to_from_dict_and_str_repr(self): # Arrange uuid = UUID4() event = OrderDenied( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("SCALPER-001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), client_order_id=ClientOrderId("O-2020872378423"), reason="Exceeded MAX_ORDER_RATE", event_id=uuid, ts_init=0, ) # Act, Assert assert OrderDenied.from_dict(OrderDenied.to_dict(event)) == event assert ( str(event) == "OrderDenied(instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, reason=Exceeded MAX_ORDER_RATE)" # noqa ) assert ( repr(event) == f"OrderDenied(trader_id=TRADER-001, strategy_id=SCALPER-001, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, reason=Exceeded MAX_ORDER_RATE, event_id={uuid}, ts_init=0)" # noqa )
def test_serialize_and_deserialize_limit_orders_with_expire_time(self): # Arrange order = LimitOrder( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), time_in_force=TimeInForce.GTD, expire_time=UNIX_EPOCH, init_id=uuid4(), timestamp_ns=0, ) # Act serialized = self.serializer.serialize(order) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == order print(b64encode(serialized)) print(order)
def test_serialize_and_deserialize_amend_order_commands(self): # Arrange command = UpdateOrder( self.trader_id, StrategyId("SCALPER-001"), AUDUSD_SIM.id, ClientOrderId("O-123456"), VenueOrderId("001"), Quantity(100000, precision=0), Price(1.00001, precision=5), None, uuid4(), 0, ) # Act serialized = self.serializer.serialize(command) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == command print(b64encode(serialized)) print(command)
def test_calculate_pnl_for_short_position_loss(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.SELL, Quantity.from_str("10"), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10500.00"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) # Act pnl = position.calculate_pnl( Price.from_str("10500.00"), Price.from_str("10670.50"), Quantity.from_str("10.000000"), ) # Assert self.assertEqual(Money(-1705.00000000, USDT), pnl) self.assertEqual( Money(-1705.00000000, USDT), position.unrealized_pnl(Price.from_str("10670.50")), ) self.assertEqual(Money(-105.00000000, USDT), position.realized_pnl) self.assertEqual([Money(105.00000000, USDT)], position.commissions()) self.assertEqual( Money(106705.00000000, USDT), position.notional_value(Price.from_str("10670.50")), )
def test_serialize_and_deserialize_stop_limit_orders(self): # Arrange order = StopLimitOrder( ClientOrderId("O-123456"), StrategyId("S-001"), AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000, precision=0), price=Price(1.00000, precision=5), trigger=Price(1.00010, precision=5), time_in_force=TimeInForce.GTC, expire_time=None, init_id=uuid4(), timestamp_ns=0, ) # Act serialized = self.serializer.serialize(order) deserialized = self.serializer.deserialize(serialized) # Assert assert deserialized == order print(b64encode(serialized)) print(order)
def setUp(self): # Fixture Setup self.clock = LiveClock() self.uuid_factory = UUIDFactory() self.logger = TestLogger(self.clock) self.trader_id = TraderId("TESTER", "000") self.account_id = TestStubs.account_id() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S", "001"), clock=self.clock, ) self.portfolio = Portfolio( clock=self.clock, logger=self.logger, ) self.portfolio.register_cache(DataCache(self.logger)) self.analyzer = PerformanceAnalyzer() # Fresh isolated loop testing pattern self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) database = BypassExecutionDatabase(trader_id=self.trader_id, logger=self.logger) self.exec_engine = LiveExecutionEngine( loop=self.loop, database=database, portfolio=self.portfolio, clock=self.clock, logger=self.logger, )
def test_calculate_unrealized_pnl_for_short(self): # Arrange order = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.SELL, Quantity.from_str("5.912000"), ) fill = TestStubs.event_order_filled( order, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("10505.60"), ) position = Position(instrument=BTCUSDT_BINANCE, fill=fill) pnl = position.unrealized_pnl(Price.from_str("10407.15")) # Assert self.assertEqual(Money(582.03640000, USDT), pnl) self.assertEqual(Money(-62.10910720, USDT), position.realized_pnl) self.assertEqual([Money(62.10910720, USDT)], position.commissions())
def test_calculate_pnl_for_inverse2(self): # Arrange order = self.order_factory.market( ETHUSD_BITMEX.id, OrderSide.SELL, Quantity(100000), ) fill = TestStubs.event_order_filled( order, instrument=ETHUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), last_px=Price("375.95"), ) position = Position(fill=fill) # Act # Assert self.assertEqual(Money(1582.66, USD), position.unrealized_pnl(Price("370.00"))) self.assertEqual(Money(100000.00, USD), position.notional_value(Price("370.00")))
def test_order_filled_event_to_from_dict_and_str_repr(self): # Arrange uuid = UUID4() event = OrderFilled( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("SCALPER-001"), account_id=AccountId("SIM", "000"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), client_order_id=ClientOrderId("O-2020872378423"), venue_order_id=VenueOrderId("123456"), execution_id=ExecutionId("1"), position_id=PositionId("2"), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, last_qty=Quantity.from_str("0.561000"), last_px=Price.from_str("15600.12445"), currency=USDT, commission=Money(12.20000000, USDT), liquidity_side=LiquiditySide.MAKER, ts_event=0, event_id=uuid, ts_init=0, ) # Act, Assert assert event.is_buy assert not event.is_sell assert OrderFilled.from_dict(OrderFilled.to_dict(event)) == event assert ( str(event) == "OrderFilled(account_id=SIM-000, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, venue_order_id=123456, execution_id=1, position_id=2, order_side=BUY, order_type=LIMIT, last_qty=0.561000, last_px=15600.12445 USDT, commission=12.20000000 USDT, liquidity_side=MAKER, ts_event=0)" # noqa ) assert ( repr(event) == f"OrderFilled(trader_id=TRADER-001, strategy_id=SCALPER-001, account_id=SIM-000, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, venue_order_id=123456, execution_id=1, position_id=2, order_side=BUY, order_type=LIMIT, last_qty=0.561000, last_px=15600.12445 USDT, commission=12.20000000 USDT, liquidity_side=MAKER, event_id={uuid}, ts_event=0, ts_init=0)" # noqa )
def test_order_submitted_event_to_from_dict_and_str_repr(self): # Arrange uuid = UUID4() event = OrderSubmitted( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("SCALPER-001"), account_id=AccountId("SIM", "000"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), client_order_id=ClientOrderId("O-2020872378423"), ts_event=0, event_id=uuid, ts_init=0, ) # Act, Assert assert OrderSubmitted.from_dict(OrderSubmitted.to_dict(event)) == event assert ( str(event) == "OrderSubmitted(account_id=SIM-000, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, ts_event=0)" # noqa ) assert ( repr(event) == f"OrderSubmitted(trader_id=TRADER-001, strategy_id=SCALPER-001, account_id=SIM-000, instrument_id=BTC/USDT.BINANCE, client_order_id=O-2020872378423, event_id={uuid}, ts_event=0, ts_init=0)" # noqa )
def test_position_hash_str_repr(self): # Arrange order = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) fill = TestEventStubs.order_filled( order, instrument=AUDUSD_SIM, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00001"), ) position = Position(instrument=AUDUSD_SIM, fill=fill) # Act, Assert assert isinstance(hash(position), int) assert str( position) == "Position(LONG 100_000 AUD/USD.SIM, id=P-123456)" assert repr( position) == "Position(LONG 100_000 AUD/USD.SIM, id=P-123456)"
def test_add_order(self): # Arrange order = self.strategy.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) position_id = PositionId("P-1") # Act self.cache.add_order(order, position_id) # Assert self.assertIn(order.client_order_id, self.cache.client_order_ids()) self.assertIn( order.client_order_id, self.cache.client_order_ids(instrument_id=order.instrument_id), ) self.assertIn( order.client_order_id, self.cache.client_order_ids(strategy_id=self.strategy.id), ) self.assertNotIn( order.client_order_id, self.cache.client_order_ids(strategy_id=StrategyId("S-ZX1")), ) self.assertIn( order.client_order_id, self.cache.client_order_ids(instrument_id=order.instrument_id, strategy_id=self.strategy.id), ) self.assertIn(order, self.cache.orders()) self.assertEqual(VenueOrderId.null(), self.cache.venue_order_id(order.client_order_id)) self.assertIsNone(self.cache.client_order_id(order.venue_order_id))
def test_cancel_order_command_to_from_dict_and_str_repr(self): # Arrange uuid = self.uuid_factory.generate() command = CancelOrder( trader_id=TraderId("TRADER-001"), strategy_id=StrategyId("S-001"), instrument_id=AUDUSD_SIM.id, client_order_id=ClientOrderId("O-123456"), venue_order_id=VenueOrderId("001"), command_id=uuid, ts_init=self.clock.timestamp_ns(), ) # Act, Assert assert CancelOrder.from_dict(CancelOrder.to_dict(command)) == command assert ( str(command) == "CancelOrder(instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001)" # noqa ) assert ( repr(command) == f"CancelOrder(client_id=SIM, trader_id=TRADER-001, strategy_id=S-001, instrument_id=AUD/USD.SIM, client_order_id=O-123456, venue_order_id=001, command_id={uuid}, ts_init=0)" # noqa )
def test_order_filled(self): # Arrange uuid = uuid4() event = OrderFilled( account_id=AccountId("SIM", "000"), client_order_id=ClientOrderId("O-2020872378423"), venue_order_id=VenueOrderId("123456"), execution_id=ExecutionId("1"), position_id=PositionId("2"), strategy_id=StrategyId("SCALPER-001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), order_side=OrderSide.BUY, last_qty=Quantity.from_str("0.561000"), last_px=Price.from_str("15600.12445"), currency=USDT, commission=Money(12.20000000, USDT), liquidity_side=LiquiditySide.MAKER, execution_ns=0, event_id=uuid, timestamp_ns=0, ) print(event) # Act assert ( f"OrderFilled(account_id=SIM-000, client_order_id=O-2020872378423, " f"venue_order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"instrument_id=BTC/USDT.BINANCE, side=BUY-MAKER, last_qty=0.561000, " f"last_px=15600.12445, " f"commission=12.20000000 USDT, event_id={uuid})" == str(event)) assert ( f"OrderFilled(account_id=SIM-000, client_order_id=O-2020872378423, " f"venue_order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"instrument_id=BTC/USDT.BINANCE, side=BUY-MAKER, last_qty=0.561000, " f"last_px=15600.12445, " f"commission=12.20000000 USDT, event_id={uuid})" == repr(event))
def test_order_filled(self): # Arrange uuid = uuid4() event = OrderFilled( account_id=AccountId("SIM", "000"), cl_ord_id=ClientOrderId("O-2020872378423"), order_id=OrderId("123456"), execution_id=ExecutionId("1"), position_id=PositionId("2"), strategy_id=StrategyId("SCALPER", "001"), symbol=Symbol("BTC/USDT", Exchange("BINANCE")), order_side=OrderSide.BUY, fill_qty=Quantity("0.561000"), cum_qty=Quantity("0.561000"), leaves_qty=Quantity(0), fill_price=Price("15600.12445"), currency=USDT, is_inverse=False, commission=Money("12.20000000", USDT), liquidity_side=LiquiditySide.MAKER, execution_time=UNIX_EPOCH, event_id=uuid, event_timestamp=UNIX_EPOCH, ) # Act self.assertEqual(f"OrderFilled(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"symbol=BTC/USDT.BINANCE, side=BUY-MAKER, fill_qty=0.561000, " f"fill_price=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, event_id={uuid})", str(event)) # noqa self.assertEqual(f"OrderFilled(account_id=SIM-000, cl_ord_id=O-2020872378423, " f"order_id=123456, position_id=2, strategy_id=SCALPER-001, " f"symbol=BTC/USDT.BINANCE, side=BUY-MAKER, fill_qty=0.561000, " f"fill_price=15600.12445 USDT, cum_qty=0.561000, leaves_qty=0, " f"commission=12.20000000 USDT, event_id={uuid})", repr(event)) # noqa
def test_serialize_and_deserialize_order_initialized_events(self): # Arrange options = {'Price': '1.0005'} event = OrderInitialized( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.symbol, OrderSide.SELL, OrderType.STOP_MARKET, Quantity(100000), TimeInForce.DAY, uuid4(), UNIX_EPOCH, options=options, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(deserialized, event) self.assertEqual(options, event.options)
def test_order_initialized(self): # Arrange uuid = uuid4() event = OrderInitialized( client_order_id=ClientOrderId("O-2020872378423"), strategy_id=StrategyId("SCALPER", "001"), instrument_id=InstrumentId(Symbol("BTC/USDT"), Venue("BINANCE")), order_side=OrderSide.BUY, order_type=OrderType.LIMIT, quantity=Quantity("0.561000"), time_in_force=TimeInForce.DAY, event_id=uuid, timestamp_ns=0, options={"Price": "15200.10"}, ) # Act # Assert assert ( f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})" == str(event)) assert ( f"OrderInitialized(client_order_id=O-2020872378423, strategy_id=SCALPER-001, event_id={uuid})" == repr(event))
def setup(self): # Fixture Setup self.loop = asyncio.get_event_loop() self.loop.set_debug(True) self.clock = LiveClock() self.uuid_factory = UUIDFactory() self.logger = Logger(self.clock) self.trader_id = TestStubs.trader_id() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S-001"), clock=self.clock, ) self.random_order_factory = OrderFactory( trader_id=TraderId("RANDOM-042"), strategy_id=StrategyId("S-042"), clock=self.clock, ) self.msgbus = MessageBus( trader_id=self.trader_id, clock=self.clock, logger=self.logger, ) self.cache = TestStubs.cache() self.portfolio = Portfolio( msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.data_engine = LiveDataEngine( loop=self.loop, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.exec_engine = LiveExecutionEngine( loop=self.loop, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.risk_engine = LiveRiskEngine( loop=self.loop, portfolio=self.portfolio, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.instrument_provider = InstrumentProvider() self.instrument_provider.add(AUDUSD_SIM) self.instrument_provider.add(GBPUSD_SIM) self.client = MockLiveExecutionClient( loop=self.loop, client_id=ClientId(SIM.value), venue_type=VenueType.ECN, account_id=TestStubs.account_id(), account_type=AccountType.CASH, base_currency=USD, instrument_provider=self.instrument_provider, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.portfolio.update_account(TestStubs.event_cash_account_state()) self.exec_engine.register_client(self.client) self.cache.add_instrument(AUDUSD_SIM)
def test_get_realized_pnls_when_all_flat_positions_returns_expected_series( self): # Arrange order1 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) order2 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), ) order3 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.BUY, Quantity(100000), ) order4 = self.order_factory.market( AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), ) fill1 = TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=PositionId("P-1"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00000"), ) fill2 = TestStubs.event_order_filled( order2, instrument=AUDUSD_SIM, position_id=PositionId("P-1"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00010"), ) fill3 = TestStubs.event_order_filled( order3, instrument=AUDUSD_SIM, position_id=PositionId("P-2"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00000"), ) fill4 = TestStubs.event_order_filled( order4, instrument=AUDUSD_SIM, position_id=PositionId("P-2"), strategy_id=StrategyId("S", "001"), fill_price=Price("1.00020"), ) position1 = Position(fill1) position1.apply(fill2) position2 = Position(fill3) position2.apply(fill4) self.analyzer.add_positions([position1, position2]) # Act result = self.analyzer.get_realized_pnls() # Assert self.assertEqual(2, len(result)) self.assertEqual(6.0, result['P-1']) self.assertEqual(16.0, result['P-2'])
def setup(self): # Fixture Setup self.loop = asyncio.get_event_loop() self.loop.set_debug(True) self.clock = LiveClock() self.uuid_factory = UUIDFactory() self.logger = Logger(self.clock) self.trader_id = TestStubs.trader_id() self.account_id = TestStubs.account_id() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S-001"), clock=self.clock, ) self.random_order_factory = OrderFactory( trader_id=TraderId("RANDOM-042"), strategy_id=StrategyId("S-042"), clock=self.clock, ) self.msgbus = MessageBus( trader_id=self.trader_id, clock=self.clock, logger=self.logger, ) self.cache = TestStubs.cache() self.portfolio = Portfolio( msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.data_engine = LiveDataEngine( loop=self.loop, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.exec_engine = LiveExecutionEngine( loop=self.loop, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.risk_engine = LiveRiskEngine( loop=self.loop, portfolio=self.portfolio, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) self.exec_client = MockExecutionClient( client_id=ClientId("SIM"), venue_type=VenueType.ECN, account_id=TestStubs.account_id(), account_type=AccountType.MARGIN, base_currency=USD, msgbus=self.msgbus, cache=self.cache, clock=self.clock, logger=self.logger, ) # Wire up components self.exec_engine.register_client(self.exec_client)
def position_which_is_closed(position_id, close_price=None) -> Position: if close_price is None: close_price = Price("1.0001") order_factory = OrderFactory( strategy_id=StrategyId("S", "001"), id_tag_trader=IdTag("001"), id_tag_strategy=IdTag("001"), ) order = order_factory.market( TestStubs.symbol_audusd_fxcm(), OrderSide.SELL, Quantity(100000), ) filled1 = OrderFilled( TestStubs.account_id(), order.cl_ord_id, OrderId("1"), ExecutionId(order.cl_ord_id.value.replace('O', 'E')), position_id, StrategyId("S", "1"), order.symbol, order.side, order.quantity, Quantity(), close_price, Money(0, USD), LiquiditySide.TAKER, USD, # Stub event USD, # Stub event UNIX_EPOCH + timedelta(minutes=5), uuid4(), UNIX_EPOCH + timedelta(minutes=5), ) filled2 = OrderFilled( TestStubs.account_id(), order.cl_ord_id, OrderId("2"), ExecutionId(order.cl_ord_id.value.replace('O', 'E')), position_id, StrategyId("S", "1"), order.symbol, OrderSide.BUY, order.quantity, Quantity(), close_price, Money(0, USD), LiquiditySide.TAKER, USD, # Stub event USD, # Stub event UNIX_EPOCH + timedelta(minutes=5), uuid4(), UNIX_EPOCH + timedelta(minutes=5), ) position = Position(filled1) position.apply(filled2) return position
def test_strategy_id_given_malformed_string_raises_value_error(self): # Arrange, Act, Assert with pytest.raises(ValueError): StrategyId("BAD_STRING")
def test_calculate_pnls_for_multi_currency_cash_account_btcusdt(self): # Arrange event = AccountState( account_id=AccountId("SIM", "001"), account_type=AccountType.CASH, base_currency=None, # Multi-currency reported=True, balances=[ AccountBalance( Money(10.00000000, BTC), Money(0.00000000, BTC), Money(10.00000000, BTC), ), AccountBalance( Money(20.00000000, ETH), Money(0.00000000, ETH), Money(20.00000000, ETH), ), ], margins=[], info={}, # No default currency set event_id=UUID4(), ts_event=0, ts_init=0, ) account = CashAccount(event) order1 = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.SELL, Quantity.from_str("0.50000000"), ) fill1 = TestEventStubs.order_filled( order1, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("45500.00"), ) position = Position(BTCUSDT_BINANCE, fill1) # Act result1 = account.calculate_pnls( instrument=BTCUSDT_BINANCE, position=position, fill=fill1, ) order2 = self.order_factory.market( BTCUSDT_BINANCE.id, OrderSide.BUY, Quantity.from_str("0.50000000"), ) fill2 = TestEventStubs.order_filled( order2, instrument=BTCUSDT_BINANCE, position_id=PositionId("P-123456"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("45500.00"), ) position.apply(fill2) result2 = account.calculate_pnls( instrument=BTCUSDT_BINANCE, position=position, fill=fill2, ) # Assert assert result1 == [ Money(-0.50000000, BTC), Money(22727.25000000, USDT) ] assert result2 == [ Money(0.50000000, BTC), Money(-22772.75000000, USDT) ]
def setup(self): # Fixture Setup self.clock = LiveClock() self.uuid_factory = UUIDFactory() self.logger = Logger(self.clock) self.trader_id = TraderId("TESTER", "000") self.account_id = TestStubs.account_id() self.order_factory = OrderFactory( trader_id=self.trader_id, strategy_id=StrategyId("S", "001"), clock=self.clock, ) self.random_order_factory = OrderFactory( trader_id=TraderId("RANDOM", "042"), strategy_id=StrategyId("S", "042"), clock=self.clock, ) self.portfolio = Portfolio( clock=self.clock, logger=self.logger, ) self.portfolio.register_cache(DataCache(self.logger)) self.analyzer = PerformanceAnalyzer() # Fresh isolated loop testing pattern self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.database = BypassExecutionDatabase(trader_id=self.trader_id, logger=self.logger) self.exec_engine = LiveExecutionEngine( loop=self.loop, database=self.database, portfolio=self.portfolio, clock=self.clock, logger=self.logger, ) self.venue = Venue("SIM") self.exec_client = MockExecutionClient( self.venue.value, self.account_id, self.exec_engine, self.clock, self.logger, ) self.risk_engine = LiveRiskEngine( loop=self.loop, exec_engine=self.exec_engine, portfolio=self.portfolio, clock=self.clock, logger=self.logger, config={}, ) self.exec_engine.register_client(self.exec_client) self.exec_engine.register_risk_engine(self.risk_engine)
def test_get_realized_pnls_when_all_flat_positions_returns_expected_series( self): # Arrange order1 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) order2 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.SELL, Quantity.from_int(100000), ) order3 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.BUY, Quantity.from_int(100000), ) order4 = self.order_factory.market( AUDUSD_SIM.id, OrderSide.SELL, Quantity.from_int(100000), ) fill1 = TestStubs.event_order_filled( order1, instrument=AUDUSD_SIM, position_id=PositionId("P-1"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00000"), ) fill2 = TestStubs.event_order_filled( order2, instrument=AUDUSD_SIM, position_id=PositionId("P-1"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00010"), ) fill3 = TestStubs.event_order_filled( order3, instrument=AUDUSD_SIM, position_id=PositionId("P-2"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00000"), ) fill4 = TestStubs.event_order_filled( order4, instrument=AUDUSD_SIM, position_id=PositionId("P-2"), strategy_id=StrategyId("S-001"), last_px=Price.from_str("1.00020"), ) position1 = Position(instrument=AUDUSD_SIM, fill=fill1) position1.apply(fill2) position2 = Position(instrument=AUDUSD_SIM, fill=fill3) position2.apply(fill4) self.analyzer.add_positions([position1, position2]) # Act result = self.analyzer.realized_pnls(USD) # Assert assert len(result) == 2 assert result["P-1"] == 6.0 assert result["P-2"] == 16.0