'benchmark_price': dv.data_benchmark, # 为空计算的是绝对收益 不为空计算相对收益 'period': period, # 20天的持有期 'mask': mask, 'can_enter': can_enter, 'can_exit': can_exit, 'forward': True, 'commission': 0.0008, "covariance_type": "shrink", # 协方差矩阵估算方法 还可以为"simple" "rollback_period": 250 } # 滚动窗口天数 comb_factors = dict() for method in ["equal_weight", "ic_weight", "ir_weight", "max_IR", "max_IC"]: signal = multi_factor.combine_factors(factor_dict, standardize_type="rank", winsorization=False, weighted_method=method, props=props) #z-score标准化 comb_factors[method] = process.standardize(signal, index_member) ic_20 = multi_factor.get_factors_ic_df( comb_factors, price=dv.get_ts("close_adj"), high=dv.get_ts("high_adj"), # 可为空 low=dv.get_ts("low_adj"), # 可为空 n_quantiles=5, # quantile分类数 mask=mask, # 过滤条件 can_enter=can_enter, # 是否能进场 can_exit=can_exit, # 是否能出场 period=period, # 持有期
'ret_type': 'return',#可选参数还有upside_ret/downside_ret 则组合因子将以优化潜在上行、下行空间为目标 'benchmark_price': dv.data_benchmark, # 为空计算的是绝对收益 不为空计算相对收益 'period': 20, # 20天的持有期 'mask': mask, 'can_enter': can_enter, 'can_exit': can_exit, 'forward': True, 'commission': 0.0008, "covariance_type": "shrink", # 协方差矩阵估算方法 还可以为"simple" "rollback_period": 250} # 滚动窗口天数 comb_factors = dict() for method in ["equal_weight","ic_weight","ir_weight","max_IR","max_IC"]: comb_factors[method] = multi_factor.combine_factors(factor_dict, standardize_type="z_score", #有"rank"(排序标准化),"z_score"(z-score标准化)两种 winsorization=False, weighted_method=method, props=props) print(method) print(comb_factors[method].dropna(how="all").head()) period = 20 ic_20 = multi_factor.get_factors_ic_df(comb_factors, price=dv.get_ts("close_adj"), high=dv.get_ts("high_adj"), # 可为空 low=dv.get_ts("low_adj"),# 可为空 n_quantiles=5,# quantile分类数 mask=mask,# 过滤条件 can_enter=can_enter,# 是否能进场 can_exit=can_exit,# 是否能出场 period=period,# 持有期
'forward': True, 'commission': 0.0008, "covariance_type": "shrink", # "shrink"表示的是压缩协方差矩阵估算方法 还可以为"simple"协方差矩阵估算方法 "rollback_period": 120 } # 滚动窗口天数 #测试:multi_factor.combine_factors();comb_factors是合成因子(将上述4个因子进行合成),这里的合成方法预设有5种(5种方法好好理解下?) comb_factors = dict() for method in ["equal_weight", "ic_weight", "ir_weight", "max_IR", "max_IC"]: #分别表示进行等权、以某个时间窗口的滚动平均ic为权重、 #以某个时间窗口的滚动ic_ir为权重、最大化上个持有期的ic_ir为目标处理权重、最大化上个持有期的ic为目标处理权重的加权组合方式(上文中提及) comb_factors[method] = multi_factor.combine_factors( factor_dict, #因子的字典,其中Key为因子的名称,因子的value为dataframe standardize_type= "rank", #输入因子标准化方法,有"rank"(排序标准化),"z_score"(z-score标准化)两种("rank"/"z_score") winsorization=False, #对合成的因子去极值,例如:0.05表示去掉因子值左右两端5%的数值 weighted_method=method, #可选的加权方法(5种) props=props) #props是上面已经配置好的配置信息 print(method) print(comb_factors[method].dropna(how="all").head()) #step2:计算新因子的ic_30(即ic分析) #比较组合前和组合后的因子在30日持有期下的表现(统一到2014年9月后进行比较.这是由于上面用到了一个时间的滚动窗口"rollback_period": 120) ic_30 = multi_factor.get_factors_ic_df( comb_factors, price=dv.get_ts("close_adj"), high=dv.get_ts("high_adj"), # 可为空 low=dv.get_ts("low_adj"), # 可为空 n_quantiles=5, # quantile分类数 mask=mask, # 过滤条件
def test_multi_factor(): from jaqs_fxdayu.research.signaldigger import multi_factor, process dv = DataView() dv.load_dataview(dataview_folder) dv.add_formula("momentum", "Return(close_adj, 20)", is_quarterly=False, add_data=True) mask = mask_index_member(dv) can_enter, can_exit = limit_up_down(dv) ic = dict() factors_dict = { signal: dv.get_ts(signal) for signal in ["pb", "pe", "ps", "momentum"] } for period in [5, 15]: ic[period] = multi_factor.get_factors_ic_df( factors_dict, price=dv.get_ts("close_adj"), high=dv.get_ts("high_adj"), # 可为空 low=dv.get_ts("low_adj"), # 可为空 n_quantiles=5, # quantile分类数 mask=mask, # 过滤条件 can_enter=can_enter, # 是否能进场 can_exit=can_exit, # 是否能出场 period=period, # 持有期 benchmark_price=dv. data_benchmark, # 基准价格 可不传入,持有期收益(return)计算为绝对收益 commission=0.0008, ) factor_dict = dict() index_member = dv.get_ts("index_member") for name in ["pb", "pe", "ps", "momentum"]: signal = -1 * dv.get_ts(name) # 调整符号 process.winsorize(factor_df=signal, alpha=0.05, index_member=index_member) # 去极值 signal = process.rank_standardize( signal, index_member) # 因子在截面排序并归一化到0-1(只保留排序信息) signal = process.standardize(signal, index_member) # z-score标准化 保留排序信息和分布信息 # 行业市值中性化 signal = process.neutralize( signal, group=dv.get_ts("sw1"), float_mv=dv.get_ts("float_mv"), index_member=index_member, # 是否只处理时只考虑指数成份股 ) factor_dict[name] = signal # 因子间存在较强同质性时,使用施密特正交化方法对因子做正交化处理,用得到的正交化残差作为因子 new_factors = multi_factor.orthogonalize( factors_dict=factor_dict, standardize_type="rank", # 输入因子标准化方法,有"rank"(排序标准化),"z_score"(z-score标准化)两种("rank"/"z_score") winsorization=False, # 是否对输入因子去极值 index_member=index_member) # 是否只处理指数成分股 # 多因子组合-动态加权参数配置 props = { 'price': dv.get_ts("close_adj"), 'high': dv.get_ts("high_adj"), # 可为空 'low': dv.get_ts("low_adj"), # 可为空 'ret_type': 'return', # 可选参数还有upside_ret/downside_ret 则组合因子将以优化潜在上行、下行空间为目标 'benchmark_price': dv.data_benchmark, # 为空计算的是绝对收益 不为空计算相对收益 'period': 30, # 30天的持有期 'mask': mask, 'can_enter': can_enter, 'can_exit': can_exit, 'forward': True, 'commission': 0.0008, "covariance_type": "shrink", # 协方差矩阵估算方法 还可以为"simple" "rollback_period": 120 } # 滚动窗口天数 comb_factors = dict() for method in [ "equal_weight", "ic_weight", "ir_weight", "max_IR", "max_IC", "factors_ret_weight" ]: comb_factors[method] = multi_factor.combine_factors( factor_dict, standardize_type="rank", winsorization=False, weighted_method=method, props=props)