def get_kline_data(self): kline_data = GetKlineData() all_stock_data = kline_data.cache_all_stock_data() self.kline = kline_data.get_market_data(all_stock_data, stock_code=self.stock_list, field=['close']) return self.kline
def get_benchmark_net_asset_value(self, period, benchmark): data_class = GetKlineData() benchmark_close = None if period == Period.DAILY.value: start_time = Environment.benchmark_index[0] end_time = Environment.benchmark_index[-1] benchmark_close = data_class.get_market_data( Environment.index_daily_data, stock_code=[benchmark], field=['close'], start=start_time, end=end_time) elif period == Period.ONE_MIN.value: start_time = millisecond_to_date( millisecond=Environment.benchmark_index[0], format='%Y-%m-%d %H:%M:%S') end_time = millisecond_to_date( millisecond=Environment.benchmark_index[-1], format='%Y-%m-%d %H:%M:%S') benchmark_close = data_class.get_market_data( Environment.index_daily_data, stock_code=[benchmark], field=['close'], start=start_time, end=end_time) benchmark_close = list(benchmark_close) benchmark_net_asset_value = [ current_close / benchmark_close[0] for current_close in benchmark_close ] return benchmark_net_asset_value
def show_backtesting_indicator(cls, event): benchmark = event.event_data_dict['strategy_data'].benchmark account = event.event_data_dict['strategy_data'].account data_class = GetKlineData() start_time = Environment.benchmark_index[0] end_time = Environment.benchmark_index[-1] account_df = Environment.backtesting_record_account benchmark_df = data_class.get_market_data(Environment.index_daily_data, stock_code=[benchmark], field=['close'], ).to_frame(name='close') account_df = account_df[account_df.index.get_level_values(1) == account[0]] account_df.reset_index(level='account_id', drop=True, inplace=True) net_value_analysis_obj = NetValueAnalysis(account_df, benchmark_df, start_time, end_time) net_analysis_result = net_value_analysis_obj.cal_net_analysis_result() for i in net_analysis_result: Environment.logger.info(i, net_analysis_result[i]) # 持仓数据转pandas position_data_df = Environment.backtesting_record_position position_data_df = position_data_df[position_data_df.index.get_level_values(1) == account[0]] position_analysis_obj = PositionAnalysis(position_data_df) position_analysis_result = position_analysis_obj.cal_position_analysis_result() for i in position_analysis_result: Environment.logger.info(i, position_analysis_result[i])
def update_a_share_capitalization(self): """ 保存 总股本,总市值, 流通股本,流通市值 四个hdf5 :return: """ with MongoConnect(self.database): a_share_capitalization = AShareCapitalization.objects().as_pymongo() field_list = ['security_code', 'change_date', 'total_share', 'float_share', 'float_a_share', 'float_b_share', 'float_h_share'] self.a_share_capitalization = pd.DataFrame(list(a_share_capitalization)).reindex(columns=field_list) kline_object = GetKlineData() market_close_data = kline_object.cache_all_stock_data()['close'] index = list(set(market_close_data.index).union(set(self.a_share_capitalization['change_date']))) share_capitalization_grouped = self.a_share_capitalization.groupby('security_code') share_capitalization = pd.DataFrame(index=index) for i in share_capitalization_grouped: data = i[1].reindex(['change_date', 'total_share'], axis=1).sort_values('change_date').set_index( 'change_date') try: share_capitalization[i[0]] = data except ValueError: # 有四只票 change date 重复,需要手工清洗修正 # print(data) share_capitalization[i[0]] = data[data.index.duplicated()] share_capitalization = share_capitalization.fillna(method='ffill').reindex(market_close_data.index) return share_capitalization.multiply(10000) * market_close_data
def save_a_share_adj_factor_right(self): """ 取当日收盘价,作为转、送的股价, 再计算复权因子更新到AShareExRightDividend, 复权因子adj_factor 比例 = 送股比例 + 转增比例 + 缩减比例 单次复权因子 = 股权登记日收盘价 * (1 + 比例 + 配股比例 + 增发比例) / (股权登记日收盘价 - 派息比例 + 股权登记日收盘价 * 比例 + 配股价格 * 配股比例 + 增发价格 * 增发比例) :return: """ kline_object = GetKlineData() all_market_data = kline_object.cache_all_stock_data() with MongoConnect(self.database): self.data = pd.DataFrame( AShareExRightDividend.objects.as_pymongo()) self.data['close'] = self.data.apply( lambda x: self.get_adj_day_close(x['security_code'], x[ 'ex_date'], all_market_data), axis=1) self.data = self.data.fillna(0) ratio = self.data['bonus_share_ratio'] + self.data[ 'conversed_ratio'] + self.data['consolidate_split_ratio'] self.data['adj_factor'] = self.data['close'] * ( 1 + ratio + self.data['rightsissue_ratio'] + self.data['seo_ratio'] ) / (self.data['close'] - self.data['cash_dividend_ratio'] + self.data['close'] * ratio + self.data['rightsissue_price'] * self.data['rightsissue_ratio'] + self.data['seo_price'] * self.data['seo_ratio']) folder_name = LocalDataFolderName.ADJ_FACTOR.value path = LocalDataPath.path + folder_name + '/' self.data = self.data.reindex( columns=['security_code', 'ex_date', 'adj_factor']) self.data.set_index(["ex_date"], inplace=True) self.data.sort_index(inplace=True) calendar_obj = GetCalendar() calendar = calendar_obj.get_calendar('SZ') backward_factor = pd.DataFrame(index=calendar) adj_factor = pd.DataFrame(index=calendar) data_dict = dict( list(self.data.groupby(self.data['security_code']))) for security_code, adj_data in data_dict.items(): backward_factor[security_code] = self.cal_backward_factor( adj_data['adj_factor']) adj_factor[security_code] = adj_data['adj_factor'] backward_factor.replace([np.inf, 0], np.nan, inplace=True) backward_factor.fillna(method='ffill', inplace=True) backward_factor.fillna(1, inplace=True) backward_factor = backward_factor.reindex( columns=all_market_data['close'].columns, fill_value=1) save_data_to_hdf5(path, AdjustmentFactor.BACKWARD_ADJ_FACTOR.value, backward_factor) save_data_to_hdf5(path, AdjustmentFactor.FROWARD_ADJ_FACTOR.value, backward_factor.div(backward_factor.iloc[-1]))
def update_a_share_capitalization(self): """ 保存 总股本,总市值, 流通股本,流通市值 四个hdf5 :return: """ with MongoConnect(self.database): a_share_capitalization = AShareCapitalization.objects().as_pymongo( ) field_list = [ 'security_code', 'change_date', 'total_share', 'float_share', 'float_a_share', 'float_b_share', 'float_h_share' ] self.a_share_capitalization = pd.DataFrame( list(a_share_capitalization)).reindex(columns=field_list) kline_object = GetKlineData() market_close_data = kline_object.cache_all_stock_data()['close'] index = list( set(market_close_data.index).union( set(self.a_share_capitalization['change_date']))) index.sort() share_capitalization_grouped = self.a_share_capitalization.groupby( 'security_code') total_share = pd.DataFrame({}) float_a_share = pd.DataFrame({}) for i in share_capitalization_grouped: data = i[1].sort_values('change_date').set_index('change_date') try: total_share[i[0]] = data['total_share'].reindex(index) float_a_share[i[0]] = data['float_a_share'].reindex(index) except ValueError: # 有四只票 change date 重复,需要手工清洗修正 # print(data[data.index.duplicated()]) total_share[i[0]] = data[ data.index.duplicated()]['total_share'].reindex(index) float_a_share[i[0]] = data[data.index.duplicated( )]['float_a_share'].reindex(index) total_share = total_share.fillna(method='ffill').reindex( market_close_data.index) float_a_share = float_a_share.fillna(method='ffill').reindex( market_close_data.index) total_share_value = total_share.multiply(10000) * market_close_data float_a_share_value = float_a_share.multiply( 10000) * market_close_data folder_name = LocalDataFolderName.INDICATOR_EVERYDAY.value path = LocalDataPath.path + folder_name + '/' save_data_to_hdf5(path, 'total_share', total_share) save_data_to_hdf5(path, 'float_a_share', float_a_share) save_data_to_hdf5(path, 'total_share_value', total_share_value) save_data_to_hdf5(path, 'float_a_share_value', float_a_share_value)
def update_market_data(cls, event): current_date = event.event_data_dict["strategy_data"].time_tag data_class = GetKlineData() stock_code_list = [] for position_data in Environment.bar_position_data_list: stock_code_list.append(position_data.instrument + "." + position_data.exchange) stock_code_list = list(set(stock_code_list)) cls.current_close_price_all = data_class.get_market_data( Environment.daily_data, stock_code=stock_code_list, field=["close"], start=current_date, end=current_date)
def __init__(self): self._run_mode = RunMode.BACKTESTING.value self._account = [] self._capital = 1000000 self._start = datetime(2017, 1, 1) self._end = datetime(2018, 1, 1) self._benchmark = '000300.SH' self._period = Period.DAILY.value # 后续支持1min 3min 5min 等多周期 self._universe = [] self._rights_adjustment = RightsAdjustment.FROWARD.value self._time_tag = 0 # 数据缓存开关 self._daily_data_cache = False self._one_min_data_cache = False # 取数据 self._get_data = GetKlineData() self.bar_index = 0
def __init__(self, factor, factor_name): self.factor = factor self.factor_name = factor_name market_data = GetKlineData() \ .cache_all_stock_data(dividend_type=RightsAdjustment.BACKWARD.value, field=['close'])['close'] \ .reindex(factor.index) \ .reindex(factor.columns, axis=1) self.ic_decay = 20 column_list = [factor_name + '_' + str(i + 1) for i in range(self.ic_decay)] self.stock_return_dict = {i + 1: market_data.pct_change(periods=i + 1) for i in range(self.ic_decay)} # IC信号衰减计算,index 是时间序列, columns是decay周期,[1, self.ic_decay], 闭区间 self.ic_df = pd.DataFrame(columns=column_list) self.p_value_df = pd.DataFrame(columns=column_list) # IC均值、 IC标准差、 IC_IR比率、 IC > 0 占比、 | IC | > 0.02 占比(绝对值)、 偏度、 峰度 index_list = ['ic_mean', 'ic_std', 'ic_ir', 'ic_ratio', 'ic_abs_ratio', 'ic_skewness', 'ic_kurtosis'] self.ic_result = pd.DataFrame(index=index_list, columns=column_list)
factor_t_value=factor_t_value, # 单因子检测的T值的统计值,'t_value_mean': 绝对值均值, 't_value_greater_two':绝对值序列大于2的占比 factor_t_value_statistics=self.factor_t_value_statistics, # 净值分析结果 net_analysis_result=self.net_analysis_result) doc.save() if __name__ == '__main__': factor_name = 'factor_ma10' path = LocalDataPath.path + LocalDataFolderName.FACTOR.value + '/' factor_ma5 = get_local_data(path, factor_name + '.h5') # 指数数据不全,需要删一部分因子数据 factor_ma5 = factor_ma5[factor_ma5.index < datetime.datetime(2020, 1, 1)] kline_object = GetKlineData() market_data = kline_object.cache_all_stock_data( dividend_type=RightsAdjustment.BACKWARD.value, field=['close']) market_close_data = kline_object.get_market_data(market_data, field=['close']) # 指数行情,沪深300代替 all_index_data = kline_object.cache_all_index_data() benchmark_df = kline_object.get_market_data( all_index_data, stock_code=['000300.SH'], field=['close']).to_frame(name='close') # 沪深300 的日线,有脏数据,后续单独处理 if datetime.datetime(2016, 1, 1) in benchmark_df.index: benchmark_df = benchmark_df.drop(datetime.datetime(2016, 1, 1)) regression_analysis_obj = RegressionAnalysis(factor_ma5, 'factor_ma5', market_close_data,
ic_df = self.ic_df.copy() p_value_df = self.p_value_df.copy() ic_df.index = ic_df.index.format() p_value_df.index = p_value_df.index.format() doc = FactorIcAnalysisResult( factor_name=factor_name, # 因子数据开始时间 begin_date=self.factor.index[0], # 因子数据结束时间 end_date=self.factor.index[-1], # IC信号衰减计算,index 是时间序列, columns是decay周期,[1, self.ic_decay], 闭区间 ic=ic_df, # p值信号衰减计算,index 是时间序列, columns是decay周期,[1, self.ic_decay], 闭区间 p_value=p_value_df, ic_result=self.ic_result) doc.save() if __name__ == '__main__': path = LocalDataPath.path + LocalDataFolderName.FACTOR.value + '/' factor_name = 'factor_ma10' factor_ma5 = get_local_data(path, factor_name + '.h5') market_close_data = GetKlineData().cache_all_stock_data( dividend_type=RightsAdjustment.BACKWARD.value, field=['close'])['close'] ic_analysis_obj = IcAnalysis(factor_ma5, factor_name, market_close_data) ic_analysis_obj.cal_ic_df(method='spearmanr') ic_analysis_obj.cal_ic_indicator() ic_analysis_obj.save_ic_analysis_result(factor_name)