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,都是基于历史窗口计算,因此自然具有滞后性。毕竟趋势描述的是一段区间的走势特征,而非单点波动。

代码就不贴出来了,把上述方法交给编程辅助工具即可实现。