def orderDictToOrder(o): sideMulti = 1 if o["side"] == "Buy" else -1 ext = o['ext_fields'] if 'ext_fields' in o.keys() else None stop = o['trigger_price'] if 'trigger_price' in o.keys() else None if stop is None: stop = o['stop_px'] if 'stop_px' in o.keys() else None if stop is None and ext is not None and 'trigger_price' in ext.keys(): stop = ext['trigger_price'] order = Order( orderId=o["order_link_id"], stop=float(stop) if stop is not None else None, limit=float(o["price"]) if o['order_type'] == 'Limit' else None, amount=float(o["qty"] * sideMulti)) if "order_status" in o.keys(): order.stop_triggered = o[ "order_status"] == "New" and stop is not None order.active = o['order_status'] == 'New' or o[ 'order_status'] == 'Untriggered' elif "stop_order_status" in o.keys(): order.stop_triggered = o["stop_order_status"] == 'Triggered' or o[ 'stop_order_status'] == 'Active' order.active = o['stop_order_status'] == 'Triggered' or o[ 'stop_order_status'] == 'Untriggered' exec = o['cum_exec_qty'] if 'cum_exec_qty' in o.keys() else 0 order.executed_amount = float(exec) * sideMulti order.tstamp = parse_utc_timestamp(o['timestamp'] if 'timestamp' in o.keys() else o['created_at']) order.exchange_id = o["order_id"] if 'order_id' in o.keys( ) else o['stop_order_id'] order.executed_price = None if 'cum_exec_value' in o.keys() and 'cum_exec_qty' in o.keys( ) and float(o['cum_exec_value']) != 0: order.executed_price = o['cum_exec_qty'] / float( o["cum_exec_value"]) # cause of inverse return order
def handle_order_execution(self, order: Order, intrabar: Bar): amount = order.amount - order.executed_amount order.executed_amount = order.amount fee = self.taker_fee if order.limit_price: price = order.limit_price fee = self.maker_fee elif order.stop_price: price = int( order.stop_price * (1 + math.copysign(self.market_slipage_percent, order.amount) / 100) / self.symbol.tickSize) * self.symbol.tickSize else: price = intrabar.open * ( 1 + math.copysign(self.market_slipage_percent, order.amount) / 100) price = min(intrabar.high, max( intrabar.low, price)) # only prices within the bar. might mean less slipage order.executed_price = price self.account.open_position.quantity += amount delta = amount * (price if not self.symbol.isInverse else -1 / price) self.account.open_position.walletBalance -= delta self.account.open_position.walletBalance -= math.fabs(delta) * fee order.active = False order.execution_tstamp = intrabar.tstamp order.final_reason = 'executed' self.account.order_history.append(order) self.account.open_orders.remove(order) logger.debug("executed order " + order.id + " | " + str(self.account.usd_equity) + " " + str(self.account.open_position.quantity))
def orderDictToOrder(self, o) -> Order: """ { "bizError": 0, "orderID": "9cb95282-7840-42d6-9768-ab8901385a67", "clOrdID": "7eaa9987-928c-652e-cc6a-82fc35641706", "symbol": "BTCUSD", "side": "Buy", "actionTimeNs": 1580533011677666800, "transactTimeNs": 1580533011677666800, "orderType": null, "priceEp": 84000000, "price": 8400, "orderQty": 1, "displayQty": 1, "timeInForce": null, "reduceOnly": false, "stopPxEp": 0, "closedPnlEv": 0, "closedPnl": 0, "closedSize": 0, "cumQty": 0, "cumValueEv": 0, "cumValue": 0, "leavesQty": 0, "leavesValueEv": 0, "leavesValue": 0, "stopPx": 0, "stopDirection": "Falling", "ordStatus": "Untriggered" }, """ sideMult = -1 if o['side'] == Client.SIDE_SELL else 1 stop = self.noneIfZero( o['stopPx']) if 'stopPx' in o else self.noneIfZero( o['stopPxEp'], True) price = self.noneIfZero( o['price']) if 'price' in o else self.noneIfZero( o['priceEp'], True) order = Order(orderId=o['clOrdID'], stop=stop, limit=price, amount=o['orderQty'] * sideMult) order.exchange_id = o['orderID'] order.tstamp = o['actionTimeNs'] / 1000000000 order.active = o['ordStatus'] in [ Client.ORDER_STATUS_NEW, Client.ORDER_STATUS_UNTRIGGERED, Client.ORDER_STATUS_TRIGGERED ] order.executed_amount = o['cumQty'] * sideMult val = o['cumValue'] if 'cumValue' in o else o[ 'cumValueEv'] / self.valueScale order.executed_price = o['cumQty'] / val if val != 0 else 0 if order.executed_amount != 0: order.execution_tstamp = o['transactTimeNs'] / 1000000000 order.stop_triggered = order.stop_price is not None and o[ 'ordStatus'] == Client.ORDER_STATUS_TRIGGERED return order
def handle_order_execution(self, order: Order, intrabar: Bar): amount = order.amount - order.executed_amount order.executed_amount = order.amount fee = self.taker_fee if order.limit_price: price = order.limit_price fee = self.maker_fee elif order.stop_price: price = int( order.stop_price * (1 + math.copysign(self.market_slipage_percent, order.amount) / 100) / self.symbol.tickSize) * self.symbol.tickSize else: price = intrabar.open * ( 1 + math.copysign(self.market_slipage_percent, order.amount) / 100) price = min(intrabar.high, max( intrabar.low, price)) # only prices within the bar. might mean less slipage order.executed_price = price oldAmount = self.account.open_position.quantity if oldAmount != 0: oldavgentry = self.account.open_position.avgEntryPrice if oldAmount * amount > 0: self.account.open_position.avgEntryPrice = ( oldavgentry * oldAmount + price * amount) / (oldAmount + amount) if oldAmount * amount < 0: if abs(oldAmount) < abs(amount): profit = oldAmount * ( (price - oldavgentry) if not self.symbol.isInverse else (-1 / price + 1 / oldavgentry)) self.account.open_position.walletBalance += profit #close current, open new self.account.open_position.avgEntryPrice = price else: #closes the position by "-amount" cause amount is the side and direction of the close profit = -amount * ( (price - oldavgentry) if not self.symbol.isInverse else (-1 / price + 1 / oldavgentry)) self.account.open_position.walletBalance += profit else: self.account.open_position.avgEntryPrice = price self.account.open_position.quantity += amount volume = amount * (price if not self.symbol.isInverse else -1 / price) self.account.open_position.walletBalance -= math.fabs(volume) * fee order.active = False order.execution_tstamp = intrabar.tstamp order.final_reason = 'executed' self.account.order_history.append(order) self.account.open_orders.remove(order) self.logger.debug("executed order %s | %.0f %.2f | %.2f@ %.1f" % (order.id, self.account.usd_equity, self.account.open_position.quantity, order.executed_amount, order.executed_price))
def convertOrder(self, apiOrder: binance_f.model.Order) -> Order: direction = 1 if apiOrder.side == OrderSide.BUY else -1 order = Order(orderId=apiOrder.clientOrderId, amount=apiOrder.origQty * direction, limit=apiOrder.price, stop=apiOrder.stopPrice) order.executed_amount = apiOrder.executedQty * direction order.executed_price = apiOrder.avgPrice order.active = apiOrder.status in ["NEW", "PARTIALLY_FILLED"] order.exchange_id = apiOrder.orderId return order
def get_orders(self) -> List[Order]: mexOrders = self.bitmex.open_orders() result: List[Order] = [] for o in mexOrders: sideMulti = 1 if o["side"] == "Buy" else -1 order = Order(orderId=o["clOrdID"], stop=o["stopPx"], limit=o["price"], amount=o["orderQty"] * sideMulti) order.stop_triggered = o["triggered"] == "StopOrderTriggered" order.executed_amount = (o["cumQty"]) * sideMulti order.tstamp = parse_utc_timestamp(o['timestamp']) order.execution_tstamp = order.tstamp order.active = o['ordStatus'] == 'New' order.exchange_id = o["orderID"] order.executed_price = o["avgPx"] result.append(order) return result