def __init__(self): self.cu_wind = sql_oracle.cu self.cu_pra = sql_oracle.cu_pra_sel self.time_tool = Time_tool() self.init_funcs() self.market = pd.DataFrame() self.gen_market()
def __init__(self): self.cu = sql_oracle.cu self.cu_pra = sql_oracle.cu_pra_sel self.t = Time_tool() self.init_table() self.init_funcs() self.year_x = 52
class SeasonLabel(object): def __init__(self): self.cu_wind = sql_oracle.cu self.cu_pra = sql_oracle.cu_pra_sel self.time_tool = Time_tool() self.init_funcs() self.market = pd.DataFrame() self.gen_market() def init_funcs(self): '''初始化各种外挂方法''' classes = [LeverageRatio, StandardDeviation, MaxDrawDown, IntervalProfit, AlphaCategroy, SharpRation, DownStd] for class_ in classes: class_(self).add_func() def gen_time_list(self, start_date, end_date, s_type='daily', pre_flag=True): '''生成交易日序列 s_type: daily, 日频; weekly, 周频 pre_flag: True, 需要计算收益率的标签在取样时需要往前多取一个交易日 attention: 算法不需要用前一交易日信息,但需要用前一日净值信息来替代, ''' t_list = [] if s_type == 'daily': t_df = self.time_tool.get_trade_days(start_date, end_date) t_list = list(t_df.iloc[:, 0]) if pre_flag == True: pre_day = self.time_tool.get_pre_trade_day(start_date) t_list.insert(0, pre_day) if s_type == 'weekly': t_df = self.time_tool.get_week_trade_days(start_date, end_date) t_list = list(t_df.iloc[:, 0]) if pre_flag == True: pre_day = self.time_tool.get_pre_week_trade_day(start_date) t_list.insert(0, pre_day) return t_list def get_fund_price(self, code, start_date='', end_date='', time_list=[]): '''计算波动和回测时用到的sql查询方法''' if time_list: start_date = time_list[0] end_date = time_list[-1] sql = ''' select f13_1101 as 截止日期, f21_1101 as 复权单位净值 from wind.tb_object_1101 left join wind.tb_object_1090 on f2_1090 = f14_1101 where F16_1090= '%(code)s' and F13_1101 >= '%(start_date)s' and f13_1101 <= '%(end_date)s' order by f13_1101 ''' % {'end_date': end_date, 'code': code, 'start_date': start_date} fund_price = pd.DataFrame(self.cu_wind.execute(sql).fetchall(), columns=['日期', '复权单位净值']) fund_price.set_index('日期', inplace=True) if fund_price.empty: raise Exception('lact of fund value') if time_list: # 基金净值数据是按照周频发布 # 基金成立在时间段中间,导致获取净值数据不足 # if len(time_list) - fund_price.shape[0] > len(time_list) * 0.1: time_list_dt = pd.DataFrame(time_list, columns=['日期']) fund_price = pd.merge(time_list_dt, fund_price, on=['日期'], how='outer') if fund_price.shape[0] / len(time_list) < 0.9: raise Exception('lack of data, timelist>>fund_price.shape[0]') fund_price.fillna(method='ffill', inplace=True) fund_price = pd.merge(time_list_dt, fund_price, on=['日期'], how='left') fund_price.set_index(['日期'], inplace=True) # fund_price = fund_price.reindex(time_list) return fund_price def get_fund_price_biwi(self, code, start_date='', end_date='', time_list=[]): '''获取基金基准 ''' if time_list: t1, t2 = time_list[0], time_list[-1] else: t1, t2 = start_date, end_date sql_code = code + 'BI.WI' sql_week_close_bibw = f""" select trade_dt,s_dq_close from wind.chinamutualfundbenchmarkeod where s_info_windcode = '{sql_code}' and (trade_dt >= '{t1}' and trade_dt <='{t2}') order by trade_dt """ sql_res = self.cu_wind.execute(sql_week_close_bibw).fetchall() assert sql_res, f'{code}基准查询结果为空,请改变基准' df = pd.DataFrame(sql_res, columns=['日期', '收盘价']) if df.empty: raise Exception('基金基准查询结果为空') if df.shape[0] < len(time_list) * 0.9: raise Exception('基准数据不足') time_list_dt = pd.DataFrame(time_list, columns=['日期']) df = pd.merge(time_list_dt, df, on=['日期'], how='outer') df.fillna(method='ffill', inplace=True) df = pd.merge(time_list_dt, df, on=['日期'], how='left') df.set_index(['日期'], inplace=True) return df def get_ejfl_type(self, code, start_date, end_date): '''获取区间内第一个匹配的二级分类类型''' end_date = end_date[0: 4] + '1231' sql_string = f''' select * from ( select ejfl from t_fund_classify_his where rptdate <= {end_date} and cpdm = {code} order by rptdate ) where rownum=1 ''' ejfl_type = self.cu_pra.execute(sql_string).fetchall() if ejfl_type: rst = ejfl_type[0][0] else: rst = None return rst def get_market(self, fund_type, time_list): """获取同类基准 """ if self.market.empty: self.gen_market() time_list_dt = pd.DataFrame(time_list, columns=['日期']) market_tmp = pd.merge(time_list_dt, self.market, on=['日期'], how='outer') market_tmp.fillna(method='ffill', inplace=True) market_tmp = pd.merge(time_list_dt, market_tmp, on=['日期'], how='left') market_all = pd.DataFrame() for i in ['中证800','中证国债','恒生指数','中证综合债','中证短债','中证可转债','MSCI']: market_all[str(i)+'收益率'] = market_tmp[str(i)].pct_change() if fund_type =='股票型': market_type = market_all['中证800收益率'] elif fund_type == '激进配置型': market_type = market_all['中证800收益率']*0.8+market_all['中证国债收益率']*0.2 elif fund_type =='标准配置型': market_type = market_all['中证800收益率']*0.6+market_all['中证国债收益率']*0.4 elif fund_type == '保守配置型': market_type = market_all['中证800收益率'] * 0.2 + market_all['中证国债收益率'] * 0.8 elif fund_type == '灵活配置型': market_type = market_all['中证800收益率'] * 0.5 + market_all['中证国债收益率'] * 0.5 elif fund_type == '沪港深股票型': market_type = market_all['中证800收益率'] * 0.45 + market_all['中证国债收益率'] * 0.1+market_all['恒生指数收益率']*0.45 elif fund_type == '沪港深配置型': market_type = market_all['中证800收益率'] * 0.35 + market_all['中证国债收益率'] * 0.3 + market_all['恒生指数收益率'] * 0.35 elif fund_type =='纯债型': market_type = market_all['中证综合债收益率'] elif fund_type == '普通债券型': market_type = market_all['中证综合债收益率']*0.9+market_all['中证800收益率'] * 0.1 elif fund_type == '激进债券型': market_type = market_all['中证综合债收益率']*0.8+market_all['中证800收益率'] * 0.2 elif fund_type =='短债型': market_type = market_all['中证短债收益率'] elif fund_type =='可转债型': market_type = market_all['中证可转债收益率'] elif fund_type =='环球股票': market_type = market_all['MSCI收益率'] else: market_type = np.array([]) rst = pd.DataFrame(market_type, columns=['市场组合收益率']) rst['日期'] = time_list rst.set_index(['日期'], inplace=True) return rst def gen_market(self): '''计算同类基准 中证800收益率, 中证国债收益率, 恒生指数收益率, 中证综合债收益率, 中证短债收益率 MSCI收益率 没有用到 中证可转债 ''' # 中证800 market2 = self.market_fetch('000906') market1 = self.market_fetch('000001') market1 = market1[market1.index < '20050105'] a = market2[market2.index == '20050104'].iloc[0, 0] / market1[market1.index== '20050104'].iloc[-1, 0] market1['000906'] = market1['000001'] * a index = market1[market1.index == '20050104'].index.tolist()[0] market_800 = pd.concat([market1[['000906']] , market2], axis=0).drop([index]) # 中证国债 m_country = self.market_fetch('h11006') # 恒生指数 HSI = self.get_market_wind('HSI.HI') #中证综合债 m_bond = self.market_fetch('h11009') # 中证短债 market_short = self.market_fetch('h11015') # 中证可转债 market_tran = self.market_fetch('000832') # MSCI MSCI = self.get_market_wind("892400.MI") self.market = market_800.join([m_country,HSI,m_bond,market_short,market_tran,MSCI]) self.market.columns = ['中证800','中证国债','恒生指数','中证综合债','中证短债','中证可转债','MSCI'] return def market_fetch(self, stock_index): '''获取所有交易日指数数据''' sql1 = ''' SELECT T0.F2_1425 日期, T0.F7_1425 AS 复权收盘价 FROM wind.TB_OBJECT_1425 T0 LEFT JOIN wind.TB_OBJECT_1090 T1 ON T1.F2_1090 = T0.F1_1425 WHERE T1.F16_1090 = '%(index_code)s' AND T1.F4_1090 = 'S' ORDER BY T0.F2_1425 ''' % {'index_code': stock_index} market = pd.DataFrame(self.cu_wind.execute(sql1).fetchall(), columns=['日期', '指数收盘价']) market.index = market['日期'] del market['日期'] market.columns = [stock_index] # market = market.pct_change() return market def get_market_wind(slef, code, index_start_date='19900101', end_date='20190331'): try: df = w.wsd(code, "close", index_start_date, end_date, "","Currency=CNY", usedf=True)[1] #df = w.wsd(code, "close", "2015-01-01", end_date, "","Currency=CNY", usedf=True)[1] df.index = pd.Series(df.index).apply(lambda x: str(x)[:4] + str(x)[5:7] + str(x)[8:10]) df.columns = [code] except: df = pd.DataFrame(columns=[code]) return df def get_fund_price_fof(self, code, start_date='', end_date='', time_list=[]): '''fof 基金计算波动和回测时用到的sql查询方法''' if time_list: start_date = time_list[0] end_date = time_list[-1] sql = ''' select tradedate, closeprice from t_fof_value_info where fundid = '%(code)s' and tradedate >= '%(start_date)s' and tradedate <= '%(end_date)s' ''' % {'end_date': end_date, 'code': code, 'start_date': start_date} fund_price = pd.DataFrame(self.cu_pra.execute(sql).fetchall(), columns=['日期', '复权单位净值']) fund_price.set_index('日期', inplace=True) if fund_price.empty: raise Exception('lact of fund value') if time_list: if len(time_list) - fund_price.shape[0] > 30: raise Exception('lack of data') fund_price = fund_price.reindex(time_list) return fund_price def get_fund_price_index(self, code, start_date='', end_date='', time_list=[]): '''获取指数的净值数据''' if time_list: start_date = time_list[0] end_date = time_list[-1] sql =f''' select f2_1425,f7_1425 from wind.tb_object_1425 left join wind.tb_object_1090 on f1_1425 = f2_1090 where f16_1090 = '{code}' and (f2_1425 >='{start_date}' and f2_1425 <= '{end_date}') and f4_1090 = 'S' order by f2_1425 ''' fund_price = pd.DataFrame(self.cu_wind.execute(sql).fetchall(), columns=['日期', '复权单位净值']) fund_price.set_index('日期', inplace=True) if fund_price.empty: raise Exception('lact of fund value') if time_list: if len(time_list) - fund_price.shape[0] > 30: raise Exception('lack of data') fund_price = fund_price.reindex(time_list) return fund_price
class Week_return: """周收益率相关类 对外接口: zhoubodong:波动率 :param code: 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float max_down_fund:最大回测 :param code: 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float performance_stability_fof:业绩稳定 :param code: fof 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float compute_alpha2:计算alpha :param code: 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float abs_return:获取绝对收益率 :param code: 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float performance_stability:业绩稳定,code :param code: 代码:str :param start_date:起始日期 :str :param end_date: 结束日期:str :return: float """ def __init__(self): self.cu = sql_oracle.cu self.cu_pra = sql_oracle.cu_pra_sel self.t = Time_tool() self.init_table() self.init_funcs() self.year_x = 52 def init_table(self): """初始化各种数据库表名""" self.fof_member_info = 't_fof_member_info' def init_funcs(self): """初始化各种外挂方法""" classes = [Compute_alpha] for class_ in classes: class_(self).add_func() def set_year_x(self, x): """设置计算年化时的系数""" self.year_x = x def _get_winning(self, df): """ 计算胜率 :param df:超额收益 :return: 胜率 """ # 超额收益大于0的个数/总个数 res = len(df.loc[df['超额收益'] > 0]) / len(df) return res def get_week_return_year(self, df): """根据传入的周收益表计算年化收益""" # 周收益平均*系数,默认是52 return_mena = df['超额收益'].mean() res = return_mena * self.year_x return res def get_week_return(self, code: str, start_date: str, end_date: str, types: str = 'fund', jz: str = 'biwi'): """周超额收益查询""" # 首先计算出时间序列 time_df = self.t.get_week_trade_days(start_date, end_date) pre_day = self.t.get_pre_week_trade_day(start_date) time_list = list(time_df['日期']) # 对于第一周的计算 需要用到上一周的数据,所有向列表头部插入了一个日期 time_list.insert(0, pre_day) if types == 'fund': df = self.get_week_return_fund(code, time_list, jz) else: df = self.get_week_return_fund_fof(code, time_list, jz) return df def get_week_return_fund(self, code: str, time_list: list, jz: str = 'biwi'): """ fund 周收益查询 :param code: 基金代码 :param time_list: 时间序列 :param js: 基准 :return: """ df01 = self.get_week_value_fund(code, time_list) if jz == 'biwi': try: df02 = self.get_week_close_biwi(code, time_list) except: df02 = self.get_week_close_ejfl(code,time_list) else: df02 = self.get_week_close_biwi(code, time_list) # 超额收益计算 基金收益率-指数收益率 df = pd.merge(df01, df02, on='日期', how='left') df['超额收益'] = df['周收益率_x'] - df['周收益率_y'] # 去重 df.dropna(inplace=True) # time_index = df01.index.values # return_value = df01['周收益率'].values - df02['周收益率'].values # df = pd.DataFrame(columns=['时间', '超额收益']) # df['时间'] = time_index # df['超额收益'] = return_value df.set_index('日期', inplace=True) df = df[['超额收益']] return df def get_week_return_fund_fof(self, code: str, time_list: list, jz: str = 'zz800'): """ fund 周收益查询 fof 版 :param code: 基金代码 :param time_list: 时间序列 :param js: 基准 :return: """ df01 = self.get_week_value_fund_fof(code, time_list) if jz == 'zz800': # 中证800 index_code = '000906' df02 = self.get_week_close_zz800(index_code, time_list) else: df02 = self.get_week_close_biwi(code, time_list) # 超额收益计算 基金收益率-指数收益率 df = pd.merge(df01, df02, on='日期', how='left') df['超额收益'] = df['周收益率_x'] - df['周收益率_y'] # 去空 df.dropna(inplace=True) # time_index = df01.index.values # return_value = df01['周收益率'].values - df02['周收益率'].values # df = pd.DataFrame(columns=['时间', '超额收益']) # df['时间'] = time_index # df['超额收益'] = return_value df.set_index('日期', inplace=True) df = df[['超额收益']] return df def get_week_value_fund(self, code: str, time_list: list): """ 获取周净值,算周收益,fund :param code: 基金代码 :param time_list: 每个交易周中的最后一个交易日,含有起始日期的上一个交易周的最后一个交易日 :return: df index 日期,columns收益率 """ t1 = time_list[0] t2 = time_list[-1] sql_week_value_fund = f""" select f13_1101,f21_1101 from wind.tb_object_1101 left join wind.tb_object_1090 on f14_1101 = f2_1090 where f16_1090 = '{code}' and (f13_1101 >= '{t1}' and f13_1101 <='{t2}') order by f13_1101 """ sql_res = self.cu.execute(sql_week_value_fund).fetchall() df = pd.DataFrame(sql_res, columns=['日期', '复权单位净值']) df.set_index('日期', inplace=True) # 筛选出需要的日期 df = df.reindex(time_list) # df02 = df['复权单位净值'].pct_change() df['上周复权单位净值'] = df['复权单位净值'].shift() df['周收益率'] = (df['复权单位净值'] - df['上周复权单位净值']) / df['上周复权单位净值'] # df = df[['周收益率']] # 去重,其索引,后期merge会用到日期字段 df.dropna(inplace=True) df.reset_index(inplace=True) return df def get_week_value_fund_fof(self, code: str, time_list: list): """ 获取周净值,算周收益,fof :param code: 基金代码 :param time_list: 每个交易周中的最后一个交易日,含有起始日期的上一个交易周的最后一个交易日 :return: df index 日期,columns收益率 """ t1 = time_list[0] t2 = time_list[-1] # sql_week_value_fund = f""" # select f13_1101,f21_1101 from wind.tb_object_1101 left join wind.tb_object_1090 on f14_1101 = f2_1090 # where f16_1090 = '{code}' and (f13_1101 >= '{t1}' and f13_1101 <='{t2}') # order by f13_1101 # """ sql_week_value_fund = f""" select tradedate,closeprice from t_fof_value_info where fundid = '{code}' and tradedate >= '{t1}' and tradedate <= '{t2}' order by tradedate """ print(sql_week_value_fund) sql_res = self.cu_pra.execute(sql_week_value_fund).fetchall() df = pd.DataFrame(sql_res, columns=['日期', '复权单位净值']) # print(df) df.set_index('日期', inplace=True) # 筛选出需要的日期 df = df.reindex(time_list) # df02 = df['复权单位净值'].pct_change() df['上周复权单位净值'] = df['复权单位净值'].shift() df['周收益率'] = (df['复权单位净值'] - df['上周复权单位净值']) / df['上周复权单位净值'] # df = df[['周收益率']] # 去重,其索引,后期merge会用到日期字段 df.dropna(inplace=True) df.reset_index(inplace=True) # print(df) return df def get_week_close_biwi(self, code: str, time_list: list): """ 取基准,算周收益,biwi 这里要做异常处理,基准不能有空!基准含有空直接报错! :param code: 基金代码 :param time_list: 每个交易周中的最后一个交易日,含有起始日期的上一个交易周的最后一个交易日 :return: """ t1 = time_list[0] t2 = time_list[-1] sql_code = code + 'BI.WI' sql_week_close_bibw = f""" select trade_dt,s_dq_close from wind.chinamutualfundbenchmarkeod where s_info_windcode = '{sql_code}' and (trade_dt >= '{t1}' and trade_dt <='{t2}') order by trade_dt """ sql_res = self.cu.execute(sql_week_close_bibw).fetchall() assert sql_res, f'{code}基准查询结果为空,请改变基准' df = pd.DataFrame(sql_res, columns=['日期', '收盘价']) assert df.iloc[0][0] == t1, f'{code}基准查询结果含有空值,请改变基准' df.set_index('日期', inplace=True) # 筛选出需要的日期 df = df.reindex(time_list) # 计算收益率 close2-close1/close1 df['周收益率'] = df['收盘价'].pct_change() # 去空值 df.dropna(inplace=True) # df = df[['周收益率']] # 去索引,后面merge 会用到日期字段 df.reset_index(inplace=True) return df def get_week_close_zz800(self,index_code:str,time_list:list): """ 取基准,算周收益,biwi 这里要做异常处理,基准不能有空!基准含有空直接报错! :param code: 基金代码 :param time_list: 每个交易周中的最后一个交易日,含有起始日期的上一个交易周的最后一个交易日 :return: """ t1 = time_list[0] t2 = time_list[-1] sql_week_close_zz800 = f""" select f2_1425,f7_1425 from wind.tb_object_1425 left join wind.tb_object_1090 on f1_1425 = f2_1090 where f16_1090 = '{index_code}' and (f2_1425 >='{t1}' and f2_1425 <= '{t2}') and f4_1090 = 'S' order by f2_1425 """ # print(sql_week_close_zz800) sql_res = self.cu.execute(sql_week_close_zz800).fetchall() assert sql_res, f'{code}基准查询结果为空,请改变基准' df = pd.DataFrame(sql_res, columns=['日期', '收盘价']) assert df.iloc[0][0] == t1, f'{code}基准查询结果含有空值,请改变基准' df.set_index('日期', inplace=True) # 筛选出需要的日期 df = df.reindex(time_list) # 计算收益率 close2-close1/close1 df['周收益率'] = df['收盘价'].pct_change() # 去空值 df.dropna(inplace=True) # df = df[['周收益率']] # 去索引,后面merge 会用到日期字段 df.reset_index(inplace=True) return df def get_week_close_ejfl(self,code:str,time_list:list): """ 判断二级分类并且取出相应基准的周收盘 :param codeLStr: 基金代码 :param time_list: 时间列表 :return: """ ejfl = self.get_ejfl(code,time_list) index = self.change_ejfl_to_index(ejfl,time_list) index['日期'] = time_list index.rename(columns = {'市场组合收益率':'周收益率'},inplace = True) return index def get_ejfl(self,code:str,time_list:list): """根据代码和输入周期,计算二级分类""" end_date = time_list[-1] sql_string = f''' select * from ( select ejfl from t_fund_classify_his where rptdate <= {end_date} and cpdm = {code} order by rptdate ) where rownum=1 ''' sql_res = self.cu_pra.execute(sql_string).fetchall() if sql_res: res = sql_res[0][0] else: res = None return res def change_ejfl_to_index(self,fund_type:str,time_list:list): """ 输入二级分类和时间轴 :param fund_type: 二级分类 :param time_list: 时间轴 :return: """ res = sl.get_market(fund_type,time_list) return res def unpack_fof(self, fof,start_date,end_date): """解包fof""" sql_unpakc_fof = f""" select memberfundid,weight from {self.fof_member_info} where fundid = '{fof}' """ sql_res = self.cu_pra.execute(sql_unpakc_fof).fetchall() df = pd.DataFrame(sql_res, columns=['X', 'P']) return df def get_fund_price(self, code, start_date, end_date): """计算波动和回测时用到的sql查询方法""" sql = ''' select f13_1101 as 截止日期, f21_1101 as 复权单位净值 from wind.tb_object_1101 left join wind.tb_object_1090 on f2_1090 = f14_1101 where F16_1090= '%(code)s' and F13_1101 >= '%(start_date)s' and f13_1101 <= '%(end_date)s' ''' % {'end_date': end_date, 'code': code, 'start_date': start_date} fund_price = pd.DataFrame(self.cu.execute(sql).fetchall(), columns=['截止日期', '复权单位净值']) return fund_price # ************ 下面是对外的接口 ************************* def performance_stability(self, code: str, start_date: str, end_date: str, types: str = 'fund', jz: str = 'biwi'): """ 计算顺率 :param code:代码 :param start_date:开始日期 :param end_date: 结束日期 :param types: 代码类型,默认 fund :param jz: 指数类型,默认 biwi :return: """ if types == 'fund': df_return = self.get_week_return(code, start_date, end_date, types, jz) res = self._get_winning(df_return) elif types == 'fof': # 这里的js是自己重新定义的,理想状态是在外面的js定义好 jz = 'zz800' df_return = self.get_week_return(code, start_date, end_date, types, jz) res = self._get_winning(df_return) else: res = 0.0 return res def zhoubodong(self, code='163807', start_date='20190101', end_date='20190225'): fund_price = self.get_fund_price(code, start_date, end_date) fund_price2 = fund_price.sort_values(by=['截止日期']).reset_index(drop=True) fund_price2['fund_return'] = fund_price2.复权单位净值.diff() / fund_price2.复权单位净值.shift(1) fund_price2.dropna(axis=0, inplace=True) fund_price2.reset_index(drop=True, inplace=True) zhou_bodong = fund_price2.fund_return.std() * (math.sqrt(250)) return zhou_bodong # 计算最大回测 def max_down_fund(self, code='163807', start_date='20150528', end_date='20190225'): # 输出单只基金的最大回撤,返回一个float数值 # 提取复权净值 fund_price = self.get_fund_price(code, start_date, end_date) fund_price2 = fund_price.sort_values(by=['截止日期']).reset_index(drop=True) price_list = fund_price2['复权单位净值'].tolist() i = np.argmax((np.maximum.accumulate(price_list) - price_list) / np.maximum.accumulate(price_list)) # 结束位置 if i == 0: max_down_value = 0 else: j = np.argmax(price_list[:i]) # 开始位置 max_down_value = (price_list[j] - price_list[i]) / (price_list[j]) return -max_down_value def performance_stability_fof(self, fof: str, start_date: str, end_date: str): """ 业绩稳定性 :param code: 基金代码 :param start_date: 起始时间 :param end_date: 结束时间 :param types: 代码类型,默认 fund基金 :param jz: 基准指标,默认 biwi :return: """ # 先计算时间列表 time_df = self.t.get_week_trade_days(start_date, end_date) pre_day = self.t.get_pre_week_trade_day(start_date) time_list = list(time_df['日期']) time_list.insert(0, pre_day) # 再解包产品集D,得到x1,x2,x3和 p1,p2,p3 df_D = self.unpack_fof(fof,start_date,end_date) x_list = df_D['X'].values p_list = df_D['P'].values # print('x_list:',x_list) # print('p_list:',p_list) # 计算每个x的胜率 win_list = [] for x in x_list: df_week_return = self.get_week_return(x, start_date, end_date) winning = self._get_winning(df_week_return) win_list.append(winning) # 对上面的结果做加权平均 print('win_lilst:',win_list) res = np.average(win_list, weights=p_list) return res def abs_return(self, fof: str, start_date: str, end_date: str): """获取绝对收益率""" print('待开发') return 0.0 pass