You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于RxJS实现值偏差压力检测:输出阈值外的变化百分比

需求说明

我有一个Observable,它会生成快速的无限正整数序列。需要将其转换为值变化百分比序列,仅当在指定时间窗口(毫秒级)内,变化百分比超出设定阈值时才输出。

代码示例

function getPressurePercents(input: Observable<number>, minChange: number, iw: number) {
   // 返回一个Observable,仅当在iw时间窗口内值变化百分比超出minChange时,输出该变化百分比
}

const obs = getPressurePercents(input, 0.5, 3000).subscribe(val => {
    // 输入值在过去3秒内变化了至少0.5%
    // val = 变化百分比,Math.abs(val) >= 0.5
    // 正值表示百分比上升,负值表示百分比下降
});

需求细节

在上述示例中,目标是得到一个Observable:当输入数值在3秒窗口内出现0.5%的变化/偏差时,输出对应的变化百分比。

该需求用于识别值变化的压力峰值,例如股票价格的快速大幅波动(价格峰值),并在变化超出阈值时触发通知。

重要说明

实现需同时支持上升和下降两种场景:窗口内的百分比下降需输出负百分比。


解决方案

我实现了一个可直接集成到RxJS管道的操作符,相比纯RxJS内置操作符组合的方案更简洁易懂,具体代码如下:

import { Observable, scan, filter, map } from 'rxjs';

function getPressurePercents(input: Observable<number>, minChange: number, windowMs: number): Observable<number> {
  return input.pipe(
    scan((acc, current) => {
      // 记录当前时间与值,同时清理窗口外的历史数据
      const now = Date.now();
      acc.history = acc.history.filter(entry => now - entry.timestamp <= windowMs);
      acc.history.push({ timestamp: now, value: current });

      // 取窗口内最早的有效值作为基准
      const initialValue = acc.history[0]?.value;
      if (!initialValue) return acc;

      // 计算变化百分比
      acc.changePercent = ((current - initialValue) / initialValue) * 100;
      return acc;
    }, { history: [] as { timestamp: number; value: number }[], changePercent: 0 }),
    // 过滤出符合阈值要求的变化
    filter(state => Math.abs(state.changePercent) >= minChange),
    // 仅输出变化百分比数值
    map(state => state.changePercent)
  );
}

方案说明

  • 用scan维护时间窗口内的历史值集合,自动剔除超出窗口的旧数据
  • 以窗口内第一个有效值为基准,计算当前值的变化百分比
  • 通过filter筛选出满足阈值条件的结果,最终输出纯百分比数值
  • 天然支持正负百分比输出:上升为正,下降为负

内容的提问来源于stack exchange,提问作者vitaly-t

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:43:12