Exemple #1
0
class QA_OrderHandler(QA_Worker):
    """ORDER执行器


    ORDEHANDLDER 归属于MARKET前置

    仅负责一个无状态的执行层

    ORDER执行器的作用是因为 
    在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来
    大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断

    ORDER_Handler的作用就是根据信息更新Order

    用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新

    可用的market_broker:
    1.回测盘
    2.实时模拟盘
    3.实盘

    """

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            order = self.order_queue.insert_order(event.order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            res=[]
            for item in self.order_queue.trade_list:
                result=event.broker.receive_order(
                    QA_Event(event_type=BROKER_EVENT.TRADE, order=item))
                self.order_queue.set_status(
                    item.order_id, result['header']['status'])
                if item.callback:       
                    item.callback(result)
                res.append(result)
            event.res = res
            
            return event

        elif event.event_type is BROKER_EVENT.SETTLE:
            self.order_queue.settle()

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            return self.query_order(event.order_id)

    def query_order(self, order_id):
        return self.order_queue.queue.query()
class QA_OrderHandler(QA_Worker):
    """ORDER执行器


    ORDEHANDLDER 归属于MARKET前置

    仅负责一个无状态的执行层

    ORDER执行器的作用是因为 
    在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来
    大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断

    ORDER_Handler的作用就是根据信息更新Order

    用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新

    可用的market_broker:
    1.回测盘
    2.实时模拟盘
    3.实盘

    """

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            order = self.order_queue.insert_order(event.order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            res=[]
            for item in self.order_queue.trade_list:
                result=event.broker.receive_order(
                    QA_Event(event_type=BROKER_EVENT.TRADE, order=item))
                self.order_queue.set_status(
                    item.order_id, result['header']['status'])
                if item.callback:       
                    item.callback(result)
                res.append(result)
            event.res = res
            
            return event

        elif event.event_type is BROKER_EVENT.SETTLE:
            self.order_queue.settle()

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            return self.query_order(event.order_id)

    def query_order(self, order_id):
        return self.order_queue.queue_df.query()
Exemple #3
0
class QA_OrderHandler(QA_Worker):
    """ORDER执行器
    ORDEHANDLDER 归属于MARKET前置
    仅负责一个无状态的执行层
    ORDER执行器的作用是因为 
    在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来
    大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断
    ORDER_Handler的作用就是根据信息更新Order
    用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新
    可用的market_broker:
    1.回测盘
    2.实时模拟盘
    3.实盘
    ORDERHANDLER 持久化问题:

    设定机制: 2秒查询1次
    持久化: 2秒一次

    2018-07-29

    # 重新设置ORDERHADLER的运行模式:
    -- 常规检查 5秒一次
    -- 如果出现订单 则2-3秒 对账户轮询(直到出现订单成交/撤单为止)
    """
    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()
        self.order_status = pd.DataFrame()
        self.deal_status = pd.DataFrame()
        self.if_start_orderquery = False

        self.monitor = {}  # 1.1新增 用于监控订单

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            """
            OrderHandler 收到订单
            orderhandler 调控转发给broker
            broker返回发单结果(成功/失败)
            orderhandler.order_queue 插入一个订单
            执行回调
            """
            order = event.order
            order = event.broker.receive_order(
                QA_Event(event_type=BROKER_EVENT.TRADE,
                         order=event.order,
                         market_data=event.market_data))

            order = self.order_queue.insert_order(order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            # 实盘和本地 同步执行
            self._trade()
            # event.event_queue.task_done()

        elif event.event_type is BROKER_EVENT.SETTLE:
            """订单队列的结算:


            当队列中的订单都被处理过后:
            算可以结算了
            """

            print('SETTLE ORDERHANDLER')
            self.if_start_orderquery = False
            if len(self.order_queue.pending) > 0:
                pass
            else:
                raise RuntimeWarning('ORDERHANDLER STILL HAVE UNTRADE ORDERS')

            self.order_queue.settle()
            self.order_status = pd.DataFrame()
            self.deal_status = pd.DataFrame()

            try:
                event.event_queue.task_done()
            except:
                pass

        elif event.event_type is BROKER_EVENT.NEXT_TRADEDAY:
            """下一个交易日
            """

            self.if_start_orderquery = True
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self, engine='ORDER', event=event))

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            """query_order和query_deal 需要联动使用 

            query_order 得到所有的订单列表

            query_deal 判断订单状态--> 运行callback函数


            实盘涉及到外部订单问题: 
            及 订单的来源 不完全从QUANTAXIS中发出, 则QA无法记录来源 (标记为外部订单)
            """

            if self.if_start_orderquery:
                try:
                    # 做一些容错处理
                    res = [
                        self.monitor[account].query_orders(
                            account.account_cookie, '')
                        for account in list(self.monitor.keys())
                    ]

                    res = pd.concat(res, axis=0) if len(res) > 0 else None
                except:
                    time.sleep(1)

                self.order_status = res if res is not None else self.order_status
                if len(self.order_status) > 0:
                    QA_SU_save_order(self.order_status)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            event.event_type = MARKET_EVENT.QUERY_DEAL
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(1, 2))

            # 非阻塞
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self, engine='ORDER', event=event))

        elif event.event_type is MARKET_EVENT.QUERY_DEAL:
            """order_handler- query_deal
            将order_handler订单队列中的订单---和deal中匹配起来
            """

            if self.if_start_orderquery:
                res = [
                    self.monitor[account].query_orders(account.account_cookie,
                                                       'filled')
                    for account in list(self.monitor.keys())
                ]
                try:
                    res = pd.concat(
                        res, axis=0) if len(res) > 0 else pd.DataFrame()
                except:
                    res = None

                self.deal_status = res if res is not None else self.deal_status
                if len(self.deal_status) > 0:
                    QA_SU_save_deal(self.deal_status)

            # 检查pending订单, 更新订单状态
            try:
                for order in self.order_queue.pending:
                    if len(self.deal_status) > 0:
                        if order.realorder_id in self.deal_status.index.levels[
                                1]:
                            # 此时有成交推送(但可能是多条)
                            res = self.deal_status.loc[order.account_cookie,
                                                       order.realorder_id]

                            if isinstance(res, pd.Series):
                                order.trade(str(res.trade_id),
                                            float(res.trade_price),
                                            int(res.trade_amount),
                                            str(res.trade_time))
                            elif isinstance(res, pd.DataFrame):
                                if len(res) == 0:
                                    pass

                                elif len(res) == 1:
                                    res = res.iloc[0]
                                    order.trade(str(res.trade_id),
                                                float(res.trade_price),
                                                int(res.trade_amount),
                                                str(res.trade_time))
                                else:
                                    for _, deal in res.iterrows:
                                        order.trade(str(deal.trade_id),
                                                    float(deal.trade_price),
                                                    int(deal.trade_amount),
                                                    str(deal.trade_time))
            except Exception as e:
                print(e)
                print(self.order_queue.order_list)
                print(self.deal_status.index)
                print(self.order_status)
            # event.event_queue.task_done()
            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(2, 5))
            event.event_type = MARKET_EVENT.QUERY_ORDER
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self, engine='ORDER', event=event))

        elif event.event_type is MARKET_EVENT.QUERY_POSITION:
            pass

    def subscribe(self, account, broker):
        print('subscribe')
        self.monitor[account] = broker

    def unsubscribe(self, account, broker):
        try:
            self.monitor.pop(account)
        except:
            print('failled to unscribe {}'.format(account.account_cookie))

    def _trade(self, order=None, account=None):
        # 回测通过query_order加快速度,实盘只有query_orders方法
        if order is not None and hasattr(self.monitor[account], 'query_order'):
            res = self.monitor[account].query_order(order.order_id)
            order.trade(str(res[14]), float(res[6]), int(res[10]), str(res[2]))
        else:
            print('orderhandler: trade')
            res = [
                self.monitor[account].query_orders(account.account_cookie,
                                                   'filled')
                for account in list(self.monitor.keys())
            ]

            try:
                res = pd.concat(res,
                                axis=0) if len(res) > 0 else pd.DataFrame()
            except:
                res = None

            self.deal_status = res if res is not None else self.deal_status
            for order in self.order_queue.pending:
                if len(self.deal_status) > 0:
                    if order.realorder_id in self.deal_status.index.levels[1]:
                        # 此时有成交推送(但可能是多条)
                        #
                        res = self.deal_status.loc[order.account_cookie,
                                                   order.realorder_id]
                        print(res)
                        if isinstance(res, pd.Series):
                            order.trade(str(res.trade_id),
                                        float(res.trade_price),
                                        int(res.trade_amount),
                                        str(res.trade_time))
                        elif isinstance(res, pd.DataFrame):
                            if len(res) == 0:
                                pass

                            elif len(res) == 1:
                                res = res.iloc[0]
                                order.trade(str(res.trade_id),
                                            float(res.trade_price),
                                            int(res.trade_amount),
                                            str(res.trade_time))
                            else:
                                # print(res)
                                # print(len(res))
                                for _, deal in res.iterrows:
                                    order.trade(str(deal.trade_id),
                                                float(deal.trade_price),
                                                int(deal.trade_amount),
                                                str(deal.trade_time))
            # print('order_handler: finish trade')
            return True
class QA_OrderHandler(QA_Worker):
    """ORDER执行器
    ORDEHANDLDER 归属于MARKET前置
    仅负责一个无状态的执行层
    ORDER执行器的作用是因为 
    在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来
    大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断
    ORDER_Handler的作用就是根据信息更新Order
    用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新
    可用的market_broker:
    1.回测盘
    2.实时模拟盘
    3.实盘
    ORDERHANDLER 持久化问题:

    设定机制: 2秒查询1次
    持久化: 2秒一次

    2018-07-29

    # 重新设置ORDERHADLER的运行模式:
    -- 常规检查 5秒一次
    -- 如果出现订单 则2-3秒 对账户轮询(直到出现订单成交/撤单为止)
    """

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()
        self.order_status = pd.DataFrame()
        self.deal_status = pd.DataFrame()
        self.if_start_orderquery = False

        self.monitor = {} # 1.1新增 用于监控订单

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            """
            OrderHandler 收到订单
            orderhandler 调控转发给broker
            broker返回发单结果(成功/失败)
            orderhandler.order_queue 插入一个订单
            执行回调
            """
            order = event.order
            order = event.broker.receive_order(
                QA_Event(
                    event_type=BROKER_EVENT.TRADE,
                    order=event.order,
                    market_data=event.market_data
                )
            )

            order = self.order_queue.insert_order(order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            # 实盘和本地 同步执行
            self._trade()
            # event.event_queue.task_done()

        elif event.event_type is BROKER_EVENT.SETTLE:
            """订单队列的结算:


            当队列中的订单都被处理过后:
            算可以结算了
            """

            print('SETTLE ORDERHANDLER')
            self.if_start_orderquery = False
            if len(self.order_queue.pending) > 0:
                pass
            else:
                raise RuntimeWarning('ORDERHANDLER STILL HAVE UNTRADE ORDERS')

            self.order_queue.settle()
            self.order_status = pd.DataFrame()
            self.deal_status = pd.DataFrame()

            try:
                event.event_queue.task_done()
            except:
                pass

        elif event.event_type is BROKER_EVENT.NEXT_TRADEDAY:
            """下一个交易日
            """

            self.if_start_orderquery = True
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self,
                            engine='ORDER',
                            event=event)
                )

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            """query_order和query_deal 需要联动使用 

            query_order 得到所有的订单列表

            query_deal 判断订单状态--> 运行callback函数


            实盘涉及到外部订单问题: 
            及 订单的来源 不完全从QUANTAXIS中发出, 则QA无法记录来源 (标记为外部订单)
            """

            if self.if_start_orderquery:
                try:
                    # 做一些容错处理
                    res = [
                        self.monitor[account].query_orders(
                            account.account_cookie,
                            ''
                        ) for account in list(self.monitor.keys())
                    ]

                    res = pd.concat(res, axis=0) if len(res) > 0 else None
                except:
                    time.sleep(1)

                self.order_status = res if res is not None else self.order_status
                if len(self.order_status) > 0:
                    QA_SU_save_order(self.order_status)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            event.event_type = MARKET_EVENT.QUERY_DEAL
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(1, 2))

            # 非阻塞
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self,
                            engine='ORDER',
                            event=event)
                )

        elif event.event_type is MARKET_EVENT.QUERY_DEAL:
            """order_handler- query_deal
            将order_handler订单队列中的订单---和deal中匹配起来
            """

            if self.if_start_orderquery:
                res = [
                    self.monitor[account].query_orders(
                        account.account_cookie,
                        'filled'
                    ) for account in list(self.monitor.keys())
                ]
                try:
                    res = pd.concat(
                        res,
                        axis=0
                    ) if len(res) > 0 else pd.DataFrame()
                except:
                    res = None

                self.deal_status = res if res is not None else self.deal_status
                if len(self.deal_status) > 0:
                    QA_SU_save_deal(self.deal_status)

            # 检查pending订单, 更新订单状态
            try:
                for order in self.order_queue.pending:
                    if len(self.deal_status) > 0:
                        if order.realorder_id in self.deal_status.index.levels[1
                                                                              ]:
                            # 此时有成交推送(但可能是多条)
                            res = self.deal_status.loc[order.account_cookie,
                                                       order.realorder_id]

                            if isinstance(res, pd.Series):
                                order.trade(
                                    str(res.trade_id),
                                    float(res.trade_price),
                                    int(res.trade_amount),
                                    str(res.trade_time)
                                )
                            elif isinstance(res, pd.DataFrame):
                                if len(res) == 0:
                                    pass

                                elif len(res) == 1:
                                    res = res.iloc[0]
                                    order.trade(
                                        str(res.trade_id),
                                        float(res.trade_price),
                                        int(res.trade_amount),
                                        str(res.trade_time)
                                    )
                                else:
                                    for _, deal in res.iterrows:
                                        order.trade(
                                            str(deal.trade_id),
                                            float(deal.trade_price),
                                            int(deal.trade_amount),
                                            str(deal.trade_time)
                                        )
            except Exception as e:
                print(e)
                print(self.order_queue.order_list)
                print(self.deal_status.index)
                print(self.order_status)
            # event.event_queue.task_done()
            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(2, 5))
            event.event_type = MARKET_EVENT.QUERY_ORDER
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self,
                            engine='ORDER',
                            event=event)
                )

        elif event.event_type is MARKET_EVENT.QUERY_POSITION:
            pass

    def subscribe(self, account, broker):
        print('subscribe')
        self.monitor[account] = broker

    def unsubscribe(self, account, broker):
        try:
            self.monitor.pop(account)
        except:
            print('failled to unscribe {}'.format(account.account_cookie))

    def _trade(self, order=None, account=None):
        # 回测通过query_order加快速度,实盘只有query_orders方法
        if order is not None and hasattr(self.monitor[account], 'query_order'):
            res = self.monitor[account].query_order(order.order_id)
            order.trade(str(res[14]), float(res[6]), int(res[10]), str(res[2]))
        else:
            print('orderhandler: trade')
            res = [
                self.monitor[account].query_orders(
                    account.account_cookie,
                    'filled'
                ) for account in list(self.monitor.keys())
            ]

            try:
                res = pd.concat(res, axis=0) if len(res) > 0 else pd.DataFrame()
            except:
                res = None

            self.deal_status = res if res is not None else self.deal_status
            for order in self.order_queue.pending:
                if len(self.deal_status) > 0:
                    if order.realorder_id in self.deal_status.index.levels[1]:
                        # 此时有成交推送(但可能是多条)
                        #
                        res = self.deal_status.loc[order.account_cookie,
                                                   order.realorder_id]
                        print(res)
                        if isinstance(res, pd.Series):
                            order.trade(
                                str(res.trade_id),
                                float(res.trade_price),
                                int(res.trade_amount),
                                str(res.trade_time)
                            )
                        elif isinstance(res, pd.DataFrame):
                            if len(res) == 0:
                                pass

                            elif len(res) == 1:
                                res = res.iloc[0]
                                order.trade(
                                    str(res.trade_id),
                                    float(res.trade_price),
                                    int(res.trade_amount),
                                    str(res.trade_time)
                                )
                            else:
                                # print(res)
                                # print(len(res))
                                for _, deal in res.iterrows:
                                    order.trade(
                                        str(deal.trade_id),
                                        float(deal.trade_price),
                                        int(deal.trade_amount),
                                        str(deal.trade_time)
                                    )
            # print('order_handler: finish trade')
            return True
class QA_OrderHandlerAsync(QA_Worker):
    """ORDER执行器
    异步handler

    """

    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()
        self.order_status = pd.DataFrame()
        self.deal_status = pd.DataFrame()
        self.if_start_orderquery = False

        self.monitor = {}  # 1.1新增 用于监控订单

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            """
            OrderHandler 收到订单

            orderhandler 调控转发给broker

            broker返回发单结果(成功/失败)

            orderhandler.order_queue 插入一个订单

            执行回调

            """

            order = event.order
            order = event.broker.receive_order(
                QA_Event(event_type=BROKER_EVENT.TRADE, order=event.order, market_data=event.market_data))
            # print(threading.current_thread().ident)
            order = self.order_queue.insert_order(order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            # 实盘和本地 同步执行
            self._trade()
            # event.event_queue.task_done()

        elif event.event_type is BROKER_EVENT.SETTLE:

            """订单队列的结算:


            当队列中的订单都被处理过后:
            算可以结算了
            """

            print('SETTLE ORDERHANDLER')

            # if len(self.order_queue.untrade) > 0:
            #     self.if_start_orderquery = False
            #     event.event_type = BROKER_EVENT.TRADE
            #     event.event_queue.put(
            #         QA_Task(
            #             worker=self,
            #             engine='ORDER',
            #             event=event
            #         )
            #     )

            if len(self.order_queue.untrade)==0:
                self._trade()
            else:
                
                self._trade()
                # print(self.order_queue.untrade)

            self.order_queue.settle()

            self.order_status = pd.DataFrame()
            self.deal_status = pd.DataFrame()

            try:
                event.event_queue.task_done()
            except:
                pass

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            """query_order和query_deal 需要联动使用 

            query_order 得到所有的订单列表

            query_deal 判断订单状态--> 运行callback函数


            实盘涉及到外部订单问题: 
            及 订单的来源 不完全从QUANTAXIS中发出, 则QA无法记录来源 (标记为外部订单)
            """

            if self.if_start_orderquery:
                # if QA_util_if_tradetime(datetime.datetime.now()):

                    # print(event.broker)
                    # print(event.account_cookie)
                try:
                    # 做一些容错处理
                    res = [self.monitor[account].query_orders(
                        account.account_cookie, '') for account in list(self.monitor.keys())]

                    res = pd.concat(res, axis=0) if len(
                        res) > 0 else None

                except:
                    time.sleep(1)

                self.order_status = res if res is not None else self.order_status
                if len(self.order_status) > 0:
                    QA_SU_save_order(self.order_status)
                # else:
                #     time.sleep(1)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            # event=event
            event.event_type = MARKET_EVENT.QUERY_DEAL
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(1, 2))
            # event.event_queue.task_done()
            # 非阻塞
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(
                        worker=self,
                        engine='ORDER',
                        event=event
                    )
                )
            # time.sleep(random.randint(2,5))
            # print(event.event_type)
            # print(event2.event_type)
            # self.run(event)

            # print(self.order_status)
            # print('UPDATE ORDERS')

        elif event.event_type is MARKET_EVENT.QUERY_DEAL:

            """order_handler- query_deal

            将order_handler订单队列中的订单---和deal中匹配起来


            """

            # if len(self.order_queue.pending) > 0:
            #     for order in self.order_queue.pending:
            #         #self.query
            #         waiting_realorder_id = [
            #             order.realorder_id for order in self.order_queue.trade_list]
            #         result = event.broker.query_deal
            #         time.sleep(1)
            if self.if_start_orderquery:
                res = [self.monitor[account].query_orders(
                    account.account_cookie, 'filled') for account in list(self.monitor.keys())]

                try:
                    #res=[pd.DataFrame() if not isinstance(item,pd.DataFrame) else item for item in res]
                    res = pd.concat(res, axis=0) if len(
                        res) > 0 else pd.DataFrame()
                except:
                    res = None

                self.deal_status = res if res is not None else self.deal_status
                if len(self.deal_status) > 0:
                    QA_SU_save_deal(self.deal_status)
                # print(self.order_status)

            # 检查pending订单, 更新订单状态
            try:
                for order in self.order_queue.pending:
                    if len(self.deal_status) > 0:
                        if order.realorder_id in self.deal_status.index.levels[1]:
                            # 此时有成交推送(但可能是多条)
                            #
                            res = self.deal_status.loc[order.account_cookie,
                                                       order.realorder_id]

                            if isinstance(res, pd.Series):
                                order.trade(str(res.trade_id), float(res.trade_price), int(
                                    res.trade_amount), str(res.trade_time))
                            elif isinstance(res, pd.DataFrame):
                                if len(res) == 0:
                                    pass

                                elif len(res) == 1:
                                    res = res.iloc[0]
                                    order.trade(str(res.trade_id), float(res.trade_price), int(
                                        res.trade_amount), str(res.trade_time))
                                else:
                                    print(res)
                                    print(len(res))
                                    for _, deal in res.iterrows:
                                        order.trade(str(deal.trade_id), float(deal.trade_price), int(
                                            deal.trade_amount), str(deal.trade_time))
            except Exception as e:
                print(e)
                print(self.order_queue.order_list)
                print(self.deal_status.index)
                print(self.order_status)
            # event.event_queue.task_done()
            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(2, 5))
            event.event_type = MARKET_EVENT.QUERY_ORDER
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(
                        worker=self,
                        engine='ORDER',
                        event=event
                    )
                )
            # self.run(event)
            # self.run(event)

        elif event.event_type is MARKET_EVENT.QUERY_POSITION:
            pass

    def subscribe(self, account, broker):
        print('subscribe')
        self.monitor[account] = broker

    def unsubscribe(self, account, broker):
        try:
            self.monitor.pop(account)
        except:
            print('failled to unscribe {}'.format(account.account_cookie))


    async def _trade(self):
        res = [self.monitor[account].query_orders(
            account.account_cookie, 'filled') for account in list(self.monitor.keys())]

        try:
            #res=[pd.DataFrame() if not isinstance(item,pd.DataFrame) else item for item in res]
            res = pd.concat(res, axis=0) if len(
                res) > 0 else pd.DataFrame()
        except:
            res = None

        self.deal_status = res if res is not None else self.deal_status
        for order in self.order_queue.pending:



            if len(self.deal_status) > 0:
                if order.realorder_id in self.deal_status.index.levels[1]:
                    # 此时有成交推送(但可能是多条)
                    #
                    res = self.deal_status.loc[order.account_cookie,
                                                order.realorder_id]

                    if isinstance(res, pd.Series):
                        await order.trade(str(res.trade_id), float(res.trade_price), int(
                            res.trade_amount), str(res.trade_time))
                    elif isinstance(res, pd.DataFrame):
                        if len(res) == 0:
                            pass

                        elif len(res) == 1:
                            res = res.iloc[0]
                            order.trade(str(res.trade_id), float(res.trade_price), int(
                                res.trade_amount), str(res.trade_time))
                        else:
                            print(res)
                            print(len(res))
                            for _, deal in res.iterrows:
                                order.trade(str(deal.trade_id), float(deal.trade_price), int(
                                    deal.trade_amount), str(deal.trade_time))
        return True
Exemple #6
0
class QA_OrderHandlerAsync(QA_Worker):
    """ORDER执行器
    异步handler

    """
    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()
        self.order_status = pd.DataFrame()
        self.deal_status = pd.DataFrame()
        self.if_start_orderquery = False

        self.monitor = {}  # 1.1新增 用于监控订单

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            """
            OrderHandler 收到订单

            orderhandler 调控转发给broker

            broker返回发单结果(成功/失败)

            orderhandler.order_queue 插入一个订单

            执行回调

            """

            order = event.order
            order = event.broker.receive_order(
                QA_Event(event_type=BROKER_EVENT.TRADE,
                         order=event.order,
                         market_data=event.market_data))
            # print(threading.current_thread().ident)
            order = self.order_queue.insert_order(order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            # 实盘和本地 同步执行
            self._trade()
            # event.event_queue.task_done()

        elif event.event_type is BROKER_EVENT.SETTLE:
            """订单队列的结算:


            当队列中的订单都被处理过后:
            算可以结算了
            """

            print('SETTLE ORDERHANDLER')

            # if len(self.order_queue.untrade) > 0:
            #     self.if_start_orderquery = False
            #     event.event_type = BROKER_EVENT.TRADE
            #     event.event_queue.put(
            #         QA_Task(
            #             worker=self,
            #             engine='ORDER',
            #             event=event
            #         )
            #     )

            if len(self.order_queue.untrade) == 0:
                self._trade()
            else:

                self._trade()
                # print(self.order_queue.untrade)

            self.order_queue.settle()

            self.order_status = pd.DataFrame()
            self.deal_status = pd.DataFrame()

            try:
                event.event_queue.task_done()
            except:
                pass

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            """query_order和query_deal 需要联动使用 

            query_order 得到所有的订单列表

            query_deal 判断订单状态--> 运行callback函数


            实盘涉及到外部订单问题: 
            及 订单的来源 不完全从QUANTAXIS中发出, 则QA无法记录来源 (标记为外部订单)
            """

            if self.if_start_orderquery:
                # if QA_util_if_tradetime(datetime.datetime.now()):

                # print(event.broker)
                # print(event.account_cookie)
                try:
                    # 做一些容错处理
                    res = [
                        self.monitor[account].query_orders(
                            account.account_cookie, '')
                        for account in list(self.monitor.keys())
                    ]

                    res = pd.concat(res, axis=0) if len(res) > 0 else None

                except:
                    time.sleep(1)

                self.order_status = res if res is not None else self.order_status
                if len(self.order_status) > 0:
                    QA_SU_save_order(self.order_status)
                # else:
                #     time.sleep(1)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            # event=event
            event.event_type = MARKET_EVENT.QUERY_DEAL
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(1, 2))
            # event.event_queue.task_done()
            # 非阻塞
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self, engine='ORDER', event=event))
            # time.sleep(random.randint(2,5))
            # print(event.event_type)
            # print(event2.event_type)
            # self.run(event)

            # print(self.order_status)
            # print('UPDATE ORDERS')

        elif event.event_type is MARKET_EVENT.QUERY_DEAL:
            """order_handler- query_deal

            将order_handler订单队列中的订单---和deal中匹配起来


            """

            # if len(self.order_queue.pending) > 0:
            #     for order in self.order_queue.pending:
            #         #self.query
            #         waiting_realorder_id = [
            #             order.realorder_id for order in self.order_queue.trade_list]
            #         result = event.broker.query_deal
            #         time.sleep(1)
            if self.if_start_orderquery:
                res = [
                    self.monitor[account].query_orders(account.account_cookie,
                                                       'filled')
                    for account in list(self.monitor.keys())
                ]

                try:
                    #res=[pd.DataFrame() if not isinstance(item,pd.DataFrame) else item for item in res]
                    res = pd.concat(
                        res, axis=0) if len(res) > 0 else pd.DataFrame()
                except:
                    res = None

                self.deal_status = res if res is not None else self.deal_status
                if len(self.deal_status) > 0:
                    QA_SU_save_deal(self.deal_status)
                # print(self.order_status)

            # 检查pending订单, 更新订单状态
            try:
                for order in self.order_queue.pending:
                    if len(self.deal_status) > 0:
                        if order.realorder_id in self.deal_status.index.levels[
                                1]:
                            # 此时有成交推送(但可能是多条)
                            #
                            res = self.deal_status.loc[order.account_cookie,
                                                       order.realorder_id]

                            if isinstance(res, pd.Series):
                                order.trade(str(res.trade_id),
                                            float(res.trade_price),
                                            int(res.trade_amount),
                                            str(res.trade_time))
                            elif isinstance(res, pd.DataFrame):
                                if len(res) == 0:
                                    pass

                                elif len(res) == 1:
                                    res = res.iloc[0]
                                    order.trade(str(res.trade_id),
                                                float(res.trade_price),
                                                int(res.trade_amount),
                                                str(res.trade_time))
                                else:
                                    print(res)
                                    print(len(res))
                                    for _, deal in res.iterrows:
                                        order.trade(str(deal.trade_id),
                                                    float(deal.trade_price),
                                                    int(deal.trade_amount),
                                                    str(deal.trade_time))
            except Exception as e:
                print(e)
                print(self.order_queue.order_list)
                print(self.deal_status.index)
                print(self.order_status)
            # event.event_queue.task_done()
            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(2, 5))
            event.event_type = MARKET_EVENT.QUERY_ORDER
            if self.if_start_orderquery:
                event.event_queue.put(
                    QA_Task(worker=self, engine='ORDER', event=event))
            # self.run(event)
            # self.run(event)

        elif event.event_type is MARKET_EVENT.QUERY_POSITION:
            pass

    def subscribe(self, account, broker):
        print('subscribe')
        self.monitor[account] = broker

    def unsubscribe(self, account, broker):
        try:
            self.monitor.pop(account)
        except:
            print('failled to unscribe {}'.format(account.account_cookie))

    async def _trade(self):
        res = [
            self.monitor[account].query_orders(account.account_cookie,
                                               'filled')
            for account in list(self.monitor.keys())
        ]

        try:
            #res=[pd.DataFrame() if not isinstance(item,pd.DataFrame) else item for item in res]
            res = pd.concat(res, axis=0) if len(res) > 0 else pd.DataFrame()
        except:
            res = None

        self.deal_status = res if res is not None else self.deal_status
        for order in self.order_queue.pending:

            if len(self.deal_status) > 0:
                if order.realorder_id in self.deal_status.index.levels[1]:
                    # 此时有成交推送(但可能是多条)
                    #
                    res = self.deal_status.loc[order.account_cookie,
                                               order.realorder_id]

                    if isinstance(res, pd.Series):
                        await order.trade(str(res.trade_id),
                                          float(res.trade_price),
                                          int(res.trade_amount),
                                          str(res.trade_time))
                    elif isinstance(res, pd.DataFrame):
                        if len(res) == 0:
                            pass

                        elif len(res) == 1:
                            res = res.iloc[0]
                            order.trade(str(res.trade_id),
                                        float(res.trade_price),
                                        int(res.trade_amount),
                                        str(res.trade_time))
                        else:
                            print(res)
                            print(len(res))
                            for _, deal in res.iterrows:
                                order.trade(str(deal.trade_id),
                                            float(deal.trade_price),
                                            int(deal.trade_amount),
                                            str(deal.trade_time))
        return True
class QA_OrderHandler(QA_Worker):
    """ORDER执行器


    ORDEHANDLDER 归属于MARKET前置

    仅负责一个无状态的执行层

    ORDER执行器的作用是因为 
    在实盘中 当一个订单发送出去的时候,市场不会返回一个更新的订单类回来
    大部分时间都依赖子线程主动查询 或者是一个市场信息来进行判断

    ORDER_Handler的作用就是根据信息更新Order

    用于接受订单 发送给相应的marker_broker 再根据返回的信息 进行更新

    可用的market_broker:
    1.回测盘
    2.实时模拟盘
    3.实盘



    ORDERHANDLER 持久化问题:

    设定机制: 2秒查询1次
    持久化: 2秒一次

    2018-07-29


    # 重新设置ORDERHADLER的运行模式:

    -- 常规检查 5秒一次

    -- 如果出现订单 则2-3秒 对账户轮询(直到出现订单成交/撤单为止)



    """
    def __init__(self, *args, **kwargs):
        super().__init__()
        self.order_queue = QA_OrderQueue()
        self.type = EVENT_TYPE.MARKET_EVENT

        self.event = QA_Event()
        self.order_status = pd.DataFrame()
        self.deal_status = pd.DataFrame()
        self.if_start_orderquery = False

    def run(self, event):
        if event.event_type is BROKER_EVENT.RECEIVE_ORDER:
            # 此时的message应该是订单类
            """
            OrderHandler 收到订单

            orderhandler 调控转发给broker

            broker返回发单结果(成功/失败)

            orderhandler.order_queue 插入一个订单

            执行回调

            """

            order = event.order
            # print(event.broker)
            order = event.broker.receive_order(
                QA_Event(event_type=BROKER_EVENT.TRADE, order=event.order))
            # print(threading.current_thread().ident)
            order = self.order_queue.insert_order(order)
            if event.callback:
                event.callback(order)

        elif event.event_type is BROKER_EVENT.TRADE:
            # 实盘和本地 同步执行
            res = []
            for order in self.order_queue.pending:
                result = event.broker.query_orders(order.account_cookie,
                                                   order.realorder_id)
                self.order_queue.set_status(order.order_id,
                                            result['header']['status'])
                if order.callback:
                    order.callback(result)
                res.append(result)
            event.res = res

            return event

        elif event.event_type is BROKER_EVENT.SETTLE:
            self.order_queue.settle()

        elif event.event_type is MARKET_EVENT.QUERY_ORDER:
            """query_order和query_deal 需要联动使用 

            query_order 得到所有的订单列表

            query_deal 判断订单状态--> 运行callback函数


            实盘涉及到外部订单问题: 
            及 订单的来源 不完全从QUANTAXIS中发出, 则QA无法记录来源 (标记为外部订单)
            """

            if self.if_start_orderquery:
                # if QA_util_if_tradetime(datetime.datetime.now()):

                # print(event.broker)
                # print(event.account_cookie)
                try:
                    # 做一些容错处理
                    res = [
                        event.broker[i].query_orders(event.account_cookie[i],
                                                     '')
                        for i in range(len(event.account_cookie))
                    ]
                    res = pd.concat(res, axis=0) if len(res) > 0 else None

                except:
                    time.sleep(1)

                self.order_status = res if res is not None else self.order_status
                if len(self.order_status) > 0:
                    QA_SU_save_order(self.order_status)
                # else:
                #     time.sleep(1)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            # event=event
            event.event_type = MARKET_EVENT.QUERY_DEAL
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(1, 2))

            # 非阻塞
            event.event_queue.put(
                QA_Task(worker=self, engine='ORDER', event=event))
            # time.sleep(random.randint(2,5))
            # print(event.event_type)
            # print(event2.event_type)
            # self.run(event)

            # print(self.order_status)
            # print('UPDATE ORDERS')

        elif event.event_type is MARKET_EVENT.QUERY_DEAL:
            """order_handler- query_deal

            将order_handler订单队列中的订单---和deal中匹配起来


            """

            # if len(self.order_queue.pending) > 0:
            #     for order in self.order_queue.pending:
            #         #self.query
            #         waiting_realorder_id = [
            #             order.realorder_id for order in self.order_queue.trade_list]
            #         result = event.broker.query_deal
            #         time.sleep(1)
            if self.if_start_orderquery:
                self.deal_status = [
                    event.broker[i].query_orders(event.account_cookie[i],
                                                 'filled')
                    for i in range(len(event.account_cookie))
                ]
                # print(self.order_status)
                self.deal_status = pd.concat(
                    self.deal_status,
                    axis=0) if len(self.deal_status) > 0 else pd.DataFrame()
                if len(self.deal_status) > 0:
                    QA_SU_save_deal(self.deal_status)
                # print(self.order_status)

            # 这里加入随机的睡眠时间 以免被发现固定的刷新请求
            if event.event_queue.qsize() < 1:
                time.sleep(random.randint(2, 5))
            event.event_type = MARKET_EVENT.QUERY_ORDER

            event.event_queue.put(
                QA_Task(worker=self, engine='ORDER', event=event))
            # self.run(event)
            # self.run(event)

        elif event.event_type is MARKET_EVENT.QUERY_POSITION:
            pass

    def query_order(self, order_id):
        pass