原创文章第603篇,专注“AI量化投资、世界运行的规律、个人成长与财富自由"。
我们重新更新了可转债的全量数据,包含全量已经退市的转债。
——这是与股票市场不一样的地方,股票退市相对少,而转债本身就有退出周期。
因此,如果没有包含进来,那么策略就是有偏差的。
双低指标,单调性非常好:
单因子回测一下:
年化27.9%,最大回撤-13.6%。
策略核心代码如下:
import bt from bt_algos_extend import SelectTopK order_by = 'close'#'double_low'#'double_low' signal = CSVDataloader.get_col_df(df,col=order_by) #signal.dropna(inplace=True) all = [] for K in [30,]:s = bt.Strategy('可转债单因子策略'.format(K), [bt.algos.RunWeekly(),SelectTopK(signal,K,sort_descending=False),bt.algos.WeighEqually(),bt.algos.Rebalance()])all.append(s) stras = [bt.Backtest(s, data) for s in all]
把转债的价格单独拆分出来:
分层单调性一般:
IC值很好,但回测结果一般。
回测结果,年化12.6%,最大回撤-11.7%。
转股溢价率因子——单调性良好:
IC值一般:
年化28.6%,回撤-33.6%。
三个因子的分析结果看下来,有一个简单的结果:
分层单调性,对于轮动因子非常。
IC值大,但分层效果不好,大概率因子里包含了非线性因素。
IC值大的因子,可以经由机器学习模型来组合。
今天我们开始用机器学习的方式来初筛因子集。
咱们还是使用lightGBM集成学习的方式,决策树是可以筛选特征的重要性的。
import pandas as pd from lightgbm import LGBMRegressor from sklearn.metrics import mean_squared_error, r2_scoredef calc_metrics(model, X, y):y_pred = model.predict(X)mse = mean_squared_error(y, y_pred)r2 = r2_score(y, y_pred)print('r2:', r2, 'mse:', mse)def split_data(df, date):df_train = df[df.index <= date]df_val = df[df.index > date]return df_train, df_valdef train(df_train, df_val, feature_cols, label_col='label'):model = LGBMRegressor(boosting='gbdt', # gbdt \ dartn_estimators=600, # 迭代次数learning_rate=0.1, # 步长max_depth=10, # 树的最大深度seed=42, # 指定随机种子,为了复现结果num_leaves=250,# min_split_gain=0.01,lambda_l1=2,lambda_l2=2000)X_train = df_train[feature_cols]y_train = df_train[label_col]X_test = df_val[feature_cols]y_test = df_val[label_col]model.fit(X_train, y_train)calc_metrics(model, X_train, y_train)calc_metrics(model, X_test, y_test)"""模型保存"""from config import DATA_DIR# model.booster_.save_model(DATA_DIR.joinpath('models').joinpath('lgb_regressor.txt'))feat_importances = pd.Series(model.feature_importances_, index=X_train.columns).sort_values(ascending=False)print(feat_importances.head(20))return modelif __name__ == '__main__':import pandas as pdfrom config import DATA_DIR_BASICfrom datafeed.dataloader import CSVDataloader# bonds = pd.read_csv(DATA_DIR_BASIC.joinpath('cb_list2.csv'))# bonds = bonds[bonds['delist_date'] is None]# bonds = bonds['ts_code']df = CSVDataloader.get_df(symbols=None, set_index=True, start_date='20190101', path='bonds_all')print(df)df = CSVDataloader.calc_expr(df, ['close+cb_over_rate', 'roc(close,20)', 'ta_cci(high,low,close,20)','shift(close,-10)/close-1'],['double_low', 'roc_20', 'cci_20', 'label'])df.dropna(inplace=True)df_train, df_val = split_data(df, '2023-12-31')train(df_train, df_val, feature_cols=['cb_over_rate','close','bond_value','cb_value','ps_ttm','bond_over_rate','double_low', 'pb','pe_ttm'], label_col='label')
机器学习的权重排序:
bond_value IC值不明显,分层不单调,但lightGBM的权重重要性很高。这一点是比较矛盾的。
代码在这里:
AI量化实验室——2024量化投资的星辰大海
吾日三省吾身
欲速则不达。——这句老话非常有道理。
有时候,我们总希望把一些不喜欢的事情,尽快终结掉。
在评估不够充分时就快速推进事情。
结果有可能,事情也许办了,但引入其他更加不可控的事情。
有时候,淡定一点,把事情处理得稳妥一点,后续的事情会更少。
好事多磨,淡定一点。
历史文章:
全量可转债:平价底价溢价率与正股PB的单因子分析(附python代码)
代码发布:quantlabv5.3,可转债所有数据及双低、动量因子策略,单因子分析框架
量化私募公司的多因子构建方案(附python代码)
年化22.8%的单因子分析:基于Alphalens做可转债全市场数据的单因子分析(附python代码+全量数据)
AI量化实验室——2024量化投资的星辰大海