分类 量化交易 下的文章

🚀 实战精讲:一分钟数据也能玩转的 RSI 增量更新技术


在量化交易中,RSI(相对强弱指数) 是一项经典且高效的动量指标。但对于分钟线、秒线等高频数据场景,传统的 RSI 算法存在效率瓶颈,尤其是在实时系统中反复扫描历史K线极其不划算。

本篇文章,我们将系统性讲解一种基于平均涨跌幅的 RSI 增量更新算法,并结合实盘中常见的多币种管理、风控联动等场景,逐步构建一套高性能 RSI 技术体系。


📘 RSI 的基本原理回顾

RSI 的经典计算公式为:

RSI = 100 - 100 / (1 + RS)
RS = 平均上涨幅度 / 平均下跌幅度

其中,“平均”一般采用 N 日(或 N 根K线) 的移动平均值,常用周期为 6、14、21 等。


🎯 实战问题:分钟线数据如何高效计算 RSI?

在高频场景下,例如:

  • 加密货币:全天 1440 根 1min K线
  • 美股分钟线:每个交易日约 390 根
  • 高频策略:每秒响应一次行情更新

我们若用全量遍历方式去计算 RSI,不仅性能开销大,而且不具备持续性。


✅ 增量更新方案:仅需保存 avgGain 和 avgLoss!

1. 初始化阶段(N 个数据)

先计算 N 根K线的平均涨幅、跌幅(SMA):

avgGain₀ = sum(gains) / N
avgLoss₀ = sum(losses) / N

2. 实时更新阶段(从 N+1 开始)

只需使用上一时刻的 avgGainavgLoss,加上当前一根K线的涨跌值,使用递推公式更新:

avgGainₙ = (PrevAvgGain * (N - 1) + 当前Gain) / N
avgLossₙ = (PrevAvgLoss * (N - 1) + 当前Loss) / N

再将其带入 RSI 公式即可得到最新值。


🧩 多币种实时 RSI 追踪器(PHP 实战)

我们将 RSI 更新器封装成类,每个交易对(symbol)拥有一个独立实例。

class RSITracker {
    private int $period;
    private float $avgGain = 0.0;
    private float $avgLoss = 0.0;
    private ?float $lastClose = null;
    private int $initCount = 0;

    public function __construct(int $period = 6) {
        $this->period = $period;
    }

    public function update(float $close): ?float {
        if (is_null($this->lastClose)) {
            $this->lastClose = $close;
            return null;
        }

        $delta = $close - $this->lastClose;
        $gain = max($delta, 0);
        $loss = max(-$delta, 0);
        $this->lastClose = $close;

        if ($this->initCount < $this->period) {
            $this->avgGain = ($this->avgGain * $this->initCount + $gain) / ($this->initCount + 1);
            $this->avgLoss = ($this->avgLoss * $this->initCount + $loss) / ($this->initCount + 1);
            $this->initCount++;
            return null;
        }

        $this->avgGain = ($this->avgGain * ($this->period - 1) + $gain) / $this->period;
        $this->avgLoss = ($this->avgLoss * ($this->period - 1) + $loss) / $this->period;

        if ($this->avgLoss == 0) return 100.0;

        $rs = $this->avgGain / $this->avgLoss;
        return round(100 - 100 / (1 + $rs), 2);
    }
}

📦 多币种支持示例

foreach ($symbols as $symbol) {
    $trackers[$symbol] = new RSITracker(6);
}

$trackers['BTC-USDT']->update($close);

⚙️ 风控联动机制

  • RSI > 70 → 超买,触发止盈或做空提示
  • RSI < 30 → 超卖,触发抄底或买入提示
  • 可设置状态锁防止重复触发,回归 30~70 后解锁

🔌 可接入的实战系统

模块接入方式说明
OKX / Binance 行情WebSocket 每分钟推送收盘价
Webman 系统注册为定时或事件驱动组件
Redis 缓存保存 RSI 状态,跨进程共享
策略联动RSI 信号触发下单模块

🧠 总结

RSI 作为一个经典指标,在高频场景下也能轻量级运行,只要你用对方式!

通过增量更新、状态缓存和策略联动,我们可以构建出一个实盘可用、响应迅速、性能稳定的 RSI 处理框架。


📮 加入我们

欢迎关注我们,加入米多量化交流社群,一起探讨:

  • 交易信号构建
  • 多因子择时
  • 高频风险监控
  • 实盘风控插件设计

量化交易指标-随机指标(KDJ)

随机指标KDJGeorge C. Lane 提出。 它综合了动量观念,强弱指标及移动平均线的优点,用来度量股价脱离价格正常范围的变异程度。

KDJ 指标考虑的不仅是收盘价,而且有近期的最高价和最低价,这避免了仅考虑收盘价而忽视真正波动幅度的弱点。

随机指标的原理

随机指标(KDJ)一般是根据统计学的原理,通过一个特定的周期(如9日,9周)内出现过的最高价,最低价及最后一个计算周期的收盘价及这三者之间的比例关系,来计算最后一个计算周期的未成熟值(RSV),然后根据移动平均线的方法来计算K值, D值与J值,并绘制成曲线图来判断股票走势。

随机指标的计算公式


KDJ指标的计算比较复杂,首先要计算周期(n日,n周)的未成熟随机值RSV(RAW Stochastic Value),然后再计算K值,D值,J值。

以日K来计算的例子

RSV计算

$$RSV(n) = \frac{ Cn - Ln }{ Hn - Ln }$$

其中 Ct = 当前周期的收盘价,Ln = 当前计算周期内的最低价 Hn = 当前计算周期内最高价

K值计算

$$K(n) = \frac{2}{3}K(n-1) + \frac{1}{3}RSV(n)$$

其中 n=当前周期值

D值计算

$$D(n) = \frac{2}{3}D(n-1) + \frac{1}{3}K(n)$$

平滑因子 2/3, 1/3 是由人为决定,不过现在各大机构已经统一按 2/3, 1/3来计算

J值计算

K值的三倍减去D值的两倍,J值的意义本质上是衡量K值和D值之间的变异程度

$$J(n) = 3K(n) - 2D(n) $$

随机指标的投资策略


随机指标在图形上是三条曲线。即是K线,D线,J线。利用这三条曲线之间的关系就可以研究股票价格的趋势。随机指标主要用于反映股票市场中的超买和超卖现象,走势背驰现象。从而预测短期走势至顶和见底的过程。

超卖超卖现象

超买区: K值在80以上,D值在70以上,代表一个交易信号,股价未来一段时间很有可能会下跌。

超卖区: K值在20以下,D值在30以下,代表买入信号,股价未来一段时间很有可能会上涨。

K线图分析

这里我通过 比特币 近段时间的走势结合KDJ分析,我们是否能根据指标策略赚到利润。
BTC走势

如上图,假如我们的策略是

  • 每日8:01分K线完结后计算出KDJ, 如果K值 <= 20 买入BTC
  • 每日8:01分K线完结后计算出KDJ, 如果K只 >= 80 卖出BTC

买入默认按开盘价买入

从1月18日到2月02日这个周期我们有 1.1% 左右的收益,这里只是典型的一个例子。

详细的讲解可以听这个博主讲解10分钟学会随机指标

总结


股票的每一种指标都是为我们进入市场或者建立自己仓位的一个信号,具体信号的差异,风险的控制需要根据经验和自身能承受的风险能力来去衡量。后续我会通过一些代码分享如何编写可以自动执行的交易程序,如果大家喜欢这类型的文章和分享,一定要关注我。

参考文献