def test_serialize_and_deserialize_stop_limit_orders_with_expire_time( self): # Arrange order = StopLimitOrder( ClientOrderId("O-123456"), StrategyId("S", "001"), AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), price=Price("1.00000"), trigger=Price("1.00010"), 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 self.assertEqual(order, deserialized) print(b64encode(serialized)) print(order)
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, 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 self.assertEqual(command, deserialized) self.assertEqual(order, deserialized.order) print(command) print(len(serialized)) print(serialized) print(b64encode(serialized))
def test_margin_available_for_multi_asset_account(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("0.00000000", BTC), Money("0.00000000", ETH)], info={}, # No default currency set event_id=uuid4(), timestamp_ns=0, ) account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Act result1 = account.margin_available(BTC) account.update_initial_margin(Money("0.00010000", BTC)) result2 = account.margin_available(BTC) account.update_maint_margin(Money("0.00020000", BTC)) result3 = account.margin_available(BTC) result4 = account.margin_available(ETH) # Assert self.assertEqual(Money("10.00000000", BTC), result1) self.assertEqual(Money("9.99990000", BTC), result2) self.assertEqual(Money("9.99970000", BTC), result3) self.assertEqual(Money("20.00000000", ETH), result4)
def test_instantiated_accounts_basic_properties(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money(1_000_000, USD)], [Money(1_000_000, USD)], [Money(0, USD)], info={"default_currency": "USD"}, # Set the default currency event_id=uuid4(), timestamp_ns=0, ) # Act account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Assert self.assertEqual(AccountId("SIM", "001"), account.id) self.assertEqual("Account(id=SIM-001)", str(account)) self.assertEqual("Account(id=SIM-001)", repr(account)) self.assertEqual(int, type(hash(account))) self.assertTrue(account == account) self.assertFalse(account != account)
def test_equity_with_multi_asset_account_returns_expected_money(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("0.00000000", BTC), Money("0.00000000", ETH)], info={}, # No default currency set event_id=uuid4(), timestamp_ns=0, ) account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Act result = account.equity(BTC) # Assert self.assertEqual(Money("10.00000000", BTC), result)
def test_margin_available_for_single_asset_account(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("100000.00", USD)], [Money("0.00", USD)], [Money("0.00", USD)], info={"default_currency": "USD"}, # No default currency set event_id=uuid4(), timestamp_ns=0, ) account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Act result1 = account.margin_available() account.update_initial_margin(Money("500.00", USD)) result2 = account.margin_available() account.update_maint_margin(Money("1000.00", USD)) result3 = account.margin_available() # Assert self.assertEqual(Money("100000.00", USD), result1) self.assertEqual(Money("99500.00", USD), result2) self.assertEqual(Money("98500.00", USD), result3)
def test_update_maint_margin(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("0.00000000", BTC), Money("0.00000000", ETH)], info={}, # No default currency set event_id=uuid4(), timestamp_ns=0, ) # Act account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) margin = Money("0.00050000", BTC) # Act account.update_maint_margin(margin) # Assert self.assertEqual(margin, account.maint_margin(BTC)) self.assertEqual({BTC: margin}, account.maint_margins())
def test_unrealized_pnl_with_multi_asset_account_when_no_open_positions_returns_zero( self, ): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("0.00000000", BTC), Money("0.00000000", ETH)], info={}, # No default currency set event_id=uuid4(), timestamp_ns=0, ) account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Act result = account.unrealized_pnl(BTC) # Assert self.assertEqual(Money("0.00000000", BTC), result)
def test_serialize_and_deserialize_order_working_events_with_expire_time( self): # Arrange event = OrderWorking( self.account_id, ClientOrderId("O-123456"), OrderId("B-123456"), AUDUSD_SIM.symbol, OrderSide.SELL, OrderType.STOP_MARKET, Quantity(100000), Price("1.50000"), TimeInForce.DAY, UNIX_EPOCH, UNIX_EPOCH, uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(deserialized, event)
def test_serialize_and_deserialize_order_filled_events(self): # Arrange event = OrderFilled( self.account_id, ClientOrderId("O-123456"), OrderId("1"), ExecutionId("E123456"), PositionId("T123456"), StrategyId("S", "001"), AUDUSD_SIM.symbol, OrderSide.SELL, Quantity(100000), Quantity(100000), Quantity(), Price("1.00000"), AUDUSD_SIM.quote_currency, AUDUSD_SIM.is_inverse, Money(0, USD), LiquiditySide.TAKER, UNIX_EPOCH, uuid4(), UNIX_EPOCH, ) # Act serialized = self.serializer.serialize(event) deserialized = self.serializer.deserialize(serialized) # Assert self.assertEqual(deserialized, event)
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 setUp(self): # Fixture Setup clock = TestClock() logger = TestLogger(clock) self.order_factory = OrderFactory( trader_id=TraderId("TESTER", "000"), strategy_id=StrategyId("S", "001"), clock=TestClock(), ) state = AccountState( account_id=AccountId("BINANCE", "1513111"), balances=[Money("10.00000000", BTC)], balances_free=[Money("0.00000000", BTC)], balances_locked=[Money("0.00000000", BTC)], info={}, event_id=uuid4(), event_timestamp=UNIX_EPOCH, ) self.data_cache = DataCache(logger) self.account = Account(state) self.portfolio = Portfolio(clock, logger) self.portfolio.register_account(self.account) self.portfolio.register_cache(self.data_cache) self.data_cache.add_instrument(AUDUSD_SIM) self.data_cache.add_instrument(GBPUSD_SIM) self.data_cache.add_instrument(BTCUSDT_BINANCE) self.data_cache.add_instrument(BTCUSD_BITMEX) self.data_cache.add_instrument(ETHUSD_BITMEX)
def test_generate_accounts_report_with_initial_account_state_returns_expected( self): # Arrange state = AccountState( account_id=AccountId("BITMEX", "1513111"), account_type=AccountType.MARGIN, base_currency=BTC, reported=True, balances=[ AccountBalance( currency=BTC, total=Money(10.00000000, BTC), free=Money(10.00000000, BTC), locked=Money(0.00000000, BTC), ) ], info={}, event_id=uuid4(), updated_ns=0, timestamp_ns=0, ) account = Account(state) report_provider = ReportProvider() # Act report = report_provider.generate_account_report(account) # Assert self.assertEqual(1, len(report))
def test_apply_order_amended_event_to_stop_order(self): # Arrange order = self.order_factory.stop_market( AUDUSD_SIM.id, OrderSide.BUY, Quantity(100000), Price("1.00000"), ) order.apply(TestStubs.event_order_submitted(order)) order.apply(TestStubs.event_order_accepted(order)) updated = OrderUpdated( self.account_id, order.client_order_id, VenueOrderId("1"), Quantity(120000), Price("1.00001"), 0, uuid4(), 0, ) # Act order.apply(updated) # Assert self.assertEqual(OrderState.ACCEPTED, order.state) self.assertEqual(VenueOrderId("1"), order.venue_order_id) self.assertEqual(Quantity(120000), order.quantity) self.assertEqual(Price("1.00001"), order.price) self.assertTrue(order.is_working) self.assertFalse(order.is_completed) self.assertEqual(4, order.event_count)
def setUp(self): # Fixture Setup self.clock = TestClock() uuid_factor = TestUUIDFactory() logger = TestLogger(self.clock) self.order_factory = OrderFactory( strategy_id=StrategyId("S", "001"), id_tag_trader=IdTag("001"), id_tag_strategy=IdTag("001"), clock=TestClock(), ) state = AccountState( AccountId.from_string("BITMEX-1513111-SIMULATED"), BTC, Money(10., BTC), Money(0., BTC), Money(0., BTC), uuid4(), UNIX_EPOCH ) self.account = Account(state) self.portfolio = Portfolio(self.clock, uuid_factor, logger) self.portfolio.register_account(self.account)
def test_instantiate_multi_asset_account(self): # Arrange event = AccountState( AccountId("SIM", "001"), [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("10.00000000", BTC), Money("20.00000000", ETH)], [Money("0.00000000", BTC), Money("0.00000000", ETH)], info={}, # No default currency set event_id=uuid4(), event_timestamp=UNIX_EPOCH, ) # Act account = Account(event) # Wire up account to portfolio account.register_portfolio(self.portfolio) self.portfolio.register_account(account) # Assert self.assertEqual(AccountId("SIM", "001"), account.id) self.assertEqual(None, account.default_currency) self.assertEqual(event, account.last_event) self.assertEqual([event], account.events) self.assertEqual(1, account.event_count) self.assertEqual(Money("10.00000000", BTC), account.balance(BTC)) self.assertEqual(Money("20.00000000", ETH), account.balance(ETH)) self.assertEqual(Money("10.00000000", BTC), account.balance_free(BTC)) self.assertEqual(Money("20.00000000", ETH), account.balance_free(ETH)) self.assertEqual(Money("0.00000000", BTC), account.balance_locked(BTC)) self.assertEqual(Money("0.00000000", ETH), account.balance_locked(ETH)) self.assertEqual( { BTC: Money("10.00000000", BTC), ETH: Money("20.00000000", ETH) }, account.balances()) self.assertEqual( { BTC: Money("10.00000000", BTC), ETH: Money("20.00000000", ETH) }, account.balances_free()) self.assertEqual( { BTC: Money("0.00000000", BTC), ETH: Money("0.00000000", ETH) }, account.balances_locked()) self.assertEqual(Money("0.00000000", BTC), account.unrealized_pnl(BTC)) self.assertEqual(Money("0.00000000", ETH), account.unrealized_pnl(ETH)) self.assertEqual(Money("10.00000000", BTC), account.equity(BTC)) self.assertEqual(Money("20.00000000", ETH), account.equity(ETH)) self.assertEqual({}, account.init_margins()) self.assertEqual({}, account.maint_margins()) self.assertEqual(None, account.init_margin(BTC)) self.assertEqual(None, account.init_margin(ETH)) self.assertEqual(None, account.maint_margin(BTC)) self.assertEqual(None, account.maint_margin(ETH))
def test_market_value_when_insufficient_data_for_xrate_returns_none(self): # Arrange state = AccountState( account_id=AccountId("BITMEX", "01234"), balances=[Money("10.00000000", BTC), Money("10.00000000", ETH)], balances_free=[ Money("10.00000000", BTC), Money("10.00000000", ETH) ], balances_locked=[ Money("0.00000000", BTC), Money("0.00000000", ETH) ], info={}, event_id=uuid4(), event_timestamp=UNIX_EPOCH, ) account = Account(state) self.portfolio.register_account(account) order = self.order_factory.market( ETHUSD_BITMEX.symbol, OrderSide.BUY, Quantity(100), ) fill = TestStubs.event_order_filled( order=order, instrument=ETHUSD_BITMEX, position_id=PositionId("P-123456"), strategy_id=StrategyId("S", "001"), fill_price=Price("376.05"), ) last_ethusd = QuoteTick( ETHUSD_BITMEX.symbol, Price("376.05"), Price("377.10"), Quantity("16"), Quantity("25"), UNIX_EPOCH, ) position = Position(fill) self.portfolio.update_position( TestStubs.event_position_opened(position)) self.data_cache.add_quote_tick(last_ethusd) self.portfolio.update_tick(last_ethusd) # Act result = self.portfolio.market_values(BITMEX) # Assert # TODO: Currently no Quanto thus no xrate required self.assertEqual({ETH: Money('0.02659221', ETH)}, result)
def event_order_submitted(order) -> OrderSubmitted: return OrderSubmitted( account_id=TestStubs.account_id(), client_order_id=order.client_order_id, ts_submitted_ns=0, event_id=uuid4(), timestamp_ns=0, )
def event_order_submitted(order) -> OrderSubmitted: return OrderSubmitted( TestStubs.account_id(), order.cl_ord_id, UNIX_EPOCH, uuid4(), UNIX_EPOCH, )
def test_venue_status(self): uuid = uuid4() event = VenueStatusEvent( status=VenueStatus.OPEN, event_id=uuid, timestamp_ns=0, ) assert f"VenueStatusEvent(status=OPEN, event_id={uuid})" == repr(event)
def event_order_submitted(order) -> OrderSubmitted: return OrderSubmitted( TestStubs.account_id(), order.client_order_id, 0, uuid4(), 0, )
def test_sort(self): # Arrange receiver = [] event1 = TimeEventHandler(TimeEvent("123", uuid4(), UNIX_EPOCH, 0, 0), receiver.append) event2 = TimeEventHandler(TimeEvent("123", uuid4(), UNIX_EPOCH, 0, 0), receiver.append) event3 = TimeEventHandler( TimeEvent("123", uuid4(), UNIX_EPOCH + timedelta(1), 0, 0), receiver.append) # Act # Stable sort as event1 and event2 remain in order result = sorted([event3, event1, event2]) # Assert assert result == [event1, event2, event3]
def test_comparisons(self): # Arrange receiver = [] event1 = TimeEventHandler(TimeEvent("123", uuid4(), UNIX_EPOCH), receiver.append) event2 = TimeEventHandler( TimeEvent("123", uuid4(), UNIX_EPOCH + timedelta(1)), receiver.append) # Act # Assert self.assertTrue(event1 == event1) self.assertTrue(event1 != event2) self.assertTrue(event1 < event2) self.assertTrue(event1 <= event2) self.assertTrue(event2 > event1) self.assertTrue(event2 >= event1)
def event_order_expired(order) -> OrderExpired: return OrderExpired( TestStubs.account_id(), order.cl_ord_id, OrderId("1"), UNIX_EPOCH, uuid4(), UNIX_EPOCH, )
def event_order_rejected(order) -> OrderRejected: return OrderRejected( TestStubs.account_id(), order.cl_ord_id, UNIX_EPOCH, "ORDER_REJECTED", uuid4(), UNIX_EPOCH, )
def event_order_cancelled(order) -> OrderCancelled: return OrderCancelled( TestStubs.account_id(), order.cl_ord_id, order.id, UNIX_EPOCH, uuid4(), UNIX_EPOCH, )
def test_instrument_status(self): uuid = uuid4() event = InstrumentStatusEvent( status=InstrumentStatus.PAUSE, event_id=uuid, timestamp_ns=0, ) assert f"InstrumentStatusEvent(status=PAUSE, event_id={uuid})" == repr( event)
def event_order_triggered(order) -> OrderTriggered: return OrderTriggered( TestStubs.account_id(), order.cl_ord_id, order.id, UNIX_EPOCH, uuid4(), UNIX_EPOCH, )
def test_hash_time_event(self): # Arrange event = TimeEvent("123", uuid4(), UNIX_EPOCH) # Act result = hash(event) # Assert self.assertEqual(int, type(result)) # No assertions raised
def event_order_triggered(order) -> OrderTriggered: return OrderTriggered( TestStubs.account_id(), order.client_order_id, order.venue_order_id, 0, uuid4(), 0, )