量化股票趋势的方法
1 引入
如何用程序识别股票趋势:上涨/下跌/横盘?我面对的问题是:某些策略在上涨时有效,有些在下跌时有效,还有些更适用于横盘。那么,如何以量化方式准确判断当前趋势呢?
趋势本身是一个相对的概念。上涨与下跌显然不同,而上涨与横盘有时难以区分,比如:究竟多长时间,多大涨幅能称为上涨?今天我们来探讨一下量化识别趋势的具体方法。
2 实现
在具体应用中,我们需考虑两个问题:
- 当前趋势判断:结合当前数值与近期历史数据,确定当前所处的趋势。
- 历史趋势判断:分析历史数据,将其划分为上涨、平稳和下跌的阶段。
2.1 原理
好的趋势判断方法,其核心在于明确多大尺度下允许多少波动来确认方向。这包含三个层面的框架:方向、坡度和噪音容忍度。
| 指标类别 | 用于判断什么 | 常用指标 | 参数示例 |
|---|---|---|---|
| 方向性 | 大方向是涨还是跌 | MA、MACD 方向 | 20 日 vs 60 日 |
| 坡度 | 涨得快还是慢(可用百分比或斜率) | MA 斜率、收益率 | 20 日涨幅 > +5% |
| 稳定性 | 是趋势还是乱拉(噪音比) | ATR/价格、布林带宽度 | ATR 占比 < 2% |
利用大周期判断方向,用强度指标判断真假方向,用波动指标避免噪音。
2.2 逻辑实现
下面是一个广泛应用的高效模型:ADX 结合均线方向以及波动率过滤。
| 条件 | 判定 |
|---|---|
| MA_short > MA_long & ADX > 25 | 上涨趋势 |
| MA_short < MA_long & ADX > 25 | 下跌趋势 |
| ADX < 20 | 横盘 |
| 中间区间 | 不明朗,观望 |
2.3 工具
实现金融指标时,Python 常用库包括 TA-Lib、pandas-ta、stockstats 和 finta,它们都支持计算 MA、ADX、ATR 等指标。
2.4 历史趋势判断
在分析历史趋势时,我们发现由多个短期趋势组成的大趋势可能带来过多噪音,影响我们将历史数据划分为清晰的大块,从而导致回测和建模工具可用的数据过于零散。在这种情况下,我们可以应用一些平滑处理。以下是平滑方法示例:
当某段趋势的长度小于设定的 min_len:
- 如果与前后的趋势一致,则将其归入前后趋势中。
- 如果前后趋势不一致,则比较两个趋势段的长度,选择较长的那个。
- 如果长度相同,优先选择前趋势(以保守为优)。
3 相关概念
- ATR:评估波动幅度的指标
- ATR 用于衡量近期(通常 14 天)价格波动的平均规模,ATR 值越高,表示行情波动越大且不确定性越高。
- ADX:评估趋势强度的指标
- ADX 反映近期(通常 14 天)上涨动能与下跌动能之间的差异,差异越大,趋势越强。
| 场景 | ATR | ADX | 理解 |
|---|---|---|---|
| 横盘 | 小 | 小 | 没方向、没力量 |
| 假突破 | 大 | 小 | 乱晃,不可靠 |
| 真趋势 | 适中或大 | 大 | 做对方向就舒服 |
| 极端行情 | 极大 | 极大 | 不确定能不能跑得掉 |
4 效果展示
下面展示了我用 Python 编写的趋势判断过程:上图中,蓝线代表收盘价,绿线为20日均线,红线为60日均线;中图显示ADX值;下图则呈现了平滑后的趋势。

趋势标签本质上是:以当前时点为界,对过去一段时间(如 14–60
天)的行情进行统计后得到的结果。
无论是均线、ADX 还是
ATR,都是基于历史窗口计算,因此自然具有滞后性。毕竟趋势描述的是一段区间的走势特征,而非单点波动。
代码就不贴出来了,把上述方法交给编程辅助工具即可实现。
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
