def _get_fee(self, exchange: 'ExchangeBase') -> TradeFeeBase: base, quote = split_hb_trading_pair(self.trading_pair) position_action = PositionAction.CLOSE if self.position_close else PositionAction.OPEN fee = build_perpetual_trade_fee( exchange.name, self.is_maker, position_action, base, quote, self.order_type, self.order_side, self.amount, self.price, ) return fee
def get_fee( self, base_currency: str, quote_currency: str, order_type: OrderType, order_side: TradeType, amount: Decimal, price: Decimal = Decimal("0"), is_maker: Optional[bool] = None, position_action: PositionAction = PositionAction.OPEN ) -> AddedToCostTradeFee: return build_perpetual_trade_fee( exchange=self.name, is_maker=is_maker, position_action=position_action, base_currency=base_currency, quote_currency=quote_currency, order_type=order_type, order_side=order_side, amount=amount, price=price, )
async def _update_order_status(self): """ Calls REST API to get status update for each in-flight order. """ if len(self._in_flight_orders) > 0: tracked_orders = list(self._in_flight_orders.values()) tasks = [] for tracked_order in tracked_orders: order_id = await tracked_order.get_exchange_order_id() tasks.append(self._api_request("post", "perpfi/receipt", {"txHash": order_id})) update_results = await safe_gather(*tasks, return_exceptions=True) for update_result, tracked_order in zip(update_results, tracked_orders): self.logger().info(f"Polling for order status updates of {len(tasks)} orders.") if isinstance(update_result, Exception): raise update_result if "txHash" not in update_result: self.logger().info(f"_update_order_status txHash not in resp: {update_result}") continue if update_result["confirmed"] is True: if update_result["receipt"]["status"] == 1: fee = build_perpetual_trade_fee( exchange=self.name, is_maker=True, position_action=PositionAction[tracked_order.position], base_currency=tracked_order.base_asset, quote_currency=tracked_order.quote_asset, order_type=tracked_order.order_type, order_side=tracked_order.trade_type, amount=tracked_order.amount, price=tracked_order.price, ) fee.flat_fees.append(TokenAmount("XDAI", Decimal(str(update_result["receipt"]["gasUsed"])))) self.trigger_event( MarketEvent.OrderFilled, OrderFilledEvent( self.current_timestamp, tracked_order.client_order_id, tracked_order.trading_pair, tracked_order.trade_type, tracked_order.order_type, Decimal(str(tracked_order.price)), Decimal(str(tracked_order.amount)), fee, exchange_trade_id=order_id, leverage=self._leverage[tracked_order.trading_pair], position=tracked_order.position ) ) tracked_order.last_state = "FILLED" self.logger().info(f"The {tracked_order.trade_type.name} order " f"{tracked_order.client_order_id} has completed " f"according to order status API.") event_tag = MarketEvent.BuyOrderCompleted if tracked_order.trade_type is TradeType.BUY \ else MarketEvent.SellOrderCompleted event_class = BuyOrderCompletedEvent if tracked_order.trade_type is TradeType.BUY \ else SellOrderCompletedEvent self.trigger_event(event_tag, event_class(self.current_timestamp, tracked_order.client_order_id, tracked_order.base_asset, tracked_order.quote_asset, tracked_order.fee_asset, tracked_order.executed_amount_base, tracked_order.executed_amount_quote, float(fee.fee_amount_in_quote(tracked_order.trading_pair, Decimal(str(tracked_order.price)), Decimal(str(tracked_order.amount)), self)), # this ignores the gas fee, which is fine for now tracked_order.order_type)) self.stop_tracking_order(tracked_order.client_order_id) else: self.logger().info( f"The market order {tracked_order.client_order_id} has failed according to order status API. ") self.trigger_event(MarketEvent.OrderFailure, MarketOrderFailureEvent( self.current_timestamp, tracked_order.client_order_id, tracked_order.order_type )) self.stop_tracking_order(tracked_order.client_order_id)