150-AI选股策略
由qxiao创建,最终由qxiao 被浏览 4 用户
策略介绍
本策略通过选择多维度的因子,使用AI算法来预测股票的未来表现并进行排序。这里使用算法StockRanker,BigQuant 平台开发的一种先进的机器学习算法,专门用于量化选股排序学习,通过在多个因子/特征的数据上训练,旨在从大量股票中识别并排序那些未来表现可能最优异的股票。
策略思想
策略基于以下几个核心思想:
- 特征选择:输入对股票价格有显著影响的多维度因子,包括估值、成长、财务、杠杆、市场及技术指标方面的因子
- 预测目标:预测未来 5 日收益率
- 数据抽取和处理:抽取和处理数据
- 模型训练:应用StockRanker算法,训练模型来预测股票未来上涨概率。StockRanker返回一个相对分数(score),分数越大,预测未来涨幅越大。注意此 score 绝对值没有意义。
- 仓位分配:买入 score 靠前的股票,等仓持有前10只股票
- 回测与交易:设置调仓周期,根据仓位目标,发出交易信号
策略实现&代码
在BigQuant平台可以非常容易的将量化+AI结合起来。如下是策略代码,可以克隆策略进入 AIStudio 运行和调优。
https://bigquant.com/codesharev3/d3677b94-d355-484e-863b-940154d96969
策略理解
基础选股模块
- m7添加 A股-基础选股 模块
- 指数成分:只选择
沪深300
- m7的输出连接到m1的第一个输
- 指数成分:只选择
\
因子特征选择
- 在m1 输入特征 DAI SQL 实现因子输入,这里用 表达式模式 输入
- 使用 cn_stock_prefactors 预计算因子表 中数据作为基础数据,从中选择估值、成长、财务、杠杆、市场及技术指标方面的因子提取并过滤掉st股票以及上市不足一年的股票
\
预测目标
m2
模块实现数据标注,在 m1的数据上(input_1.*
),进一步添加了 label 数据列label
列的计算m_lead(close, 5) / m_lead(open, 1)
未来第5天的收盘价除以明天的开盘价,即对应的是明天开盘买入,5个交易日后收盘卖出c_quantile_cont(_future_return, 0.01)
和c_quantile_cont(_future_return, 0.99)
计算未来收益的 1% 和 99% 分位值- clip(_future_return, _future_return_1pct, _future_return_99pct) 根据分位值裁剪数据,即裁剪极值
c_cbins(_clipped_return, 20) AS label
将数据等分为 20 组,即离散化。
\
数据抽取
\
-
m3
和m4
分别在抽取训练数据集和预测数据集 -
m3训练数据集,用于算法模型训练。抽取 2021-01-01 到 2022-12-31 的数据做为训练数据,向前取数 90天,用于部分算子需要更多历史数据
-
m4预测数据集(测试数据集体),用于验证训练效果 / 获得预测结果。抽取 2023-01-01 到 2024-12-25 的数据作为预测数据,也向前取数 90天。同时为了在模拟交易时对当日做预测,勾选上绑定交易日,在模拟交易时,将这两个值都替换为交易日期
-
另一个可选的数据集是验证数据集,一般用于查看训练过程中的收敛情况和效果
-
\
模型训练和预测
\
- m5 StockRanker 训练用于模型训练,输入数据中的label作为预测目标,其他列(除date instrument 外)作为特征输入。
-
StockRanker算法原理,可以参考论文 From RankNet to LambdaRank to LambdaMART: An Overview
-
学习算法:排序,相关技术请搜索
learning to rank
-
叶节点数量:30。StockRanker会构建多棵二叉树,这里表示每棵树的最大叶节点数量。一般情况下,这个值越大,在训练集上拟合越好,也可能在训练数据上过度拟合
-
每叶节点最小样本数:1000。这里表示每个叶节点最小需要1000个数据样本支持。一般情况下,这个值越大,泛化性能越好
-
树的数量:20。StockRanker会训练多棵树,后面的树不断拟合前面训练的残差,以期逐步减少训练损失,最后收敛。一般情况下,这个值越大,在训练集上拟合越好,也可能在训练数据上过度拟合
-
学习率:0.1。机器学习学习率。经验参数。
-
特征值离散化数量:对于每个特征,StockRanker会将其分组离散化。一般情况下,这个值越小,泛化行越好,但也可能学习不够
-
特征列采样率和数据行采样率,在训练每棵树时,使用多少比例的特征(列)和数据样本(行),为1表示每次都适应全部数据。小于1,表示随机抽样一部分。一般情况下,这个值越小,泛化行越好,但也可能学习不够
-
NDCG base,请搜索 NDCG。对应下面的1部分,这个值越大,表示顺序的影响越小。
-
\
-
仓位分配
m6
仓位分配:从预测 score 到 仓位,这个模块用于简化仓位生成,提供了多种仓位生成例子- 评分score和排序:
score DESC
按输入数据里的 score 的降序排序 - 持仓股票数量:10表示买入排名前10的股票
- 仓位公式:
1 AS position
从 score 到 postion,等权重进行仓位分配 - 总仓位:1。总仓位为1 则归一化到1,即
position / sum(position) * total_position
。如果为0 则不做归一化。
\
回测交易
\
-
m7
BigTrader 回测和交易,每5日调仓,开盘买入卖出。 -
K线处理函数:主要代码
def bigquant_run(context, data): import pandas as pd # 下一个交易日不是调仓日,则不生成信号 if not context.rebalance_period.is_signal_date(data.current_dt.date()): return # 从传入的数据 context.data 中读取今天的信号数据 today_df = context.data[context.data["date"] == data.current_dt.strftime("%Y-%m-%d")] # 卖出不在目标持有列表中的股票 for instrument in sorted(set(context.get_account_positions().keys()) - set(today_df["instrument"])): context.order_target_percent(instrument, 0) # 买入目标持有列表中的股票 for i, x in today_df.iterrows(): context.order_target_percent(x.instrument, 0.0 if pd.isnull(x.position) else x.position)
更多关于 回测的说明可以参考 预备知识回测部分
\