python量化交易

367 阅读6分钟

project 介绍

ricequant 回测选股
文章所有回测数据都在 ricequant 平台完成 , 代码字段仅在该平台有效
平台主要覆盖中国市场 , 并不支持美股数据( 如 标普500 )查询

因子选股

评判一个股票是否值得购买常见的因子有 : 每股收益(EPS) , 净资产收益率 (ROE) , 投入资本回报率 (ROIC) , 资产负债率(D/A) , 市净率(PB) , 市值 (MC) , 市盈率(PE) 等
可以选择一个因子对股票池中的股票进行排序
代码及注释👇( 测试的单因子是市值MC , 测试股票数据为沪深300 )
单因子选股.py

回测收益 :
image.png image.png 21年 - 24年亏 (策略选股亏的极多)
因20年偶然性导致策略收益略高 , 综合来看并不推荐单因子选股策略

多因子选股 :
简单组合[ 市盈率(PE) , 市净率(PB), 净资产收益率(ROE) ]
更全面的组合 : [ 每股收益(EPS) , 净资产收益率 (ROE) , 投入资本回报率 (ROIC) , 资产负债率(D/A) , 市净率(PB) , 市值 (MC) ]
对因子打分选股
正相关的因子 , 越高越好 : EPS , ROE , ROIC
负相关的因子 , 越低越好 : D/A , PB , MC
根据排名打分
每个月更新综合排名前十的数组 , 不在这个数组中的股票就卖出 , 综合策略收益很不错(19 - 24年) , 比较推荐
代码及注释 👉 多因子选股

image.png

image.png

双均线择时买股卖股

金叉与死叉
短期 > 长期 , 值得买入(黄金) , 标注交叉点位置 , 计算均线策略收益

# 使用 talib 计算短期和长期简单移动平均线 (SMA)
import talib

prices = history_bars(stock_code, context.OBSERVATION, '1d', 'close')
short_ma = talib.SMA(prices, context.SHORTPERIOD)
long_ma = talib.SMA(prices, context.LONGPERIOD)

获取到的prices数组是一个数字序列(如 NumPy 数组),该序列中的每个数字代表相应的交易日的收盘价( 由字段close指定收盘价 )。在使用简单移动平均(SMA)计算均线时,会用到这个数组prices来计算短期 / 长期的平均价格,从而形成移动平均线

遍历多因子打分选出的前十个股票 , 判断交易时间是否为黄金交叉点 , 是则买入
判断股票池中的股票在当前交易时间是否处于死亡交叉点 , 是则卖出

收益效果不如多因子选股 , 短期长期时间天数的选择结果差异很大 , 经过多次测试 , 短期时间选择 12 天 , 长期时间选择26 天效果最佳
代码文件 👉 多因子打分+双均线.py

股价预测

简单的线性回归预测涨跌

部分名词解释 :
梯度下降 : 一种优化算法 , 基本思想是沿着函数梯度的反方向 , 以迭代的方式逐步调整参数 , 从而找到函数的局部最小值。 image.png
梯度下降的数学表达为: θ=θαJ(θ)\theta = \theta - \alpha \nabla J(\theta)
其中 ,θ是模型参数 , α 是学习率(越小越好) , ∇J(θ) 是梯度
计算公式如下

J(θ)=[Jθ1,Jθ2,,Jθd].\nabla J(\boldsymbol\theta) = \begin{bmatrix} \dfrac{\partial J}{\partial \theta_1},\, \dfrac{\partial J}{\partial \theta_2},\, \dots,\, \dfrac{\partial J}{\partial \theta_d} \end{bmatrix}^\top.

批量梯度下降
每次迭代使用全样本计算梯度
随机梯度下降
每次迭代随机抽取一个样本 , 常见于深度学习 , 成功率不稳定
小批量梯度下降
使用一小批随机样本计算梯度 , 兼顾效率和稳定性
常见批量大小 : 64 , 128 , 256
回归特征制作 :
不预测涨幅 , 只预测涨势 ( 是涨是跌 )
获取选中股票24年收盘价数据 , 计算前一天报酬率 , 前两天报酬率
计算公式如下 :
报酬率=期末价值期初价值期初价值=收益期初投资额\text{报酬率} = \frac{\text{期末价值} - \text{期初价值}}{\text{期初价值}} = \frac{\text{收益}}{\text{期初投资额}}
构建回归方程
model = LinearRegression()

聚类分析

聚类分析 : 无监督问题 , 不适合寻常股价预测 , 效果不太好 , 由于没有标签 , 结果不可控
识别异常值 , 异常价格波动 , 效果很好 , 聚类算法常用于区分不同的市场状态( 牛市、熊市、震荡市 )
常用算法 :
KMEANS算法 :
K 值:簇的数量 K , 将数据点分配到 K 个不同的簇来对数据进行分组
k 值不确定性极强 , 因此预测结果具有很强的随机性 , 只能测量多组数据选出相对效果最好的 K 值

KMEANS算法工作流 :
1.初始化质心:随机选择 K 个数据点作为初始质心。
2.分配数据点:将每个数据点分配到距离其最近的质心所在的簇。
3.更新质心:对每个簇,计算其所有数据点的平均值,更新质心的位置。
4.重复迭代:重复步骤 2 和 3,直到质心的位置不再发生显著变化或达到预设的迭代次数。

算法优缺点 :
当数据集近球形且大小相似时效果良好 , 数据集不规则时效果不佳
可视化KMEANS算法工作流网站 : visualizing-k-means-clustering

DBSCAN 算法 :
参数 :
邻域半径Epsilon (ε)
MinPts : 形成核心点所需的最小点数

优点 : 不需要指定簇的个数 适用于发现奇怪形状的簇
缺点 : 不适合密集数据 , 高维数据

可视化DBSCAN算法工作流网站 : visualizing-dbscan-clustering

image.png

待实现

决策树 , 随机森林回归
lightGBM
深度学习时间序列预测 RNN

对因子数据进行处理

计算因子的IC值 : 计算因子和收益率之间的相关性 剔除缺失 , 停牌 , ST(特别处理 Special Treatment , 财务状况异常) , 新股数据
拿到因子数据 , 转秩 , 进行以下处理

去极值

对以下三种去极值方法选一种即可
[0.025 ~ 0.095]
MAD : 数据点与中位数 ( Median ) 绝对值的中位数

MAD=median(Ximedian(X))\text{MAD} = \text{median} \left( \left| X_i - \text{median}(X) \right| \right)

对极值进行操作 : n = 1.4826

Xi={Xmedian+nMADif Xi>Xmedian+nMADXmediannMADif Xi<XmediannMADXiif XmediannMADXiXmedian+nMADX_i' = \begin{cases} X_{\text{median}} + n \cdot \text{MAD} & \text{if } X_i > X_{\text{median}} + n \cdot \text{MAD} \\ X_{\text{median}} - n \cdot \text{MAD} & \text{if } X_i < X_{\text{median}} - n \cdot \text{MAD} \\ X_i & \text{if } X_{\text{median}} - n \cdot \text{MAD} \leq X_i \leq X_{\text{median}} + n \cdot \text{MAD} \end{cases}

3Sigma : 99.7%的数据

Xi±3σ\text X_i ± 3\sigma

超过这个范围视为异常数据

标准化(standard)

可以使用 sklearn 中的 StandardScaler简便计算
标准化公式:

z=xμσz = \frac{x - \mu}{\sigma}

标准化对异常值敏感 , 可先检测并处理异常值

中性化(neutral)

构建股票因子时 , 常常需要对因子进行中性化处理 , 作用类似于化学实验中的蒸馏提纯 , 使分析结果更聚焦于目标变量本身 , 减少市场或者其他因素对选股的影响
实现方法 : 构建回归方程 , 提取残差

y(kx+b)y - (kx + b)

y是因子(如PB , PE) , x 是需要剥离的变量(常见的有市值 , 行业)
多变量回归 , 用于策略回测
单变量回归 , 用于数据预处理阶段