Ejemplo n.º 1
0
    async def create_order(self, action, price, quantity, order_type=ORDER_TYPE_LIMIT, *args, **kwargs):
        """ Create an order.

        Args:
            action: Trade direction, BUY or SELL.
            price: Price of order.
            quantity: The buying or selling quantity.
            order_type: order type, MARKET or LIMIT.

        Returns:
            order_no: Order ID if created successfully, otherwise it's None.
            error: Error information, otherwise it's None.
        """
        success, error = await self._rest_api.create_order(action, self._raw_symbol, price, quantity)
        if error:
            return None, error
        order_no = success["order_id"]
        infos = {
            "account": self._account,
            "platform": self._platform,
            "strategy": self._strategy,
            "order_no": order_no,
            "symbol": self._symbol,
            "action": action,
            "price": price,
            "quantity": quantity,
            "order_type": order_type
        }
        order = Order(**infos)
        self._orders[order_no] = order
        SingleTask.run(self._order_update_callback, copy.copy(order))
        return order_no, None
Ejemplo n.º 2
0
    def _update_order(self, order_info):
        """ 更新订单信息
        @param order_info 订单信息
        * NOTE:
            order-state: 订单状态, submitting , submitted 已提交, partial-filled 部分成交, partial-canceled 部分成交撤销,
                filled 完全成交, canceled 已撤销
        """
        order_no = str(order_info["order-id"])
        action = ORDER_ACTION_BUY if order_info["order-type"] in [
            "buy-market", "buy-limit"
        ] else ORDER_ACTION_SELL
        state = order_info["order-state"]
        remain = "%.8f" % float(order_info["unfilled-amount"])
        avg_price = "%.8f" % float(order_info["price"])
        ctime = order_info["created-at"]
        utime = order_info["utime"]

        if state == "canceled":
            status = ORDER_STATUS_CANCELED
        elif state == "partial-canceled":
            status = ORDER_STATUS_CANCELED
        elif state == "submitting":
            status = ORDER_STATUS_SUBMITTED
        elif state == "submitted":
            status = ORDER_STATUS_SUBMITTED
        elif state == "partical-filled":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "filled":
            status = ORDER_STATUS_FILLED
        else:
            logger.error("status error! order_info:", order_info, caller=self)
            return None

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": action,
                "symbol": self._symbol,
                "price": "%.8f" % float(order_info["order-price"]),
                "quantity": "%.8f" % float(order_info["order-amount"]),
                "remain": remain,
                "status": status
            }
            order = Order(**info)
            self._orders[order_no] = order
        order.remain = remain
        order.status = status
        order.avg_price = avg_price
        order.ctime = ctime
        order.utime = utime
        if status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
        if order and self._order_update_callback:
            SingleTask.run(self._order_update_callback, order)
Ejemplo n.º 3
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        """
        order_no = str(order_info["order_id"])
        state = order_info["state"]
        remain = float(order_info["size"]) - float(order_info["filled_size"])
        ctime = tools.utctime_str_to_mts(order_info["ctime"])
        utime = tools.utctime_str_to_mts(order_info["utime"])

        if state == "-2":
            status = ORDER_STATUS_FAILED
        elif state == "-1":
            status = ORDER_STATUS_CANCELED
        elif state == "0":
            status = ORDER_STATUS_SUBMITTED
        elif state == "1":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "2":
            status = ORDER_STATUS_FILLED
        else:
            logger.error("status error! order_info:", order_info, caller=self)
            return None

        order = self._orders.get(order_no)
        if order:
            order.remain = remain
            order.status = status
            order.price = order_info["price"]
        else:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY
                if order_info["side"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["size"],
                "remain": remain,
                "status": status,
                "avg_price": order_info["price"]
            }
            order = Order(**info)
            self._orders[order_no] = order
        order.ctime = ctime
        order.utime = utime

        SingleTask.run(self._order_update_callback, copy.copy(order))

        if status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
Ejemplo n.º 4
0
    async def create_order(self, action, price, quantity, order_type=ORDER_TYPE_LIMIT, *args, **kwargs):
        """ 创建订单
        @param action 交易方向 BUY/SELL
        @param price 委托价格
        @param quantity 委托数量
        @param order_type 委托类型 LIMIT / MARKET
        """
        if action not in [ORDER_ACTION_BUY, ORDER_ACTION_SELL]:
            return None, "action error"
        if order_type not in [ORDER_TYPE_MARKET, ORDER_TYPE_LIMIT]:
            return None, "order_type error"

        # 创建订单
        price = tools.float_to_str(price)
        quantity = tools.float_to_str(quantity)
        success, error = await self._rest_api.create_order(action, self._raw_symbol, price, quantity, order_type)
        if error:
            return None, error
        order_no = str(success["orderNo"])
        infos = {
            "account": self._account,
            "platform": self._platform,
            "strategy": self._strategy,
            "order_no": order_no,
            "symbol": self._symbol,
            "action": action,
            "price": price,
            "quantity": quantity,
            "order_type": order_type
        }
        order = Order(**infos)
        self._orders[order_no] = order
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, copy.copy(order))
        return order_no, None
Ejemplo n.º 5
0
    async def connected_callback(self):
        """ 建立连接之后,获取当前所有未完全成交的订单
        """
        order_infos, error = await self._rest_api.get_open_orders(
            self._raw_symbol)
        if error:
            return
        for order_info in order_infos:
            order_no = "{}_{}".format(order_info["orderId"],
                                      order_info["clientOrderId"])
            if order_info["status"] == "NEW":  # 部分成交
                status = ORDER_STATUS_SUBMITTED
            elif order_info["status"] == "PARTIALLY_FILLED":  # 部分成交
                status = ORDER_STATUS_PARTIAL_FILLED
            elif order_info["status"] == "FILLED":  # 完全成交
                status = ORDER_STATUS_FILLED
            elif order_info["status"] == "CANCELED":  # 取消
                status = ORDER_STATUS_CANCELED
            elif order_info["status"] == "REJECTED":  # 拒绝
                status = ORDER_STATUS_FAILED
            elif order_info["status"] == "EXPIRED":  # 过期
                status = ORDER_STATUS_FAILED
            else:
                logger.warn("unknown status:", order_info, caller=self)
                return

            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "action":
                order_info["side"],
                "order_type":
                order_info["type"],
                "symbol":
                self._symbol,
                "price":
                order_info["price"],
                "quantity":
                order_info["origQty"],
                "remain":
                float(order_info["origQty"]) -
                float(order_info["executedQty"]),
                "status":
                status,
                "ctime":
                order_info["time"],
                "utime":
                order_info["updateTime"]
            }
            order = Order(**info)
            self._orders[order_no] = order
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, order)
Ejemplo n.º 6
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            Return order object if or None.
        """
        order_no = str(order_info["order_id"])
        state = order_info["state"]
        remain = int(order_info["size"]) - int(order_info["filled_qty"])
        ctime = tools.utctime_str_to_mts(order_info["timestamp"])
        if state == "-2":
            status = ORDER_STATUS_FAILED
        elif state == "-1":
            status = ORDER_STATUS_CANCELED
        elif state == "0":
            status = ORDER_STATUS_SUBMITTED
        elif state == "1":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "2":
            status = ORDER_STATUS_FILLED
        else:
            return None

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "action":
                ORDER_ACTION_BUY
                if order_info["type"] in ["1", "4"] else ORDER_ACTION_SELL,
                "symbol":
                self._symbol,
                "price":
                order_info["price"],
                "quantity":
                order_info["size"],
                "trade_type":
                int(order_info["type"])
            }
            order = Order(**info)
        order.remain = remain
        order.status = status
        order.avg_price = order_info["price_avg"]
        order.ctime = ctime
        order.utime = ctime
        self._orders[order_no] = order
        if state in ["-1", "2"]:
            self._orders.pop(order_no)
        return order
Ejemplo n.º 7
0
    def _update_order(self, order_info):
        """ 更新订单信息
        @param order_info 订单信息
        """
        is_updated = False  # 当前订单相比之前是否有更新
        order_no = order_info['id']
        state = order_info["state"]
        remain = float(order_info["amount"]) - float(order_info["filled_amount"])
        ctime = order_info["created_at"]

        if state == "canceled":
            status = ORDER_STATUS_CANCELED
        elif state == "submitted":
            status = ORDER_STATUS_SUBMITTED
        elif state == "partial_filled":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "filled":
            status = ORDER_STATUS_FILLED
        elif state == 'partial_canceled':
            status = ORDER_STATUS_PARTIAL_CANCELED
        elif state == 'pending_cancel':
            status = ORDER_STATUS_PENDING_CANCEL
        else:
            logger.error("status error! order_info:", order_info, caller=self)
            return None

        order = self._orders.get(order_no)
        if order:
            if order.remain != remain:
                is_updated = True
                order.remain = remain
            elif order.status != status:
                is_updated = True
                order.status = status
            elif order.price != order_info["price"]:
                is_updated = True
                order.price = order_info["price"]
        else:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY if order_info["side"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["amount"],
                "remain": remain,
                "status": status,
                "avg_price": order_info["price"]
            }
            order = Order(**info)
            self._orders[order_no] = order
            is_updated = True
        order.ctime = ctime
        if status in [ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED, ORDER_STATUS_PARTIAL_CANCELED]:
            self._orders.pop(order_no)
        return is_updated, order
Ejemplo n.º 8
0
    async def create_order(self,
                           action,
                           price,
                           quantity,
                           order_type=ORDER_TYPE_LIMIT,
                           *args,
                           **kwargs):
        """ Create an order.

        Args:
            action: Trade direction, BUY or SELL.
            price: Price of order.
            quantity: The buying or selling quantity.
            order_type: order type, MARKET or LIMIT.

        Returns:
            order_no: Order ID if created successfully, otherwise it's None.
            error: Error information, otherwise it's None.
        """
        if action == ORDER_ACTION_BUY:
            action_type = "buy"
        elif action == ORDER_ACTION_SELL:
            action_type = "sell"
        else:
            return None, "action error"
        if order_type == ORDER_TYPE_MARKET:
            order_type_2 = "market"
        elif order_type == ORDER_TYPE_LIMIT:
            order_type_2 = "limit"
        else:
            return None, "order_type error"

        client_id = tools.get_uuid1()
        price = tools.float_to_str(price)
        quantity = tools.float_to_str(quantity)
        success, error = await self._rest_api.create_order(
            client_id, action_type, self._raw_symbol, order_type_2, price,
            quantity)
        if error:
            return None, error
        order_no = success["orderId"]
        infos = {
            "account": self._account,
            "platform": self._platform,
            "strategy": self._strategy,
            "order_no": order_no,
            "symbol": self._symbol,
            "action": action,
            "price": price,
            "quantity": quantity,
            "order_type": order_type
        }
        order = Order(**infos)
        self._orders[order_no] = order
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, copy.copy(order))
        return order_no, None
Ejemplo n.º 9
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        """
        order_no = str(order_info["order_id"])
        state = order_info["state"]
        remain = int(order_info["size"]) - int(order_info["filled_qty"])
        ctime = tools.utctime_str_to_mts(order_info["timestamp"])
        if state == "-2":
            status = ORDER_STATUS_FAILED
        elif state == "-1":
            status = ORDER_STATUS_CANCELED
        elif state == "0":
            status = ORDER_STATUS_SUBMITTED
        elif state == "1":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "2":
            status = ORDER_STATUS_FILLED
        else:
            return None

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY if order_info["type"] in ["1", "4"] else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["size"],
                "trade_type": int(order_info["type"])
            }
            order = Order(**info)
        order.remain = remain
        order.status = status
        order.avg_price = order_info["price_avg"]
        order.ctime = ctime
        order.utime = ctime
        self._orders[order_no] = order

        SingleTask.run(self._order_update_callback, copy.copy(order))

        if status in [ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED]:
            self._orders.pop(order_no)
        
        # publish order
        EventOrder(**order.__dict__).publish()
        logger.info("symbol:", order.symbol, "order:", order, caller=self)
Ejemplo n.º 10
0
 def _convert_order_format(self, order_info):
     order_no = str(order_info["order_id"])
     symbol = order_info["instrument_id"]
     ctime = tools.utctime_str_to_mts(order_info["created_at"])
     utime = tools.utctime_str_to_mts(order_info["timestamp"])
     state = order_info["state"]
     if state == "-2":
         status = ORDER_STATUS_FAILED
     elif state == "-1":
         status = ORDER_STATUS_CANCELED
     elif state == "0":
         status = ORDER_STATUS_SUBMITTED
     elif state == "1":
         status = ORDER_STATUS_PARTIAL_FILLED
     elif state == "2":
         status = ORDER_STATUS_FILLED
     else:
         status = ORDER_STATUS_NONE
     if order_info["type"] == "market":
         order_type = ORDER_TYPE_MARKET
     else:
         if order_info["order_type"] == "3":
             order_type = ORDER_TYPE_IOC
         else:
             order_type = ORDER_TYPE_LIMIT
     action = ORDER_ACTION_BUY if order_info[
         "side"] == "buy" else ORDER_ACTION_SELL
     if order_type == ORDER_TYPE_MARKET and action == ORDER_ACTION_BUY:
         quantity = float(order_info["notional"])  #市价买单传入的是金额,输出的也要是金额
         remain = quantity - float(
             order_info["filled_notional"])  #市价买单传入的是金额,输出的也要是金额
     else:
         quantity = float(order_info["size"])
         remain = quantity - float(order_info["filled_size"])
     price_str = order_info["price"]
     if not price_str:
         price_str = "0"
     info = {
         "platform": self._platform,
         "account": self._account,
         "strategy": self._strategy,
         "order_no": order_no,
         "action": action,
         "symbol": symbol,
         "price": float(price_str),
         "quantity": quantity,
         "remain": remain,
         "order_type": order_type,
         "status": status,
         "ctime": ctime,
         "utime": utime
         #"avg_price": order_info["price_avg"] filled_notional/filled_size???
     }
     return Order(**info)
Ejemplo n.º 11
0
    async def _update_order(self, order_info):
        """ Update order object.

        Args:
            order_info: Order information.
        """
        if not order_info:
            return

        order_no = order_info["id"]
        size = float(order_info["size"])
        deal_size = float(order_info["dealSize"])
        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY
                if order_info["side"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["size"],
                "remain": order_info["size"],
                "avg_price": order_info["price"]
            }
            order = Order(**info)
            self._orders[order_no] = order

        if order_info["isActive"]:
            if size == deal_size:
                status = ORDER_STATUS_SUBMITTED
            else:
                status = ORDER_STATUS_PARTIAL_FILLED
        else:
            if size == deal_size:
                status = ORDER_STATUS_FILLED
            else:
                status = ORDER_STATUS_CANCELED

        if status != order.status:
            order.status = status
            order.remain = size - deal_size
            order.ctime = order_info["createdAt"]
            order.utime = tools.get_cur_timestamp_ms()
            SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
Ejemplo n.º 12
0
    def _update_order(self, order_info):
        """ 更新订单信息
        @param order_info 订单信息
        """
        order_no = order_info["order_id"]
        quantity = int(order_info["amount"])
        filled_amount = int(order_info["filled_amount"])
        remain = quantity - filled_amount
        average_price = order_info.get("average_price")
        state = order_info["order_state"]
        if state == "open":
            status = ORDER_STATUS_SUBMITTED
            if filled_amount > 0:
                status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "filled":
            status = ORDER_STATUS_FILLED
        elif state == "cancelled":
            status = ORDER_STATUS_CANCELED
        else:
            status = ORDER_STATUS_FAILED

        order = self._orders.get(order_no)
        if not order:
            action = ORDER_ACTION_BUY if order_info[
                "direction"] == "buy" else ORDER_ACTION_SELL
            trade_type = int(order_info.get("label"))
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "symbol": self._symbol,
                "order_no": order_no,
                "action": action,
                "price": order_info["price"],
                "quantity": quantity,
                "remain": remain,
                "trade_type": trade_type
            }
            order = Order(**info)
            self._orders[order_no] = order
        order.status = status
        order.remain = remain
        order.avg_price = average_price
        order.ctime = order_info["creation_timestamp"]
        order.utime = order_info["last_update_timestamp"]
        if order.status in [
                ORDER_STATUS_FILLED, ORDER_STATUS_CANCELED, ORDER_STATUS_FAILED
        ]:
            self._orders.pop(order.order_no)
        return order
Ejemplo n.º 13
0
    async def _special_update_order(self, order_no):
        logger.info('更新not_found_order')
        info = {
            "platform": self._platform,
            "account": self._account,
            "strategy": self._strategy,
            "symbol": self._symbol,
            "order_no": order_no,
        }

        order = Order(**info)
        order.status = 'not_found_order'
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, copy.copy(order))
Ejemplo n.º 14
0
    async def connected_callback(self):
        """ After websocket connection created successfully, pull back all open order information.
        """
        logger.info("Websocket connection authorized successfully.", caller=self)
        order_infos, error = await self._rest_api.get_open_orders(self._raw_symbol)
        if error:
            e = Error("get open orders error: {}".format(error))
            if self._init_success_callback:
                SingleTask.run(self._init_success_callback, False, e)
            return
        for order_info in order_infos:
            order_no = "{}_{}".format(order_info["orderId"], order_info["clientOrderId"])
            if order_info["status"] == "NEW":
                status = ORDER_STATUS_SUBMITTED
            elif order_info["status"] == "PARTIALLY_FILLED":
                status = ORDER_STATUS_PARTIAL_FILLED
            elif order_info["status"] == "FILLED":
                status = ORDER_STATUS_FILLED
            elif order_info["status"] == "CANCELED":
                status = ORDER_STATUS_CANCELED
            elif order_info["status"] == "REJECTED":
                status = ORDER_STATUS_FAILED
            elif order_info["status"] == "EXPIRED":
                status = ORDER_STATUS_FAILED
            else:
                logger.warn("unknown status:", order_info, caller=self)
                continue

            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": order_info["side"],
                "order_type": order_info["type"],
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["origQty"],
                "remain": float(order_info["origQty"]) - float(order_info["executedQty"]),
                "status": status,
                "ctime": order_info["time"],
                "utime": order_info["updateTime"]
            }
            order = Order(**info)
            self._orders[order_no] = order
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, copy.copy(order))

        if self._init_success_callback:
            SingleTask.run(self._init_success_callback, True, None)
Ejemplo n.º 15
0
    async def process(self, msg):
        """ Process message that received from Websocket connection.

        Args:
            msg: message received from Websocket connection.
        """
        logger.debug("msg:", json.dumps(msg), caller=self)
        e = msg.get("e")
        if e == "executionReport":  # Order update.
            if msg["s"] != self._raw_symbol:
                return
            order_no = "{}_{}".format(msg["i"], msg["c"])
            if msg["X"] == "NEW":
                status = ORDER_STATUS_SUBMITTED
            elif msg["X"] == "PARTIALLY_FILLED":
                status = ORDER_STATUS_PARTIAL_FILLED
            elif msg["X"] == "FILLED":
                status = ORDER_STATUS_FILLED
            elif msg["X"] == "CANCELED":
                status = ORDER_STATUS_CANCELED
            elif msg["X"] == "REJECTED":
                status = ORDER_STATUS_FAILED
            elif msg["X"] == "EXPIRED":
                status = ORDER_STATUS_FAILED
            else:
                logger.warn("unknown status:", msg, caller=self)
                return
            order = self._orders.get(order_no)
            if not order:
                info = {
                    "platform": self._platform,
                    "account": self._account,
                    "strategy": self._strategy,
                    "order_no": order_no,
                    "client_order_id": msg["c"],
                    "action": msg["S"],
                    "order_type": msg["o"],
                    "symbol": self._symbol,
                    "price": msg["p"],
                    "quantity": msg["q"],
                    "ctime": msg["O"]
                }
                order = Order(**info)
                self._orders[order_no] = order
            order.remain = float(msg["q"]) - float(msg["z"])
            order.status = status
            order.utime = msg["T"]
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, copy.copy(order))
Ejemplo n.º 16
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            Return order object if or None.
        """
        if order_info["s"] != self._raw_symbol:
            return
        order_no = "{}_{}".format(order_info["i"], order_info["c"])

        if order_info["X"] == "NEW":
            status = ORDER_STATUS_SUBMITTED
        elif order_info["X"] == "PARTIAL_FILLED":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif order_info["X"] == "FILLED":
            status = ORDER_STATUS_FILLED
        elif order_info["X"] == "CANCELED":
            status = ORDER_STATUS_CANCELED
        elif order_info["X"] == "REJECTED":
            status = ORDER_STATUS_FAILED
        elif order_info["X"] == "EXPIRED":
            status = ORDER_STATUS_FAILED
        else:
            return
        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": order_info["S"],
                "order_type": order_info["o"],
                "symbol": self._symbol,
                "price": order_info["p"],
                "quantity": order_info["q"],
                "ctime": order_info["T"]
            }
            order = Order(**info)
            self._orders[order_no] = order
        order.remain = float(order_info["q"]) - float(order_info["z"])
        order.avg_price = order_info["L"]
        order.status = status
        order.utime = order_info["T"]
        order.trade_type = int(order_no[-1])
        SingleTask.run(self._order_update_callback, copy.copy(order))
Ejemplo n.º 17
0
    async def get_order_status(self, symbol, order_id, client_order_id):
        order_info, error = self._rest_api.get_order_status(
            symbol, order_id, client_order_id)
        if not error:
            if order_info['symbol'] != symbol:
                return
            order_no = "{}_{}".format(order_info["orderId"],
                                      order_info["clientOrderId"])

            if order_info["status"] == "NEW":
                status = ORDER_STATUS_SUBMITTED
            elif order_info["status"] == "PARTIAL_FILLED":
                status = ORDER_STATUS_PARTIAL_FILLED
            elif order_info["status"] == "FILLED":
                status = ORDER_STATUS_FILLED
            elif order_info["status"] == "CANCELED":
                status = ORDER_STATUS_CANCELED
            elif order_info["status"] == "REJECTED":
                status = ORDER_STATUS_FAILED
            elif order_info["status"] == "EXPIRED":
                status = ORDER_STATUS_FAILED
            else:
                return
            order = self._orders.get(order_no)
            if not order:
                logger.info('手动查询更新订单状态')
                info = {
                    "platform": self._platform,
                    "account": self._account,
                    "strategy": self._strategy,
                    "order_no": order_no,
                    "action": order_info["side"],
                    "order_type": order_info["type"],
                    "symbol": symbol,
                    "price": order_info["price"],
                    "quantity": order_info["origQty"],
                    "ctime": order_info["time"]
                }
                order = Order(**info)
                self._orders[order_no] = order
            order.remain = float(order_info["origQty"]) - float(
                order_info["executedQty"])
            order.avg_price = None
            order.status = status
            order.utime = order_info["updateTime"]
            order.trade_type = int(order_no[-1])
            SingleTask.run(self._order_update_callback, copy.copy(order))
Ejemplo n.º 18
0
    async def create_order(self,
                           action,
                           price,
                           quantity,
                           order_type=ORDER_TYPE_LIMIT,
                           **kwargs):
        """ Create an order.

        Args:
            action: Trade direction, BUY or SELL.
            price: Price of order.
            quantity: The buying or selling quantity.
            order_type: Order type, MARKET or LIMIT.

        Returns:
            order_no: Order ID if created successfully, otherwise it's None.
            error: Error information, otherwise it's None.
        """
        if action not in [ORDER_ACTION_BUY, ORDER_ACTION_SELL]:
            return None, "action error"
        if order_type not in [ORDER_TYPE_MARKET, ORDER_TYPE_LIMIT]:
            return None, "order_type error"

        price = tools.float_to_str(price)
        quantity = tools.float_to_str(quantity)
        success, error = await self._rest_api.create_order(
            action, self._raw_symbol, price, quantity, order_type)
        if error:
            return None, error
        order_no = str(success["orderNo"])
        infos = {
            "account": self._account,
            "platform": self._platform,
            "strategy": self._strategy,
            "order_no": order_no,
            "symbol": self._symbol,
            "action": action,
            "price": price,
            "quantity": quantity,
            "order_type": order_type
        }
        order = Order(**infos)
        self._orders[order_no] = order
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, copy.copy(order))
        return order_no, None
Ejemplo n.º 19
0
    async def create_order(self,
                           action,
                           price,
                           quantity,
                           order_type=ORDER_TYPE_LIMIT,
                           account_type='margin',
                           exchange='main'):
        """ 创建订单
        @param action 交易方向 BUY/SELL
        @param price 委托价格
        @param quantity 委托数量
        @param order_type 委托类型 LIMIT / MARKET
        """
        if order_type == ORDER_TYPE_LIMIT and price:
            price = tools.float_to_str(price)
        quantity = tools.float_to_str(quantity)

        result, error = await self._rest_api.create_order(
            action, self._raw_symbol, price, quantity, order_type,
            account_type, exchange)
        if error:
            return None, error
        if result['status'] != 0:
            return None, result
        order_id = result["data"]

        # 创建订单成功后,将订单存下来
        info = {
            "platform": self._platform,
            "account": self._account,
            "strategy": self._strategy,
            "order_no": order_id,
            "action": action,
            "symbol": self._symbol,
            "price": price,  # 字符串
            "quantity": quantity,
            "remain": quantity,
            "status": ORDER_STATUS_SUBMITTED,
            "avg_price": price,
            'order_type': order_type
        }
        order = Order(**info)
        self._orders[order_id] = order

        return order_id, None
Ejemplo n.º 20
0
 def _convert_order_format(self, o):
     """将交易所订单结构转换为本交易系统标准订单结构格式
     """
     order_no = str(o["id"])
     state = o["status"]
     remain = float(o["remainingSize"])
     filled = float(o["filledSize"])
     size = float(o["size"])
     price = None if o["price"] == None else float(o["price"])
     avg_price = None if o["avgFillPrice"] == None else float(
         o["avgFillPrice"])
     if state == "new":
         status = ORDER_STATUS_SUBMITTED
     elif state == "open":
         if remain < size:
             status = ORDER_STATUS_PARTIAL_FILLED
         else:
             status = ORDER_STATUS_SUBMITTED
     elif state == "closed":
         if filled < size:
             status = ORDER_STATUS_CANCELED
         else:
             status = ORDER_STATUS_FILLED
     else:
         return None
     info = {
         "platform": self._platform,
         "account": self._account,
         "strategy": self._strategy,
         "order_no": order_no,
         "action":
         ORDER_ACTION_BUY if o["side"] == "buy" else ORDER_ACTION_SELL,
         "symbol": o["market"],
         "price": price,
         "quantity": size,
         "order_type":
         ORDER_TYPE_LIMIT if o["type"] == "limit" else ORDER_TYPE_MARKET,
         "remain": remain,  #size-filled会更好
         "status": status,
         "avg_price": avg_price
     }
     order = Order(**info)
     return order
Ejemplo n.º 21
0
 async def process(self, msg):
     """ 处理websocket上接收到的消息
     """
     logger.debug("msg:", json.dumps(msg), caller=self)
     e = msg.get("e")
     if e == "executionReport":  # 订单更新
         order_no = "{}_{}".format(msg["i"], msg["c"])
         if msg["X"] == "NEW":  # 部分成交
             status = ORDER_STATUS_SUBMITTED
         elif msg["X"] == "PARTIALLY_FILLED":  # 部分成交
             status = ORDER_STATUS_PARTIAL_FILLED
         elif msg["X"] == "FILLED":  # 完全成交
             status = ORDER_STATUS_FILLED
         elif msg["X"] == "CANCELED":  # 取消
             status = ORDER_STATUS_CANCELED
         elif msg["X"] == "REJECTED":  # 拒绝
             status = ORDER_STATUS_FAILED
         elif msg["X"] == "EXPIRED":  # 过期
             status = ORDER_STATUS_FAILED
         else:
             logger.warn("unknown status:", msg, caller=self)
             return
         order = self._orders.get(order_no)
         if not order:
             info = {
                 "platform": self._platform,
                 "account": self._account,
                 "strategy": self._strategy,
                 "order_no": order_no,
                 "action": msg["S"],
                 "order_type": msg["o"],
                 "symbol": self._symbol,
                 "price": msg["p"],
                 "quantity": msg["q"],
                 "ctime": msg["O"]
             }
             order = Order(**info)
             self._orders[order_no] = order
         order.remain = float(msg["q"]) - float(msg["z"])
         order.status = status
         order.utime = msg["T"]
         if self._order_update_callback:
             SingleTask.run(self._order_update_callback, order)
Ejemplo n.º 22
0
    def _update_order(self, order_info):
        """ 更新订单信息
        @param order_info 订单信息
              | "New" -> `Open, `New_order_accepted
              | "PartiallyFilled" -> `Open, `Partially_filled
              | "Filled" -> `Filled, `Filled
              | "DoneForDay" -> `Open, `General_order_update
              | "Canceled" -> `Canceled, `Canceled
              | "PendingCancel" -> `Pending_cancel, `General_order_update
              | "Stopped" -> `Open, `General_order_update
              | "Rejected" -> `Rejected, `New_order_rejected
              | "PendingNew" -> `Pending_open, `General_order_update
              | "Expired" -> `Rejected, `New_order_rejected
              | _ -> invalid_arg' execType ordStatus
        """
        order_no = order_info["orderID"]
        state = order_info.get("ordStatus")
        if state == "New":
            status = ORDER_STATUS_SUBMITTED
        elif state == "PartiallyFilled":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "Filled":
            status = ORDER_STATUS_FILLED
        elif state == "Canceled":
            status = ORDER_STATUS_CANCELED
        elif state in ["PendingNew", "DoneForDay", "PendingCancel"]:
            return
        else:
            return

        order = self._orders.get(order_no)
        if not order:
            action = ORDER_ACTION_BUY if order_info[
                "side"] == "Buy" else ORDER_ACTION_SELL
            text = order_info.get("text")
            trade_type = int(text.split("\n")[-1])
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "symbol": self._symbol,
                "order_no": order_no,
                "action": action,
                "price": order_info.get("price"),
                "quantity": int(order_info["orderQty"]),
                "remain": int(order_info["orderQty"]),
                "trade_type": trade_type
            }
            order = Order(**info)
            self._orders[order_no] = order
        order.status = status

        if order_info.get("cumQty"):
            order.remain = order.quantity - int(order_info.get("cumQty"))
        if order_info.get("avgPx"):
            order.avg_price = order_info.get("avgPx")
        if order.status in [
                ORDER_STATUS_FILLED, ORDER_STATUS_CANCELED, ORDER_STATUS_FAILED
        ]:
            self._orders.pop(order.order_no)
        if order_info.get("timestamp"):
            order.ctime = tools.utctime_str_to_mts(order_info.get("timestamp"))
        if order_info.get("transactTime"):
            order.utime = tools.utctime_str_to_mts(
                order_info.get("transactTime"))
        return order
Ejemplo n.º 23
0
    async def _update_order(self, order_info):
        """
        更新订单信息
        """
        order_no = order_info.get('id')
        is_updated = False
        if order_no is None:
            return is_updated, None
        remain = order_info['unfilled_quantity']
        quantity = order_info['quantity']
        state = order_info['status']
        ctime = order_info['created_at']
        utime = order_info['utime']
        if state == 'FULLY_FILLED':
            status = ORDER_STATUS_FAILED
        elif state == 'PARTIAL_FILLED':
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == 'PENDING':
            status = ORDER_STATUS_SUBMITTED
        elif state == 'PARTIAL_CANCELLED':
            status = ORDER_STATUS_PARTIAL_CANCELED
        elif state == 'FULLY_CANCELLED':
            status = ORDER_STATUS_CANCELED
        else:
            logger.error('订单状态未处理', order_info)
            return is_updated, None

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "action":
                ORDER_ACTION_BUY
                if order_info["direction"] == 'LONG' else ORDER_ACTION_SELL,
                "symbol":
                self._symbol,
                "price":
                order_info["price"],
                "quantity":
                quantity,
                "trade_type":
                TRADE_TYPE_NONE,
                'remain':
                remain,
                'status':
                status
            }
            order = Order(**info)
            is_updated = True
        else:
            if order.remain != remain:
                is_updated = True
                order.remain = remain
            elif order.status != status:
                is_updated = True
                order.status = status
        order.ctime = ctime
        order.utime = utime
        self._orders[order_no] = order
        if state in ('FULLY_FILLED', 'PARTIAL_CANCELLED', 'FULLY_CANCELLED'):
            self._orders.pop(order_no)
        return is_updated, order
Ejemplo n.º 24
0
    async def _update_order(self, order_info):
        """ 处理委托单更新
        @param order_info 委托单详情
        """
        if not order_info:
            return
        status_updated = False
        order_no = str(order_info["orderNo"])
        state = order_info["state"]

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": order_info["action"],
                "symbol": self._symbol,
                "price": order_info["priceLimit"],
                "quantity": order_info["quantity"],
                "remain": order_info["quantityRemaining"],
                "avg_price": order_info["priceLimit"]
            }
            order = Order(**info)
            self._orders[order_no] = order

        # 已提交
        if state == "UNDEAL" or state == "PROCESSING":
            if order.status != ORDER_STATUS_SUBMITTED:
                order.status = ORDER_STATUS_SUBMITTED
                status_updated = True
        # 订单部分成交
        elif state == "PARTDEAL":
            order.status = ORDER_STATUS_PARTIAL_FILLED
            if order.order_type == ORDER_TYPE_LIMIT:
                if float(order.remain) != float(order_info["quantityRemaining"]):
                    status_updated = True
                    order.remain = float(order_info["quantityRemaining"])
            else:
                if float(order.remain) != float(order_info["amountRemaining"]):
                    status_updated = True
                    order.remain = float(order_info["amountRemaining"])
        # 订单成交完成
        elif state == "DEAL":
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
            status_updated = True
        # 订单取消
        elif state == "CANCEL":
            order.status = ORDER_STATUS_CANCELED
            if order.order_type == ORDER_TYPE_LIMIT:
                if float(order.remain) != float(order_info["quantityRemaining"]):
                    order.remain = float(order_info["quantityRemaining"])
            else:
                if float(order.remain) != float(order_info["amountRemaining"]):
                    order.remain = float(order_info["amountRemaining"])
            status_updated = True
        else:
            logger.warn("state error! order_info:", order_info, caller=self)
            return

        # 有状态更新 执行回调
        if status_updated:
            order.ctime = order_info["utcCreate"]
            order.utime = order_info["utcUpdate"]
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, copy.copy(order))

        # 删除已完成订单
        if order.status in [ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED]:
            self._orders.pop(order_no)
Ejemplo n.º 25
0
 def parse(self):
     """ Parse self._data to Order object.
     """
     order = Order(**self.data)
     return order
Ejemplo n.º 26
0
    async def _update_order(self, order_info):
        """ Update order object.

        Args:
            order_info: Order information.
        """
        if not order_info:
            return
        status_updated = False
        order_no = str(order_info["orderNo"])
        state = order_info["state"]

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": order_info["action"],
                "symbol": self._symbol,
                "price": order_info["priceLimit"],
                "quantity": order_info["quantity"],
                "remain": order_info["quantityRemaining"],
                "avg_price": order_info["priceLimit"]
            }
            order = Order(**info)
            self._orders[order_no] = order

        if state == "UNDEAL" or state == "PROCESSING":
            if order.status != ORDER_STATUS_SUBMITTED:
                order.status = ORDER_STATUS_SUBMITTED
                status_updated = True
        elif state == "PARTDEAL":
            order.status = ORDER_STATUS_PARTIAL_FILLED
            if order.order_type == ORDER_TYPE_LIMIT:
                if float(order.remain) != float(
                        order_info["quantityRemaining"]):
                    status_updated = True
                    order.remain = float(order_info["quantityRemaining"])
            else:
                if float(order.remain) != float(order_info["amountRemaining"]):
                    status_updated = True
                    order.remain = float(order_info["amountRemaining"])
        elif state == "DEAL":
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
            status_updated = True
        elif state == "CANCEL":
            order.status = ORDER_STATUS_CANCELED
            status_updated = True
        else:
            logger.warn("state error! order_info:", order_info, caller=self)
            return

        # If order status updated, callback newest order information.
        if status_updated:
            order.ctime = order_info["utcCreate"]
            order.utime = order_info["utcUpdate"]
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
Ejemplo n.º 27
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.
        """
        if order_info["contract_code"] != self._contract_code:
            return
        order_no = str(order_info["order_id"])
        status = order_info["status"]

        order = self._orders.get(order_no)
        if not order:
            if order_info["direction"] == "buy":
                if order_info["offset"] == "open":
                    trade_type = TRADE_TYPE_BUY_OPEN
                else:
                    trade_type = TRADE_TYPE_BUY_CLOSE
            else:
                if order_info["offset"] == "close":
                    trade_type = TRADE_TYPE_SELL_CLOSE
                else:
                    trade_type = TRADE_TYPE_SELL_OPEN

            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "action":
                ORDER_ACTION_BUY
                if order_info["direction"] == "buy" else ORDER_ACTION_SELL,
                "symbol":
                self._contract_code,
                "price":
                order_info["price"],
                "quantity":
                order_info["volume"],
                "trade_type":
                trade_type
            }
            order = Order(**info)
            self._orders[order_no] = order

        if status in [1, 2, 3]:
            order.status = ORDER_STATUS_SUBMITTED
        elif status == 4:
            order.status = ORDER_STATUS_PARTIAL_FILLED
            order.remain = int(order.quantity) - int(
                order_info["trade_volume"])
        elif status == 6:
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
        elif status in [5, 7]:
            order.status = ORDER_STATUS_CANCELED
            order.remain = int(order.quantity) - int(
                order_info["trade_volume"])
        else:
            return

        order.avg_price = order_info["trade_avg_price"]
        order.ctime = order_info["created_at"]
        order.utime = order_info["ts"]

        SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
Ejemplo n.º 28
0
    async def _update_order(self, order_info):
        """ Update order object.

        Args:
            order_info: Order information.
        """
        if not order_info:
            return
        status_updated = False
        order_no = str(order_info["orderNumber"])
        state = order_info["status"]

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY
                if order_info["type"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["rate"],
                "quantity": order_info["amount"],
                "remain": order_info["amount"],
                "avg_price": order_info["filledRate"]
            }
            order = Order(**info)
            self._orders[order_no] = order

        if state == "open":
            filled_amount = float(order_info["filledAmount"])
            if filled_amount == 0:
                state = ORDER_STATUS_SUBMITTED
                if order.status != state:
                    order.status = ORDER_STATUS_SUBMITTED
                    status_updated = True
            else:
                remain = float(order.quantity) - filled_amount
                if order.remain != remain:
                    order.status = ORDER_STATUS_PARTIAL_FILLED
                    order.remain = remain
                    status_updated = True
        elif state == "closed":
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
            status_updated = True
        elif state == "cancelled":
            order.status = ORDER_STATUS_CANCELED
            status_updated = True
        else:
            logger.warn("state error! order_info:", order_info, caller=self)
            return

        if status_updated:
            order.avg_price = order_info["filledRate"]
            order.ctime = int(order_info["timestamp"] * 1000)
            order.utime = int(order_info["timestamp"] * 1000)
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)
Ejemplo n.º 29
0
    async def create_order(self,
                           action,
                           price,
                           quantity,
                           order_type=ORDER_TYPE_LMT):
        """ 创建委托单
        @param action 操作类型 BUY买/SELL卖
        @param price 委托价格
        @param quantity 委托数量
        @param order_type 委托单类型 LMT限价单/MKT市价单
        """
        if action not in [ORDER_ACTION_BUY, ORDER_ACTION_SELL]:
            logger.error('action error! action:', action, caller=self)
            return
        if order_type not in [ORDER_TYPE_MKT, ORDER_TYPE_LMT]:
            logger.error('order_type error! order_type:',
                         order_type,
                         caller=self)
            return

        # 创建订单
        price = tools.float_to_str(price)
        quantity = tools.float_to_str(quantity)
        params = {
            "symbol": self._raw_symbol,
            "action": action,
            "price": price,
            "quantity": quantity,
            "order_type": order_type
        }
        success, result = await self._request.do_request(
            Request.CREATE_ORDER, params)
        if not success:
            logger.error('create order error! strategy:',
                         self._strategy,
                         'symbol:',
                         self._symbol,
                         'action:',
                         action,
                         'price:',
                         price,
                         'quantity:',
                         quantity,
                         'order_type:',
                         order_type,
                         caller=self)
            return None

        order_no = result["order_no"]
        infos = {
            'platform': self._platform,
            'account': self._account,
            'strategy': self._strategy,
            'order_no': order_no,
            'symbol': self._symbol,
            'action': action,
            'price': price,
            'quantity': quantity,
            'order_type': order_type
        }
        order = Order(**infos)

        # 增加订单到订单列表
        self._add_order(order)

        # 数据库里创建新订单记录
        # await self._order_db.create_new_order(order)

        logger.info('order:', order, caller=self)
        return order_no
Ejemplo n.º 30
0
    async def _update_order(self, order_info):
        """ Update order object.

        Args:
            order_info: Order information.
        """
        if not order_info:
            return
        status_updated = False
        order_no = str(order_info["order_id"])
        status = order_info[
            "status"]  # 订单状态,0-未成交,1-部分成交,2-完全成交,3-已撤销未成交,4-已撤销部分成交

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY
                if order_info["type"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["amount"],
                "remain": order_info["amount"],
                "avg_price": order_info["avg_price"]
            }
            order = Order(**info)
            self._orders[order_no] = order

        if status == 0:
            if order.status != ORDER_STATUS_SUBMITTED:
                order.status = ORDER_STATUS_SUBMITTED
                status_updated = True
        elif status == 1:
            remain = float(order_info["amount"]) - float(
                order_info["executed_amount"])
            if order.remain != remain:
                order.remain = remain
                order.status = ORDER_STATUS_PARTIAL_FILLED
                status_updated = True
        elif status == 2:
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
            status_updated = True
        elif status == 3 or status == 4:
            order.status = ORDER_STATUS_CANCELED
            remain = float(order_info["amount"]) - float(
                order_info["executed_amount"])
            order.remain = remain
            status_updated = True
        else:
            logger.warn("state error! order_info:", order_info, caller=self)
            return

        if status_updated:
            order.avg_price = order_info["avg_price"]
            order.ctime = int(order_info["created_date"] * 1000)
            order.utime = int(order_info["finished_date"] * 1000)
            SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)