def QA_fetch_stock_day_adv( code, start='all', end=None, if_drop_index=False, # 🛠 todo collections 参数没有用到, 且数据库是固定的, 这个变量后期去掉 collections=DATABASE.stock_day): ''' :param code: 股票代码 :param start: 开始日期 :param end: 结束日期 :param if_drop_index: :param collections: 默认数据库 :return: 如果股票代码不存 或者开始结束日期不存在 在返回 None ,合法返回 QA_DataStruct_Stock_day 数据 ''' '获取股票日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] if start == 'all': start = '1990-01-01' end = str(datetime.date.today()) res = QA_fetch_stock_day(code, start, end, format='pd') if res is None: # 🛠 todo 报告是代码不合法,还是日期不合法 print("💢 Error QA_fetch_stock_day_adv parameter code=%s , start=%s, end=%s call QA_fetch_stock_day return None"%(code,start,end)) return None else: res_reset_index = res.set_index(['date', 'code'], drop=if_drop_index) # if res_reset_index is None: # print("💢 Error QA_fetch_stock_day_adv set index 'datetime, code' return None") # return None return QA_DataStruct_Stock_day(res_reset_index)
def QA_fetch_stock_day_adv(code, start='all', end=None, if_drop_index=False, collections=DATABASE.stock_day): ''' :param code: 股票代码 :param start: 开始日期 :param end: 结束日期 :param if_drop_index: :param collections: 默认数据库 :return: 如果股票代码不存 或者开始结束日期不存在 在返回 None ,合法返回 QA_DataStruct_Stock_day 数据 ''' '获取股票日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] if start == 'all': start = '1990-01-01' end = str(datetime.date.today()) res = QA_fetch_stock_day(code, start, end, format='pd') if res is None: print("code=%s , start=%s, end=%s QA_fetch_stock_day return None" % (code, start, end)) return None else: return QA_DataStruct_Stock_day( res.set_index(['date', 'code'], drop=if_drop_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 QA_fetch_stock_day_adv( code, start='all', end=None, if_drop_index=False, # 🛠 todo collections 参数没有用到, 且数据库是固定的, 这个变量后期去掉 collections=DATABASE.stock_day): ''' :param code: 股票代码 :param start: 开始日期 :param end: 结束日期 :param if_drop_index: :param collections: 默认数据库 :return: 如果股票代码不存 或者开始结束日期不存在 在返回 None ,合法返回 QA_DataStruct_Stock_day 数据 ''' '获取股票日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] if start == 'all': start = '1990-01-01' end = str(datetime.date.today()) res = QA_fetch_stock_day(code, start, end, format='pd') if res is None: # 🛠 todo 报告是代码不合法,还是日期不合法 print("💢 Error QA_fetch_stock_day_adv parameter code=%s , start=%s, end=%s call QA_fetch_stock_day return None"%(code,start,end)) return None else: res_reset_index = res.set_index(['date', 'code'], drop=if_drop_index) # if res_reset_index is None: # print("💢 Error QA_fetch_stock_day_adv set index 'datetime, code' return None") # return None return QA_DataStruct_Stock_day(res_reset_index);
def __init__(self): super().__init__() self.frequence = FREQUENCE.DAY self.market_type = MARKET_TYPE.STOCK_CN # self.stock_basics = QATs.get_stock_basics() # self.time_to_Market_300439 = self.stock_basics.loc['300439', 'timeToMarket'] # self.time_to_Market_300439 = QA.QA_util_date_int2str(self.time_to_Market_300439) # self.time_to_day = QA_util_datetime_to_strdate(QA.QA_util_date_today()) # print(self.time_to_Market_300439) # print(self.time_to_day) self.time_to_Market_300439 = '2015-04-22' self.time_to_day = '2018-05-01' self.df_from_Tdx = QA_fetch_stock_day('300439', self.time_to_Market_300439, self.time_to_day, 'pd') # print(self.df_from_Tdx) self.ma05 = QA_indicator_MA(self.df_from_Tdx, 5) self.ma10 = QA_indicator_MA(self.df_from_Tdx, 10) self.ma15 = QA_indicator_MA(self.df_from_Tdx, 15) self.ma20 = QA_indicator_MA(self.df_from_Tdx, 20)
def __get_stock_day_data(self, __bid): __data = QA_util_to_json_from_pandas(QA_fetch_stock_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 __get_data(__bid): '隔离掉引擎查询数据库的行为' __data = QA_util_to_json_from_pandas(QA_fetch_stock_day(str( __bid.code)[0:6], str(__bid.date)[0:10], str(__bid.date)[0:10], 'pd')) if len(__data) == 0: pass else: __data = __data[0] return __data
def _get_diffQA(self, code, days): 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_stock_day(code, start, end, format='pd') # todo 全自动运行时会报错。单独测试不会报错?? if len(df) !=len(df2): print("_get_diffQA : {} {} {} {}".format(start, end,df.head(), df2.head())) print('columns:\n {}\n{}'.format(df.columns, df2.columns)) print(df.equals(df2)) else: print('数据长度{}'.format(len(df))) self.assertTrue(len(df) == len(df2), "和QA返回的数据,长度不一致{}:{}".format(len(df), len(df2))) # 两种方式检测DataFrame数据一致性 obo = self.differOneByOne(df2, df) self.assertTrue(df.equals(df2), "和QA返回的数据不一致{}".format(obo)) return df
def get_data(self, code, start, end, if_fq): if if_fq: data = QA_util_to_json_from_pandas( QA_fetch_stock_day_adv(code, start, end).to_qfq().data) self.write({'result': data}) else: data = QA_util_to_json_from_pandas( QA_fetch_stock_day(code, start, end, format='pd')) self.write({'result': data})
def get(self): """ 采用了get_arguents来获取参数 默认参数: code-->000001 start-->2017-01-01 end-->today """ code = self.get_argument('code', default='000001') start = self.get_argument('start', default='2017-01-01') end = self.get_argument('end', default=str(datetime.date.today())) data = QA_util_to_json_from_pandas( QA_fetch_stock_day(code, start, end, format='pd')) self.write({'result': data})
def get(self): print(self.request.arguments) code = self.request.arguments.get('code', '000001') start = str(self.request.arguments.get('start', '2017-01-01')) end = str(self.request.arguments.get('end', '2017-12-31')) data = QA_fetch_stock_day(code[0].decode('utf-8'), start, end, format='json') print(start) print(data) self.write({'result': data, 'status': 200})
def test_getNumpy_diffQA(self): """和QA返回的数据对比一致性 """ code = '000001' days = 365 * 1.2 start = datetime.datetime.now() - datetime.timedelta(days) end = datetime.datetime.now() - datetime.timedelta(0) array1 = qm.getNumpy(code, start, end) self.assertTrue(len(array1) > 0, "返回数据数量应该大于0。") array2 = QA_fetch_stock_day(code, start, end) self.assertTrue(len(array1) == len(array2), "和QA返回的数据,长度不一致") # 两种方式检测numpy数据一致性 self.assertTrue(np.array_equal(array1, array2), "和QA返回的数据不一致{}".format("")) self.assertTrue((array1 == array2).all(), "和QA返回的数据不一致{}".format( np.setdiff1d(array1, array2, assume_unique=True)))
def QA_fetch_stock_day_adv(code, start='all', end=None, if_drop_index=False, collections=DATABASE.stock_day): '获取股票日线' end = start if end is None else end start = str(start)[0:10] end = str(end)[0:10] if start == 'all': start = '1990-01-01' end = str(datetime.date.today()) return QA_DataStruct_Stock_day( QA_fetch_stock_day(code, start, end, format='pd').set_index(['date', 'code'], drop=if_drop_index))
def __init__(self, user_cookie, portfolio_cookie, account_cookie, init_cash=100000, init_hold={}): super().__init__(user_cookie=user_cookie, portfolio_cookie=portfolio_cookie, account_cookie=account_cookie, init_cash=init_cash, init_hold=init_hold) self.frequence = FREQUENCE.DAY self.market_type = MARKET_TYPE.STOCK_CN self.commission_coeff = 0.0001 self.tax_coeff = 0.001 self.reset_assets(100000) # self.stock_basics = QATs.get_stock_basics() # self.time_to_Market_300439 = self.stock_basics.loc['300439', 'timeToMarket'] # self.time_to_Market_300439 = QA.QA_util_date_int2str(self.time_to_Market_300439) # self.time_to_day = QA_util_datetime_to_strdate(QA.QA_util_date_today()) # print(self.time_to_Market_300439) # print(self.time_to_day) self.time_to_Market_300439 = '2017-04-22' self.time_to_day = '2017-07-01' self.df_from_Tdx = QA_fetch_stock_day('300439', self.time_to_Market_300439, self.time_to_day, 'pd') # print(self.df_from_Tdx) self.ma05 = QA_indicator_MA(self.df_from_Tdx, 5) self.ma10 = QA_indicator_MA(self.df_from_Tdx, 10) self.ma15 = QA_indicator_MA(self.df_from_Tdx, 15) self.ma20 = QA_indicator_MA(self.df_from_Tdx, 20)
def _saving_work(self, code): def __QA_log_info(code, end_time, start_time): def loginfo(prefix='', astr='', listCounts=5): if len(self._loginfolist) < listCounts: self._loginfolist.append(astr) else: str = '' for i in range(len(self._loginfolist)): str += self._loginfolist[i] + ' ' str += astr QA_util_log_info(prefix.format(str), self.ui_log) self._loginfolist.clear() prefix = '##JOB02 Saving parallelism {}_DAY ==== Trying updating\n{}'.format( "xdxr", '{}') loginfo(prefix, ' {} from {} to {}'.format(code, start_time, end_time)) try: search_cond = {'code': str(code)[0:6]} _col = get_coll(client=None, cacheName="stock_xdxr", tableName="stock_xdxr") ref_ = _col.find(search_cond) ref_count = _col.count_documents(search_cond) end_time = str(now_time())[0:10] _xdxr = QA_fetch_get_stock_xdxr(str(code)) if ref_count > 0: start_time = ref_[ref_count - 1]['date'] __QA_log_info(code, end_time, start_time) if start_time != end_time: # 最后一次保存的数据之后的数据 xdxrdata = _xdxr[_xdxr['date'] > start_time] if len(xdxrdata) > 0: _col.insert_many(QA_util_to_json_from_pandas(xdxrdata), ordered=False) else: # 第一次保存数据 try: start_time = '1990-01-01' __QA_log_info(code, end_time, start_time) _col.insert_many(QA_util_to_json_from_pandas(_xdxr), ordered=False) except Exception as e: pass except Exception as e: QA_util_log_info(e.args, ui_log=self.ui_log) self.err.append(str(code)) QA_util_log_info(self.err, ui_log=self.ui_log) try: # 插入前复权数据 coll_adj = get_coll(client=None, cacheName="stock_adj", tableName="stock_adj") data = QA_fetch_stock_day(str(code), '1990-01-01', str(datetime.date.today()), 'pd') qfq = _QA_data_stock_to_fq(data, _xdxr, 'qfq') qfq = qfq.assign(date=qfq.date.apply(lambda x: str(x)[0:10])) adjdata = QA_util_to_json_from_pandas( qfq.loc[:, ['date', 'code', 'adj']]) # 如果没有新增幅圈数据,插入新增数据 ref_ = coll_adj.find(search_cond) ref_count = coll_adj.count_documents(search_cond) if ref_count > 0: # 历史保存过数据 lastref = ref_[ref_count - 1] del lastref['_id'] try: # 存在相同的数据,则保存最近数据 adjdata.index(lastref) # 找不到对应的数据,会出发异常 start_time = lastref['date'] adjdata2 = QA_util_to_json_from_pandas(qfq.loc[slice( pd.Timestamp(start_time), pd.Timestamp( end_time))].loc[:, ['date', 'code', 'adj']][1:]) if (ref_count + len(adjdata2)) == len(adjdata): # if len(adjdata2) > 0: coll_adj.insert_many(adjdata2) else: raise Exception("数据总量不匹配,重新存储") except Exception as e: # 分红数据有变化,删除以前保存的数据,重新保存新的数据 coll_adj.delete_many({'code': code}) coll_adj.insert_many(adjdata) else: # 第一次保存前复权数据 # print(adjdata) coll_adj.insert_many(adjdata) except Exception as e: print(e)
def get(self): code = self.get_argument('code', default='000001') start_date = self.get_argument('start_date', default='2018-01-01') end_date = self.get_argument('end_date', default='2018-12-31') start_year = self.get_argument('start_year', default='2017') stock_prices = QA_fetch_stock_day(code, start_date, end_date, format='pandas') financial_reports = QA_fetch_financial_report([code], report_dates( int(start_year))) # PE= 股价/每股收益 # PB= 股价/每股净资产 # PEG=PE/(企业年盈利增长率*100) price_pd = pd.DataFrame({ 'code': stock_prices.code, 'date': stock_prices.date, 'close': stock_prices.close }) reports_pd = pd.DataFrame({ 'code': financial_reports.code, 'report_date': financial_reports.report_date, 'EPS': financial_reports.EPS, 'netAssetsPerShare': financial_reports.netAssetsPerShare, 'netProfitGrowthRate': financial_reports.netProfitGrowthRate }) reports_pd['report_date_str'] = reports_pd['report_date'].apply( format_ts_date) eps_sum = reports_pd.loc[reports_pd["report_date_str"] == "2017-12-31"].EPS.sum() aps_sum = reports_pd.loc[reports_pd["report_date_str"] == "2017-12-31"].netAssetsPerShare.sum() pgr_sum = reports_pd.loc[reports_pd["report_date_str"] == "2017-12-31"].netProfitGrowthRate.sum() price_pd['date_str'] = price_pd['date'].apply( lambda x: x.strftime("%Y-%m-%d")) price_pd['eps_sum'] = price_pd['close'].apply( lambda x: round(eps_sum, 2)) price_pd['aps_sum'] = price_pd['close'].apply( lambda x: round(aps_sum, 2)) price_pd['pgr_sum'] = price_pd['close'].apply( lambda x: round(pgr_sum, 2)) price_pd['pe'] = price_pd['close'].apply( lambda x: round(x / eps_sum, 2)) price_pd['pb'] = price_pd['close'].apply( lambda x: round(x / aps_sum, 2)) price_pd['peg'] = price_pd['pe'].apply(lambda x: round(x / pgr_sum, 2)) return self.write({ 'stock_prices': QA_util_to_json_from_pandas(price_pd), 'financial_reports': QA_util_to_json_from_pandas(reports_pd) })