Beispiel #1
0
    def on_order(self, order: OrderData) -> None:
        # 更新活跃报单
        active_orders = []
        for order in self.app.recorder.get_all_active_orders(
                order.local_symbol):
            active_orders.append(order._to_dict())
        data = {"type": "active_order", "data": active_orders}

        self.io.emit("active_order", data)
        orders = []
        for order in self.app.recorder.get_all_orders():
            orders.append(order._to_dict())
        data = {"type": "order", "data": orders}
        self.io.emit("order", data)
Beispiel #2
0
    def onRtnOrder(self, data: dict):
        """
        Callback of order status update.
        """
        symbol = data["InstrumentID"]
        exchange = symbol_exchange_map.get(symbol, "")
        if not exchange:
            self.order_data.append(data)
            return

        frontid = data["FrontID"]
        sessionid = data["SessionID"]
        order_ref = data["OrderRef"]
        order_id = f"{frontid}_{sessionid}_{order_ref}"

        order = OrderData(symbol=symbol,
                          exchange=exchange,
                          order_id=order_id,
                          type=ORDERTYPE_CTP2VT[data["OrderPriceType"]],
                          direction=DIRECTION_CTP2VT[data["Direction"]],
                          offset=OFFSET_CTP2VT[data["CombOffsetFlag"]],
                          price=data["LimitPrice"],
                          volume=data["VolumeTotalOriginal"],
                          traded=data["VolumeTraded"],
                          status=STATUS_CTP2VT[data["OrderStatus"]],
                          time=data["InsertTime"],
                          gateway_name=self.gateway_name)
        self.on_event(type=EVENT_ORDER, data=order)

        self.sysid_orderid_map[data["OrderSysID"]] = order_id
Beispiel #3
0
    def update_order(self, order: OrderData):
        """"""
        if order.is_active():
            self.active_orders[order.local_order_id] = order
        else:
            if order.local_order_id in self.active_orders:
                self.active_orders.pop(order.local_order_id)

        self.calculate_frozen()
Beispiel #4
0
 def _push_order_callback(self, order: OrderData, is_traded: bool):
     """
     推送order回策略层,
     如果已经成交, 那么找到成交单数据并推送回去,
     如果没有成交 ,那么将order的状态推荐为正在提交中
     :param order_data: 报单
     :param is_traded: 是否成交
     :return:
     """
     if is_traded:
         """ 如果成交了那么同时推送"""
         trade = self.traded_order_mapping[order.order_id]
         order.status = Status.ALLTRADED
         self._push_order()
         self._push_trade(trade)
     else:
         order.status = Status.SUBMITTING
         self.order_id_pending_mapping[order.order_id] = order
         self._push_order(order)
         self.pending.appendleft(order)
Beispiel #5
0
 def _auth_order_price(self, order: OrderData):
     """
     检查报单价格是否超过涨跌停
     :param order: 报单
     :return:
     """
     if order.price > self.current_tick.limit_up or order.price < self.current_tick.limit_down:
         self.log("价格超过涨跌停, 拒单")
         order.status = Status.REJECTED
         self._push_order(order)
         return False
     return True
Beispiel #6
0
    def onRspOrderInsert(self, data: dict, error: dict, reqid: int,
                         last: bool):
        """"""
        order_ref = data["OrderRef"]
        order_id = f"{self.frontid}_{self.sessionid}_{order_ref}"

        symbol = data["InstrumentID"]
        exchange = symbol_exchange_map[symbol]
        order = OrderData(symbol=symbol,
                          exchange=exchange,
                          order_id=order_id,
                          direction=DIRECTION_CTP2VT[data["Direction"]],
                          offset=OFFSET_CTP2VT[data["CombOffsetFlag"]],
                          price=data["LimitPrice"],
                          volume=data["VolumeTotalOriginal"],
                          status=Status.REJECTED,
                          gateway_name=self.gateway_name)
        self.on_event(type=EVENT_ORDER, data=order)
        error['detail'] = "交易委托失败"
        self.on_event(type=EVENT_ERROR, data=error)
Beispiel #7
0
    def match_deal(self, data: OrderData) -> int or TradeData:
        """ 撮合成交
            维护一个返回状态
            -1: 超出下单限制
            -2: 超出涨跌价格
            -3: 未成交
            -4: 资金不足
            p : 成交回报

            todo: 处理冻结 ??

        """
        if self.params.get("deal_pattern") == "match":
            """ 撮合成交 """
            # todo: 是否可以模拟一定量的市场冲击响应? 以靠近更加逼真的回测效果 ????

        elif self.params.get("deal_pattern") == "price":
            """ 见价成交 """
            # 先判断价格和手数是否满足限制条件
            if data.volume > self.params.get(
                    "single_order_limit"
            ) or self.today_volume > self.params.get("single_day_limit"):
                """ 超出限制 直接返回不允许成交 """
                return -1
            if data.price < self.drop_price or data.price > self.upper_price:
                """ 超出涨跌价格 """
                return -2

            # 发单立即冻结
            self.account.update_frozen(data)

            # 进行成交判断
            long_c = self.price.low_price if self.price.low_price is not None else self.price.ask_price_1
            short_c = self.price.high_price if self.price.low_price is not None else self.price.bid_price_1
            long_b = self.price.open_price if self.price.low_price is not None else long_c
            short_b = self.price.open_price if self.price.low_price is not None else short_c
            long_cross = data.direction == Direction.LONG and data.price >= long_c > 0
            short_cross = data.direction == Direction.SHORT and data.price <= short_c and short_c > 0

            # 处理未成交的单子
            for order in self.pending:
                index = self.pending.index(order)
                long_cross = data.direction == Direction.LONG and order.price >= long_c > 0
                short_cross = data.direction == Direction.SHORT and order.price <= short_c and short_c > 0
                if not long_cross and not short_cross:
                    """ 不成交 """
                    continue
                if long_cross:
                    order.price = min(order.price, long_b)
                else:
                    order.price = max(order.price, short_b)
                trade = self._generate_trade_data_from_order(order)
                order.status = Status.ALLTRADED
                [
                    api(deepcopy(order))
                    for api in self.strategy_mapping.values()
                ]
                [api(trade) for api in self.strategy_mapping.values()]
                self.pending.remove(order)

                # 成交,移除冻结
                self.account.update_frozen(order=order, reverse=True)
                self.update_account_margin(trade)

            if not long_cross and not short_cross:
                # 未成交单, 提交到pending里面去
                self.pending.append(data)
                return -3

            if long_cross:
                data.price = min(data.price, long_b)
            else:
                data.price = max(data.price, short_b)
            """ 判断账户资金是否足以支撑成交 """
            if self.account.is_traded(data):
                """ 调用API生成成交单 """
                # 同时这里需要处理是否要进行
                p = self._generate_trade_data_from_order(data)
                self.account.update_trade(p)
                """ 调用strategy的on_trade """
                [api(p) for api in self.strategy_mapping.values()]
                self.today_volume += data.volume
                # 已经成交,同时移除冻结
                self.account.update_frozen(p, reverse=True)
                self.update_account_margin(p)

                return p
            else:
                """ 当前账户不足以支撑成交 """
                return -4
        else:
            raise TypeError("未支持的成交机制")
Beispiel #8
0
 def on_order(self, order: OrderData) -> None:
     data = {
         "type": "order",
         "data": order._to_dict()
     }
     self.io.emit("order", data)