def _settle(self, broker_name, callback=False): #strDbg = QA_util_random_with_topic("QA_Market._settle") #print(">-----------------------_settle----------------------------->", strDbg) # 向事件线程发送BROKER的SETTLE事件 # 向事件线程发送ACCOUNT的SETTLE事件 for account in self.session.values(): if account.running_environment == RUNNING_ENVIRONMENT.TZERO: for order in account.close_positions_order: self.event_queue.put( QA_Task(worker=self.broker[account.broker], engine=account.broker, event=QA_Event( event_type=BROKER_EVENT.RECEIVE_ORDER, order=order, callback=self.on_insert_order))) if account.broker == broker_name: self.event_queue.put( QA_Task(worker=account, engine=broker_name, event=QA_Event(event_type=ACCOUNT_EVENT.SETTLE))) self.event_queue.put( QA_Task(worker=self.broker[broker_name], engine=broker_name, event=QA_Event(event_type=BROKER_EVENT.SETTLE, broker=self.broker[broker_name], callback=callback))) print('===== SETTLED {} ====='.format(self.running_time))
def _settle(self, broker_name, callback=False): #strDbg = QA_util_random_with_topic("QA_Market._settle") print( ">-----------------------_settle----------------------------->", "QA_Market._settle" ) # 向事件线程发送BROKER的SETTLE事件 # 向事件线程发送ACCOUNT的SETTLE事件 for account in self.session.values(): """t0账户先结算当日仓位 """ if account.broker == broker_name: if account.running_environment == RUNNING_ENVIRONMENT.TZERO: for order in account.close_positions_order: price_slice = self.query_data_no_wait( broker_name=order.broker, frequence=order.frequence, market_type=order.market_type, code=order.code, start=order.datetime ) price_slice = price_slice if price_slice is None else price_slice[ 0] self.order_handler.run( QA_Event( broker=self.broker[account.broker], event_type=BROKER_EVENT.RECEIVE_ORDER, order=order, market_data=price_slice, callback=self.on_insert_order ) ) self._trade(event=QA_Event(broker_name=broker_name)) self.broker[broker_name].run( QA_Event( event_type=BROKER_EVENT.SETTLE, broker=self.broker[broker_name], callback=callback ) ) for account in self.session.values(): print(account.history) account.settle() print('===== SETTLED {} ====='.format(self.running_time))
def _renew_account(self): for account in self.session.values(): self.submit( QA_Task( worker=account, event=QA_Event( event_type=ACCOUNT_EVENT.SETTLE)))
def run(self): """generator driven data flow """ # 如果出现了日期的改变 才会进行结算的事件 _date = None for data in self.ingest_data: date = data.date[0] if self.market_type is MARKET_TYPE.STOCK_CN: if _date != date: self.market._settle(self.broker_name) elif self.market_type in [ MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN, MARKET_TYPE.FUTURE_CN ]: self.market._settle(self.broker_name) self.broker.run( QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA, market_data=data)) self.market.upcoming_data(self.broker_name, data) self.market.trade_engine.join() _date = date self.after_success()
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 run(self): """generator driven data flow """ # 如果出现了日期的改变 才会进行结算的事件 _date = None for data in self.ingest_data: #对于在ingest_data中的数据 #<class 'QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day'> date = data.date[0] # if self.market_type is MARKET_TYPE.STOCK_CN: #如果是股票市场 if _date != date: # 如果新的date # 前一天的交易日已经过去 # 往 broker 和 account 发送 settle 事件 self.market._settle(self.broker_name) elif self.market_type in [ MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN, MARKET_TYPE.FUTURE_CN ]: #基金 指数 期货 self.market._settle(self.broker_name) #print(data) self.broker.run( QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA, market_data=data)) self.market.upcoming_data(self.broker_name, data) # 生成 UPCOMING_DATA 事件放到 队列中去执行 self.market.trade_engine.join() _date = date self.after_success()
def upcoming_data(self, broker, data): ''' 更新市场数据 broker 为名字, data 是市场数据 被 QABacktest 中run 方法调用 upcoming_data ''' # main thread' # if self.running_time is not None and self.running_time!= data.datetime[0]: # for item in self.broker.keys(): # self._settle(item) self.running_time = data.datetime[0] for item in self.session.values(): # session里面是已经注册的account self.event_queue.put( QA_Task( worker=item, # item 是Account 类型, 是 QA_Work类型, 处理这个 事件 event=QA_Event( event_type=ENGINE_EVENT.UPCOMING_DATA, # args 附加的参数 market_data=data, broker_name=broker, send_order=self. insert_order, # 🛠todo insert_order = insert_order query_data=self.query_data_no_wait, query_order=self.query_order, query_assets=self.query_assets, query_trade=self.query_trade)))
def run(self): """generator driven data flow """ # 如果出现了日期的改变 才会进行结算的事件 _date = None while QA_util_if_tradetime(self.now): for data in self.ingest_data: # 对于在ingest_data中的数据 # <class 'QUANTAXIS.QAData.QADataStruct.QA_DataStruct_Stock_day'> date = data.date[0] if self.market_type is MARKET_TYPE.STOCK_CN: # 如果是股票市场 if _date != date: # 如果新的date # 前一天的交易日已经过去 # 往 broker 和 account 发送 settle 事件 try: self.market.trade_engine.join() # time.sleep(2) self.market._settle(self.broker_name) except Exception as e: raise e # 基金 指数 期货 elif self.market_type in [MARKET_TYPE.FUND_CN, MARKET_TYPE.INDEX_CN, MARKET_TYPE.FUTURE_CN]: self.market._settle(self.broker_name) # print(data) self.broker.run( QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA, market_data=data)) # 生成 UPCOMING_DATA 事件放到 队列中去执行 self.market.upcoming_data(self.broker_name, data) self.market.trade_engine.join() _date = date
def next_tradeday(self): self.order_handler.run( QA_Event( event_type=BROKER_EVENT.NEXT_TRADEDAY, event_queue=self.trade_engine.kernels_dict['ORDER'].queue ) )
def query_data_no_wait( self, broker_name, frequence, market_type, code, start, end=None ): ''' 从broker获取数据 :param broker_name: :param frequence: :param market_type: :param code: :param start: :param end: :return: ''' return self.broker[broker_name].run( event=QA_Event( event_type=MARKET_EVENT.QUERY_DATA, frequence=frequence, market_type=market_type, code=code, start=start, end=end ) )
def query_order(self, broker_name, order_id): res = self.event_queue.put( QA_Task(worker=self.broker[broker_name], engine=broker_name, event=QA_Event(order_id=order_id))) return res
def _sync_position(self): self.order_handler.run( QA_Event(event_type=MARKET_EVENT.QUERY_POSITION, account_cookie=list(self.session.keys()), broker=[ self.broker[item.broker] for item in self.session.values() ]))
def make_deal(self, code, datetime, amount=100, towards=ORDER_DIRECTION.BUY, price=0, order_model=ORDER_MODEL.MARKET, amount_model=AMOUNT_MODEL.BY_AMOUNT): """ 这是一个一定会成交,并且立刻结转(及t+0)的交易入口 """ self.account.receive_deal(self.backtest_broker.receive_order(QA_Event(order=self.account.send_order( code=code, time=datetime, amount=amount, towards=towards, price=price, order_model=order_model, amount_model=amount_model )))) self.account.settle()
def query_currentbar(self, broker_name, market_type, code): return self.broker[broker_name].run( event=QA_Event(event_type=MARKET_EVENT.QUERY_DATA, frequence=FREQUENCE.CURRENT, market_type=market_type, code=code, start=self.running_time, end=None))
def _renew_account(self): for item in self.session.values(): self.event_queue.put( QA_Task( worker=item, event=QA_Event( event_type=ACCOUNT_EVENT.SETTLE)))
def _settle(self, broker_name, callback=False): # 向事件线程发送BROKER的SETTLE事件 # 向事件线程发送ACCOUNT的SETTLE事件 for item in self.session.values(): if item.broker is broker_name: self.event_queue.put( QA_Task(worker=item, engine=broker_name, event=QA_Event(event_type=ACCOUNT_EVENT.SETTLE))) self.event_queue.put( QA_Task(worker=self.broker[broker_name], engine=broker_name, event=QA_Event(event_type=BROKER_EVENT.SETTLE, broker=self.broker[broker_name], callback=callback))) print('===== SETTLED {} ====='.format(self.running_time))
def query_data_no_wait(self, broker_name, frequence, market_type, code, start, end=None): return self.broker[broker_name].run(event=QA_Event( event_type=MARKET_EVENT.QUERY_DATA, frequence=frequence, market_type=market_type, code=code, start=start, end=end ))
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 insert_order(self, account_id, amount, amount_model, time, code, price, order_model, towards, market_type, frequence, broker_name): flag = False if order_model in [ORDER_MODEL.CLOSE, ORDER_MODEL.NEXT_OPEN]: _price = self.query_data_no_wait(broker_name=broker_name, frequence=frequence, market_type=market_type, code=code, start=time) if _price is not None and len(_price) > 0: price = float(_price[0][4]) flag = True else: QA_util_log_info('MARKET WARING: SOMEING WRONG WITH ORDER \n ') QA_util_log_info( 'code {} date {} price {} order_model {} amount_model {}'. format(code, time, price, order_model, amount_model)) elif order_model is ORDER_MODEL.MARKET: _price = self.query_data_no_wait(broker_name=broker_name, frequence=frequence, market_type=market_type, code=code, start=time) if _price is not None and len(_price) > 0: price = float(_price[0][1]) flag = True else: QA_util_log_info('MARKET WARING: SOMEING WRONG WITH ORDER \n ') QA_util_log_info( 'code {} date {} price {} order_model {} amount_model {}'. format(code, time, price, order_model, amount_model)) elif order_model is ORDER_MODEL.LIMIT: # if price > self.last_query_data[0][2] or price < self.last_query_data[0][3]: flag = True if flag: order = self.get_account(account_id).send_order( amount=amount, amount_model=amount_model, time=time, code=code, price=price, order_model=order_model, towards=towards) self.event_queue.put( QA_Task( worker=self.broker[self.get_account(account_id).broker], engine=self.get_account(account_id).broker, event=QA_Event(event_type=BROKER_EVENT.RECEIVE_ORDER, order=order, callback=self.on_insert_order))) else: pass
def _sync_deals(self): self.order_handler.run( QA_Event( event_type=MARKET_EVENT.QUERY_DEAL, account_cookie=list(self.session.keys()), broker=[ self.broker[item.broker] for item in self.session.values() ], event_queue=self.trade_engine.kernels_dict['ORDER'].queue))
def _trade(self, event): "内部函数" self.event_queue.put( QA_Task(worker=self.broker[event.broker_name], engine=event.broker_name, event=QA_Event(event_type=BROKER_EVENT.TRADE, broker=self.broker[event.broker_name], broker_name=event.broker_name, callback=self.on_trade_event)))
def _sync_orders(self): # account_cookie=list(self.session.keys()), # broker=[self.broker[item.broker] # for item in self.session.values()], # 注意: 一定要给子线程的队列@@@!!! # 2018-08-08 yutiansut # 这个callback实现了子线程方法的自我驱动和异步任务 self.order_handler.run( QA_Event( event_type=MARKET_EVENT.QUERY_ORDER, event_queue=self.trade_engine.kernels_dict['ORDER'].queue))
def _settle(self, broker_name, callback=False): #strDbg = QA_util_random_with_topic("QA_Market._settle") #print(">-----------------------_settle----------------------------->", strDbg) # 向事件线程发送BROKER的SETTLE事件 # 向事件线程发送ACCOUNT的SETTLE事件 for item in self.session.values(): if item.broker is broker_name: self.event_queue.put( QA_Task(worker=item, engine=broker_name, event=QA_Event(event_type=ACCOUNT_EVENT.SETTLE))) self.event_queue.put( QA_Task(worker=self.broker[broker_name], engine=broker_name, event=QA_Event(event_type=BROKER_EVENT.SETTLE, broker=self.broker[broker_name], callback=callback))) print('===== SETTLED {} ====='.format(self.running_time))
def _sync_position(self): self.submit(QA_Task(worker=self.order_handler, engine='ORDER', event=QA_Event( event_type=MARKET_EVENT.QUERY_POSITION, account_cookie=list(self.session.keys()), broker=[ self.broker[item.broker] for item in self.session.values() ])), nowait=True)
def settle_order(self): """交易前置结算 1. 回测: 交易队列清空,待交易队列标记SETTLE 2. 账户每日结算 3. broker结算更新 """ if self.if_start_orderthreading: self.order_handler.run( QA_Event( event_type=BROKER_EVENT.SETTLE, event_queue=self.trade_engine.kernels_dict['ORDER'].queue))
def query_data(self, broker_name, frequence, market_type, code, start, end=None): self.event_queue.put( QA_Task( worker=self.broker[broker_name], engine=broker_name, event=QA_Event( event_type=MARKET_EVENT.QUERY_DATA, frequence=frequence, market_type=market_type, code=code, start=start, end=end, callback=self.on_query_data ) ))
def run(self, event): if event.event_type is BROKER_EVENT.RECEIVE_ORDER: self.order_handler.run(event) self.run(QA_Event(event_type=BROKER_EVENT.TRADE, broker=self)) elif event.event_type is BROKER_EVENT.TRADE: """实盘交易部分!!!!! ATTENTION 这里需要开一个子线程去查询是否成交 ATTENTION """ event = self.order_handler.run(event) event.message = 'trade' if event.callback: event.callback(event)
def upcoming_data(self, broker, data): # main thread' # if self.running_time is not None and self.running_time!= data.datetime[0]: # for item in self.broker.keys(): # self._settle(item) self.running_time = data.datetime[0] for item in self.session.values(): # session里面是已经注册的account self.event_queue.put( QA_Task(worker=item, event=QA_Event(event_type=ENGINE_EVENT.UPCOMING_DATA, market_data=data, broker_name=broker, send_order=self.insert_order)))
def settle_order(self): """交易前置结算 1. 回测: 交易队列清空,待交易队列标记SETTLE 2. 账户每日结算 3. broker结算更新 """ if self.if_start_orderthreading: # print('setttle_order') self.submit(QA_Task(worker=self.order_handler, engine='ORDER', event=QA_Event(event_type=BROKER_EVENT.SETTLE, event_queue=self.trade_engine. kernels_dict['ORDER'].queue)), nowait=True)
def run(self, event): if event.event_type is MARKET_EVENT.QUERY_DATA: # 查询数据部分 code = event.code frequence = event.frequence start = event.start end = start if event.end is None else event.end market_type = event.market_type try: res = self.broker_data.select_time( start, end).select_code(code).to_numpy() except: res = self.fetcher[(market_type, frequence)](code, start, end, frequence=frequence) if event.callback: event.callback(res) else: return res elif event.event_type is MARKET_EVENT.QUERY_ORDER: self.order_handler.run(event) elif event.event_type is ENGINE_EVENT.UPCOMING_DATA: new_marketdata_dict = event.market_data.dicts for item in new_marketdata_dict.keys(): if item not in self._quotation.keys(): self._quotation[item] = new_marketdata_dict[item] # if self.broker_data is None: # self.broker_data = event.market_data # else: # self.broker_data.append(event.market_data) # self.broker_data=event.market_data elif event.event_type is BROKER_EVENT.RECEIVE_ORDER: self.order_handler.run(event) self.run(QA_Event(event_type=BROKER_EVENT.TRADE, broker=self)) elif event.event_type is BROKER_EVENT.TRADE: event = self.order_handler.run(event) event.message = 'trade' if event.callback: event.callback(event) elif event.event_type is BROKER_EVENT.SETTLE: self.order_handler.run(event) if event.callback: event.callback('settle')