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_to_str(self, enum, expected): # Arrange # Act result = OrderSideParser.to_str_py(enum) # Assert self.assertEqual(expected, result)
def nautilus_order_to_ib_order(order: NautilusOrder) -> IBOrder: if isinstance(order, NautilusMarketOrder): return IBMarketOrder( action=OrderSideParser.to_str_py(order.side), totalQuantity=order.quantity.as_double(), ) elif isinstance(order, NautilusLimitOrder): # TODO - Time in force, etc return IBLimitOrder( action=OrderSideParser.to_str_py(order.side), lmtPrice=order.price.as_double(), totalQuantity=order.quantity.as_double(), ) else: raise NotImplementedError( f"IB order type not implemented {type(order)} for {order}")
def test_order_side_from_str(self, string, expected): # Arrange # Act result = OrderSideParser.from_str_py(string) # Assert assert expected == result
def test_order_side_to_str(self, enum, expected): # Arrange # Act result = OrderSideParser.to_str_py(enum) # Assert assert expected == result
async def _submit_market_order(self, order: MarketOrder): await self._account_spot.new_order( symbol=order.instrument_id.symbol.value, side=OrderSideParser.to_str_py(order.side), type="MARKET", quantity=str(order.quantity), new_client_order_id=order.client_order_id.value, recv_window=5000, )
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)
async def _submit_limit_order(self, order: LimitOrder): if order.is_post_only: time_in_force = None else: time_in_force = TimeInForceParser.to_str_py(order.time_in_force) await self._account_spot.new_order( symbol=order.instrument_id.symbol.value, side=OrderSideParser.to_str_py(order.side), type=binance_order_type(order=order), time_in_force=time_in_force, quantity=str(order.quantity), price=str(order.price), iceberg_qty=str(order.display_qty) if order.display_qty is not None else None, new_client_order_id=order.client_order_id.value, recv_window=5000, )
async def _submit_stop_limit_order(self, order: StopLimitOrder): # Get current market price response: Dict[str, Any] = await self._market_spot.ticker_price( order.instrument_id.symbol.value) market_price = Decimal(response["price"]) await self._account_spot.new_order( symbol=order.instrument_id.symbol.value, side=OrderSideParser.to_str_py(order.side), type=binance_order_type(order=order, market_price=market_price), time_in_force=TimeInForceParser.to_str_py(order.time_in_force), quantity=str(order.quantity), price=str(order.price), stop_price=str(order.trigger), iceberg_qty=str(order.display_qty) if order.display_qty is not None else None, new_client_order_id=order.client_order_id.value, recv_window=5000, )
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, )