def test_order_side_parser_given_invalid_value_raises_value_error(self): # Arrange # Act # Assert with pytest.raises(ValueError): OrderSideParser.to_str_py(0) with pytest.raises(ValueError): OrderSideParser.from_str_py("")
def test_order_side_from_str(self, string, expected): # Arrange # Act result = OrderSideParser.from_str_py(string) # Assert self.assertEqual(expected, result)
def test_order_side_from_str(self, string, expected): # Arrange # Act result = OrderSideParser.from_str_py(string) # Assert assert expected == result
def test_calculate_balance_locked(self, price, quantity, side, locked_balance): # Arrange event = self._make_account_state(starting_balance=1000.0) account = BettingAccount(event) # Act result = account.calculate_balance_locked( instrument=self.instrument, side=OrderSideParser.from_str_py(side), quantity=Quantity.from_int(quantity), price=Price.from_str(price), ) # Assert assert result == Money(Price.from_str(locked_balance), GBP)
def _handle_execution_report(self, data: Dict[str, Any]): execution_type: str = data["x"] # Parse instrument ID symbol: str = data["s"] instrument_id: Optional[InstrumentId] = self._instrument_ids.get( symbol) if not instrument_id: instrument_id = InstrumentId(Symbol(symbol), BINANCE_VENUE) self._instrument_ids[symbol] = instrument_id # Parse client order ID client_order_id_str: str = data["c"] if not client_order_id_str or not client_order_id_str.startswith("O"): client_order_id_str = data["C"] client_order_id = ClientOrderId(client_order_id_str) # Fetch strategy ID strategy_id: StrategyId = self._cache.strategy_id_for_order( client_order_id) if strategy_id is None: # TODO(cs): Implement external order handling self._log.error( f"Cannot handle execution report: " f"strategy ID for {client_order_id} not found.", ) return venue_order_id = VenueOrderId(str(data["i"])) order_type_str: str = data["o"] ts_event: int = millis_to_nanos(data["E"]) if execution_type == "NEW": self.generate_order_accepted( strategy_id=strategy_id, instrument_id=instrument_id, client_order_id=client_order_id, venue_order_id=venue_order_id, ts_event=ts_event, ) elif execution_type == "TRADE": instrument: Instrument = self._instrument_provider.find( instrument_id=instrument_id) # Determine commission commission_asset: str = data["N"] commission_amount: str = data["n"] if commission_asset is not None: commission = Money.from_str( f"{commission_amount} {commission_asset}") else: # Binance typically charges commission as base asset or BNB commission = Money(0, instrument.base_currency) self.generate_order_filled( strategy_id=strategy_id, instrument_id=instrument_id, client_order_id=client_order_id, venue_order_id=venue_order_id, venue_position_id=None, # NETTING accounts execution_id=ExecutionId(str(data["t"])), # Trade ID order_side=OrderSideParser.from_str_py(data["S"]), order_type=parse_order_type(order_type_str), last_qty=Quantity.from_str(data["l"]), last_px=Price.from_str(data["L"]), quote_currency=instrument.quote_currency, commission=commission, liquidity_side=LiquiditySide.MAKER if data["m"] else LiquiditySide.TAKER, ts_event=ts_event, ) elif execution_type == "CANCELED" or execution_type == "EXPIRED": self.generate_order_canceled( strategy_id=strategy_id, instrument_id=instrument_id, client_order_id=client_order_id, venue_order_id=venue_order_id, ts_event=ts_event, )