def QA_fetch_index_day_adv( code, start, end=None, if_drop_index=True, # 🛠 todo collections 参数没有用到, 且数据库是固定的, 这个变量后期去掉 collections=DATABASE.index_day): ''' :param code: code: 字符串str eg 600085 :param start: 字符串str 开始日期 eg 2011-01-01 :param end: 字符串str 结束日期 eg 2011-05-01 :param if_drop_index: Ture False , dataframe drop index or not :param collections: mongodb 数据库 :return: ''' '获取指数日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] # 🛠 todo 报告错误 如果开始时间 在 结束时间之后 # 🛠 todo 如果相等 res = QA_fetch_index_day(code, start, end, format='pd') if res is None: print("QA Error QA_fetch_index_day_adv parameter code=%s start=%s end=%s call QA_fetch_index_day return None" % ( code, start, end)) return None else: res_set_index = res.set_index(['date', 'code'], drop=if_drop_index) # if res_set_index is None: # print("QA Error QA_fetch_index_day_adv set index 'date, code' return None") # return None return QA_DataStruct_Index_day(res_set_index)
def QA_fetch_index_day_adv( code, start, end=None, if_drop_index=True, # 🛠 todo collections 参数没有用到, 且数据库是固定的, 这个变量后期去掉 collections=DATABASE.index_day): ''' :param code: code: 字符串str eg 600085 :param start: 字符串str 开始日期 eg 2011-01-01 :param end: 字符串str 结束日期 eg 2011-05-01 :param if_drop_index: Ture False , dataframe drop index or not :param collections: mongodb 数据库 :return: ''' '获取指数日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] # 🛠 todo 报告错误 如果开始时间 在 结束时间之后 # 🛠 todo 如果相等 res = QA_fetch_index_day(code, start, end, format='pd') if res is None: print( "QA Error QA_fetch_index_day_adv parameter code=%s start=%s end=%s call QA_fetch_index_day return None" % (code, start, end)) else: res_set_index = res.set_index(['date', 'code']) # if res_set_index is None: # print("QA Error QA_fetch_index_day_adv set index 'date, code' return None") # return None return QA_DataStruct_Index_day(res_set_index)
def _get_diffQA(self, code, end, start, typ='stock'): # qm = self._qm if typ == 'stock': qm = F().createFetcher('stock') else: qm = F().createFetcher('index') df = qm.get(code, start, end, frequence='day') self.assertTrue(len(df) > 0, "返回数据数量应该大于0。") if typ == 'stock': df2 = QA_fetch_stock_day(code, start, end, format='pd') else: df2 = QA_fetch_index_day(code, start, end, format='pd') # self.assertTrue((df.columns.values == df2.columns.values).all(), "df.columns:{}".format(df.columns)) if len(df) != len(df2): # show df df2 print("Fetcher index: {}\n {}".format(type(qm), qm.collectionsDay)) print("{}:{}\n{} {}\n df{} df2{}".format(len(df), len(df2), start, end, df.tail(10), df2.tail(10))) self.assertTrue(np.array_equal(df, df2), "df.columns:{}".format(df.columns)) self.assertTrue( len(df) == len(df2), "和QA返回的数据,长度不一致{}:{}\n{} {}\n df{} df2{}".format( len(df), len(df2), start, end, df.tail(10), df2.tail(10))) # 两种方式检测DataFrame数据一致性 obo = self.differOneByOne(df, df2) self.assertTrue(df.equals(df2), "和QA返回的数据不一致{}".format(obo))
def test_get_diffQA(self): """和QA返回的数据对比一致性 """ code = '000001' days = 365 * 1.2 start = (datetime.datetime.now() - datetime.timedelta(days)).date() end = datetime.datetime.now() - datetime.timedelta(0) df = qm.get(code, start, end) self.assertTrue(len(df) > 0, "返回数据数量应该大于0。") df2 = QA_fetch_index_day(code, start, end, format='pd') self.assertTrue( len(df) == len(df2), "和QA返回的数据,长度不一致{}:{}".format(len(df), len(df2))) # 两种方式检测DataFrame数据一致性 obo = self.differOneByOne(df, df2) # # df df2之间的区别 # df2 = df2.loc[:, # [ # 'code', # 'open', # 'high', # 'low', # 'close', # 'volume', # 'amount', # 'date' # ]] self.assertTrue(df.equals(df2), "和QA返回的数据不一致{}".format(obo))
def __get_index_day_data(self, __bid): __data = QA_util_to_json_from_pandas(QA_fetch_index_day(str( __bid.code)[0:6], str(__bid.datetime)[0:10], str(__bid.datetime)[0:10], 'pd')) if len(__data) == 0: pass else: __data = __data[0] return __data
def QA_fetch_index_day_adv(code, start, end=None, if_drop_index=False, collections=DATABASE.index_day): '获取指数日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] return QA_DataStruct_Index_day( QA_fetch_index_day(code, start, end, format='pd').set_index(['date', 'code'], drop=if_drop_index))
def __end_of_backtest(self, *arg, **kwargs): # 开始分析 QA_util_log_info('start analysis====\n' + str(self.strategy_stock_list)) QA_util_log_info('=' * 10 + 'Trade History' + '=' * 10) QA_util_log_info('\n' + tabulate(self.account.history, headers=('date', 'code', 'price', 'towards', 'amounts', 'order_id', 'trade_id', 'commission'))) QA_util_log_info('\n' + tabulate(self.account.detail, headers=('date', 'code', 'price', 'amounts', 'order_id', 'trade_id', 'sell_price', 'sell_order_id', 'sell_trade_id', 'sell_date', 'left_amount', 'commission'))) __exist_time = int(self.end_real_id) - int(self.start_real_id) + 1 self.__benchmark_data = QA_fetch_index_day( self.benchmark_code, self.start_real_date, self.end_real_date) if len(self.__messages) > 1: performace = QA_backtest_analysis_start( self.setting.client, self.strategy_stock_list, self.__messages, self.trade_list[self.start_real_id:self.end_real_id + 1], self.market_data, self.__benchmark_data) _backtest_mes = { 'user': self.setting.QA_setting_user_name, 'strategy': self.strategy_name, 'stock_list': performace['code'], 'start_time': self.strategy_start_date, 'end_time': self.strategy_end_date, 'account_cookie': self.account.account_cookie, 'annualized_returns': performace['annualized_returns'], 'benchmark_annualized_returns': performace['benchmark_annualized_returns'], 'assets': performace['assets'], 'benchmark_assets': performace['benchmark_assets'], 'trade_date': performace['trade_date'], 'total_date': performace['total_date'], 'win_rate': performace['win_rate'], 'alpha': performace['alpha'], 'beta': performace['beta'], 'sharpe': performace['sharpe'], 'vol': performace['vol'], 'benchmark_vol': performace['benchmark_vol'], 'max_drop': performace['max_drop'], 'exist': __exist_time, 'time': datetime.datetime.now() } QA_SU_save_backtest_message(_backtest_mes, self.setting.client) QA_SU_save_account_message(self.__messages, self.setting.client) QA_SU_save_account_to_csv(self.__messages)
def __QA_backest_handle_data(self, outside_handle): '这个outside_handle就是一个外部的注入函数' # 首先判断是否能满足回测的要求` _info = {} _info['stock_list'] = self.strategy_stock_list __messages = {} self.__init_cash_per_stock = int( float(self.account.init_assest) / len(self.strategy_stock_list)) # 策略的交易日循环 for i in range(int(self.start_real_id), int(self.end_real_id) - 1, 1): # 正在进行的交易日期 __running_date = self.trade_list[i] QA_util_log_info( '=================daily hold list====================') QA_util_log_info('in the begining of ' + __running_date) QA_util_log_info( tabulate(self.account.message['body']['account']['hold'])) for __j in range(0, len(self.strategy_stock_list)): if __running_date in [l[6] for l in self.market_data[__j]] and \ [l[6] for l in self.market_data[__j]].index(__running_date) \ > self.strategy_gap + 1: __data = self.__QA_data_handle([ __l[6] for __l in self.market_data[__j] ].index(__running_date), __j) __amount = 0 for item in __data['account']['body']['account']['hold']: if self.strategy_stock_list[__j] in item: __amount = __amount + item[3] if __amount > 0: __hold = 1 else: __hold = 0 __result = outside_handle.predict(__data['market'], __data['account'], __hold, _info) if float(self.account.message['body']['account']['cash'] [-1]) > 0: self.__QA_backtest_excute_bid( __result, __running_date, __hold, str(self.strategy_stock_list[__j])[0:6], __amount) else: QA_util_log_info('not enough free money') else: pass # 在回测的最后一天,平掉所有仓位(回测的最后一天是不买入的) while len(self.account.hold) > 1: __hold_list = self.account.hold[1::] pre_del_id = [] for item_ in range(0, len(__hold_list)): if __hold_list[item_][3] > 0: __last_bid = self.bid.bid __last_bid['amount'] = int(__hold_list[item_][3]) __last_bid['order_id'] = str(random.random()) __last_bid['price'] = 'close_price' __last_bid['code'] = str(__hold_list[item_][1]) __last_bid['date'] = self.trade_list[self.end_real_id] __last_bid['towards'] = -1 __last_bid['user'] = self.setting.QA_setting_user_name __last_bid['strategy'] = self.strategy_name __last_bid['bid_model'] = 'auto' __last_bid['status'] = '0x01' __last_bid['amount_model'] = 'amount' __message = self.market.receive_bid( __last_bid, self.setting.client) _remains_day = 0 while __message['header']['status'] == 500: # 停牌状态,这个时候按停牌的最后一天计算价值(假设平仓) __last_bid['date'] = self.trade_list[self.end_real_id - _remains_day] _remains_day += 1 __message = self.market.receive_bid( __last_bid, self.setting.client) # 直到市场不是为0状态位置,停止前推日期 __messages = self.account.QA_account_receive_deal( __message) else: pre_del_id.append(item_) pre_del_id.sort() pre_del_id.reverse() for item_x in pre_del_id: __hold_list.pop(item_x) try: # 在末尾增加一个回调给策略 outside_handle.on_end(__data['market'], __data['account'], __hold, _info) except: pass # 开始分析 QA_util_log_info('start analysis====\n' + str(self.strategy_stock_list)) QA_util_log_info('=' * 10 + 'Trade History' + '=' * 10) QA_util_log_info('\n' + tabulate(self.account.history, headers=('date', 'code', 'price', 'towards', 'amounts', 'order_id', 'trade_id', 'commission'))) QA_util_log_info( tabulate(self.account.detail, headers=('date', 'code', 'price', 'amounts', 'order_id', 'trade_id', 'sell_price', 'sell_order_id', 'sell_trade_id', 'sell_date', 'left_amount', 'commission'))) __exist_time = int(self.end_real_id) - int(self.start_real_id) + 1 self.__benchmark_data = QA_fetch_index_day(self.benchmark_code, self.start_real_date, self.end_real_date) performace = QA_backtest_analysis_start( self.setting.client, self.strategy_stock_list, __messages, self.trade_list[self.start_real_id:self.end_real_id + 1], self.market_data, self.__benchmark_data) _backtest_mes = { 'user': self.setting.QA_setting_user_name, 'strategy': self.strategy_name, 'stock_list': performace['code'], 'start_time': self.strategy_start_date, 'end_time': self.strategy_end_date, 'account_cookie': self.account.account_cookie, 'annualized_returns': performace['annualized_returns'], 'benchmark_annualized_returns': performace['benchmark_annualized_returns'], 'assets': performace['assets'], 'benchmark_assets': performace['benchmark_assets'], 'trade_date': performace['trade_date'], 'total_date': performace['total_date'], 'win_rate': performace['win_rate'], 'alpha': performace['alpha'], 'beta': performace['beta'], 'sharpe': performace['sharpe'], 'vol': performace['vol'], 'benchmark_vol': performace['benchmark_vol'], 'max_drop': performace['max_drop'], 'exist': __exist_time, 'time': datetime.datetime.now() } QA_SU_save_backtest_message(_backtest_mes, self.setting.client) QA_SU_save_account_message(__messages, self.setting.client) QA_SU_save_account_to_csv(__messages)