@debut/indicators

中文文档
2.0.1发布于 2026/05/16GPL-3.0TypeScriptESM + CJS零依赖近 30 天下载 5160

Implementation of most popular technical stock indicators for debut environment

原始使用文档
文档目录28 节
  1. Features
  2. Install
  3. Quick start
  4. Streaming model
  5. nextValue(...) — close-of-bar
  6. momentValue(...) — intra-bar
  7. Available indicators
  8. Moving Averages
  9. Oscillators
  10. Momentum
  11. Trend
  12. Volatility
  13. Channels & Bands
  14. Volume
  15. Candles & Pivots
  16. Move / Wave (custom)
  17. Runtime state save & restore
  18. Candlestick Patterns
  19. Configurable thresholds
  20. Combined scanners
  21. Singleton buffer & resetting between streams
  22. Namespaced import
  23. Pattern catalog
  24. Session Volume Profile
  25. Utilities
  26. Cross-SDK validation
  27. Benchmarks
  28. License

npm npm NPM

Streaming Technical Indicators

Sponsored by Backticks — a visual canvas to build, backtest and optimize trading strategies in your browser. Built on top of this library.

A streaming, allocation-light technical-analysis toolkit for JavaScript / TypeScript. Every indicator is a class with a nextValue(...) method that consumes one bar at a time, so the same code path drives both backtests and live trading without rebuilding state. A second method, momentValue(...), computes the indicator's value for a hypothetical bar without committing any state — useful for tick-by-tick recalculation inside an unfinished candle.

Features

  • Streaming-first. O(period) per bar; no full-array recomputation.
  • momentValue everywhere. Ask "what would the value be if this bar closed now?" without mutating state.
  • TypeScript. Strongly-typed across the public surface.
  • Cross-SDK validated. 130+ jest tests cross-check our output against external reference libraries (lwc and ti) with epsilon ≤ 1e-9. See the Test column in the indicator tables below for which oracle each one is verified against.
  • Tiny package. Ships only the prebuilt lib/ bundle — ~85 kB tarball.

Install

npm install @debut/indicators

Quick start

import { SMA, RSI, MACD, BollingerBands } from '@debut/indicators';

const sma = new SMA(20);
const rsi = new RSI(14);
const macd = new MACD(12, 26, 9);
const bb = new BollingerBands(20, 2);

for (const bar of bars) {
    const sm = sma.nextValue(bar.close);
    const r = rsi.nextValue(bar.close);
    const m = macd.nextValue(bar.close);   // → { macd, signal, histogram }
    const b = bb.nextValue(bar.close);     // → { lower, middle, upper }
    // ...indicator outputs are `undefined` until each one's warmup completes.
}

nextValue returns undefined until the indicator has seen enough bars to produce a result (its "warmup" — typically period bars). After that it returns the current value on every call.

Streaming model

nextValue(...) — close-of-bar

Call this once per closed bar. The method advances internal state and returns the new indicator value. Subsequent calls reflect the committed state.

momentValue(...) — intra-bar

Call this with the live (still-forming) candle's price/volume to read what the indicator would report if the bar closed now, without committing any state. Useful when you want to react inside the candle but recompute cleanly when the next real nextValue arrives.

const sma = new SMA(4);
[1, 2, 3].forEach((v) => sma.nextValue(v));   // warmup
sma.momentValue(8);   // 3.5  ← preview if close=8
sma.nextValue(4);     // 2.5  ← actual close=4 commits state
sma.momentValue(8);   // 4.75 ← preview based on committed state
sma.nextValue(8);     // 4.25 ← actual close=8 commits state

Available indicators

Below is the full catalog grouped by category. Names in code style are the exact named export from @debut/indicators. Linkable indicator names lead to a per-indicator doc page in docs/. The Test column marks which external library the cross-SDK validation runs against — `lwc` = lightweight-charts-indicators, `ti` = technicalindicators (see Cross-SDK validation for what that means).

Moving Averages

IndicatorExportTestDescription
Simple Moving AverageSMAtiArithmetic mean over a period.
Exponential Moving AverageEMAtiWeighted average emphasizing recent prices.
Weighted Moving AverageWMAtiLinearly increasing weights toward the latest bar.
Linearly Weighted MALWMALinear weighting variant.
Exponential Weighted MAEWMAConfigurable α; lighter than EMA for tick smoothing.
Smoothed Moving AverageSMMAWilder smoothing (α = 1/period).
Wilder's Smoothed MAWEMAtiSame shape as RMA, included for compatibility.
Welles Wilder's SmoothingWWSClassic Wilder smoothing.
Adaptive Moving AverageAMAKaufman adaptive — speeds up in trend, slows in chop.
Running Moving AverageRMAα = 1/period; SMA-seeded.
Hull Moving AverageHMAlwcReduced-lag MA via WMA chaining.
Double EMADEMAlwc2 × EMA − EMA(EMA).
Triple EMATEMAThree-stage EMA reduction of lag.
Arnaud Legoux MAALMAlwcGaussian-weighted MA.
Volume Weighted MAVWMAlwcEach bar weighted by volume.
McGinley DynamicMcGinleyDynamiclwcSelf-adjusting MA reacting to market speed.
Least Squares MALSMAlwcEndpoint of rolling linear regression.

Oscillators

IndicatorExportTestDescription
Relative Strength IndexRSItiClassic 14-period momentum oscillator.
StochasticStochastictiClose vs. high-low range.
Stochastic RSIStochasticRSItiStochastic applied to RSI.
Commodity Channel IndexCCItiDeviation-from-mean cyclic oscillator.
Williams %RWilliamsInverse-stochastic momentum.
Awesome OscillatorAOtiBill Williams 5/34 SMA difference of HL2.
Accelerator OscillatorACBill Williams AO derivative.
Chande Momentum OscillatorCMOWilder-style CMO.
Chande MO (LWC)ChandeMOlwcLWC reference variant; raw rolling sums.
Detrended Price OscillatorDPOSMA-detrended price.
Relative Vigor IndexRVIlwcSWMA-based vigor / signal pair.
SMI ErgodicSMIErgodiclwcDouble-smoothed momentum (TSI without 100×).
True Strength IndexTSIlwcDouble-EMA momentum oscillator with signal.
Bollinger Bands %BBBPercentBlwcPrice position relative to BB.
Fisher TransformFisherTransformlwcGaussian-mapped price extremes.
Ultimate OscillatorUltimateOscillatorMulti-timeframe weighted momentum.
Connor's RSIcRSIComposite RSI / streak / percent-rank.
Relative Volatility IndexRelativeVolatilityIndexlwcRSI on stdev of close.

Momentum

IndicatorExportTestDescription
MACDMACDtiDifference of two EMAs with signal/histogram.
MomentumMomentumlwcclose − close[length].
Rate of ChangeROCtiPercentage change over a period.
Balance of PowerBOPlwc(close − open) / (high − low).
Bull-Bear PowerBullBearPowerlwcElder: high + low − 2·EMA(close).
Force IndexForceIndexElder: signed price-volume impulse.
Elder RayElderRayBull / bear power split.
Price OscillatorPriceOscillatorlwcPercent-PPO with signal/histogram.
Coppock CurveCoppockCurvelwcWMA of summed long/short ROCs.
TRIXTRIXtiROC of triple-smoothed EMA.
KSTKSTlwc"Know Sure Thing" weighted ROC sum + signal.

Trend

IndicatorExportTestDescription
Average Directional IndexADXtiTrend strength irrespective of direction.
Directional Movement IndexDMI+DI, −DI, ADX.
Ichimoku CloudIchimokuConversion / base / spans / lagging.
Parabolic SARPSARtiWelles Wilder's trailing stop.
SupertrendSuperTrendATR-based dynamic support/resistance.
AroonAroonlwcBars-since-extreme up/down lines.
ChoppinessChoppinesslwcRange-vs-volatility chop measure.
Mass IndexMassIndexlwcReversal detection via H-L EMA ratio.
VortexVortexlwcVI+ / VI− directional pair.
Trend Strength IndexTrendStrengthIndexlwcPearson correlation of close vs. bar index.
Chande Kroll StopChandeKrollStoplwcLong / short ATR-based stop levels.

Volatility

IndicatorExportTestDescription
Average True RangeATRtiWilder ATR with selectable smoothing.
Average Daily RangeADRlwcSMA of high − low.
Historical VolatilityHistoricalVolatilitylwcAnnualized stdev of log returns.
Bollinger BandWidthBBBandWidthlwc(upper − lower) / basis × 100.
Standard DeviationStandardDeviationStreaming biased stdev provider.

Channels & Bands

IndicatorExportTestDescription
Bollinger BandsBollingerBandstiSMA ± k × stdev.
Donchian ChannelsDCHighest-high / lowest-low envelope.
Keltner ChannelKeltnerChanneltiEMA / ATR envelope.
EnvelopesEnvelopestiFixed-percentage MA bands.
Median (with bands ready upstream)MedianlwcRolling median of HL2.

Volume

IndicatorExportTestDescription
On Balance VolumeOBVlwcCumulative signed volume.
Money Flow IndexMFItiVolume-weighted RSI.
Price Volume TrendPVTlwcVolume scaled by relative price change.
Volume OscillatorVolumeOscillatortiDifference between volume EMAs.
Chaikin OscillatorChaikinOscillatorEMA spread of A/D line.
Chaikin Money FlowChaikinMFlwcA/D divided by volume over a window.
Ease of MovementEaseOfMovementlwcPrice change vs. volume.
Klinger OscillatorKlingerlwcLong-term money-flow oscillator.
Net VolumeNetVolumelwcSigned volume by candle direction.
Volume ProfileVolumeProfileSession histogram with POC / VAH / VAL.

Candles & Pivots

IndicatorExportTestDescription
Heiken AshiHeikenAshiSmoothed candle stream.
FractalFractalBill Williams 5-bar fractals.
Pivot LevelsPivotClassic / Woodie / Camarilla / Fibonacci.
Trend LinesTrendLinesPivot-derived trend line detection.
ExtremumsExtremumsFractal-style local extrema provider.

Move / Wave (custom)

IndicatorExportDescription
MoveMoveDirection move with minimum power p.
WaveWaveBullish/bearish candle series with power p.

Runtime state save & restore

Every stateful indicator exposes two methods:

  • dumpState() returns a JSON-safe snapshot of all internal runtime state.
  • restoreState(state) restores that snapshot into a new indicator instance and returns the instance.

The snapshot includes nested providers and rolling buffers such as CircularBuffer, so an indicator can continue after a process restart without replaying the full history. Constructor parameters are still part of the indicator configuration: restore state into an instance created with the same period/options that produced the snapshot.

import { EMA } from '@debut/indicators';

const ema = new EMA(20);

for (const close of history) {
    ema.nextValue(close);
}

// Persist this string in your own runtime storage: database, file, Redis, etc.
const serialized = JSON.stringify(ema.dumpState());

// Later, after a restart:
const restored = new EMA(20).restoreState(JSON.parse(serialized));

const liveValue = restored.nextValue(nextClose);

For live systems, save the state after committing each closed bar, together with the indicator configuration and stream identity. On startup, recreate each indicator with the same constructor arguments, call restoreState(...), then continue feeding new bars through nextValue(...).

Candlestick Patterns

Each is a streaming class:

import { Doji, BullishEngulfingPattern, HammerPattern } from '@debut/indicators';

const doji = new Doji();
const engulfing = new BullishEngulfingPattern();
const hammer = new HammerPattern();   // 5-bar with confirmation candle

for (const bar of bars) {
    if (doji.nextValue(bar.open, bar.high, bar.low, bar.close)) console.log('Doji', bar.time);
    if (engulfing.nextValue(bar.open, bar.high, bar.low, bar.close)) console.log('Bull Engulfing', bar.time);
    if (hammer.nextValue(bar.open, bar.high, bar.low, bar.close)) console.log('Hammer', bar.time);
}

nextValue returns true when the pattern fires, false if not, and undefined while it's still warming up (multi-bar patterns need their full lookback first).

Configurable thresholds

Each pattern accepts an options bag in its constructor. The defaults match the ti reference exactly; tighten or loosen them as you see fit.

OptionUsed byDefaultDescription
precisionDoji-family, Marubozu, hammer-stick, HaramiCross, HammerPattern, HangingMan, ShootingStar, Abandoned/Doji-Star variants0.001Fuzzy-match tolerance: how close open≈close (or body-touches-high/low) must be to qualify as "equal". 0.001 ≈ 0.1% relative.
shadowToBodyRatioHammer-stick variants, HammerPattern, HangingMan, ShootingStar2The opposing shadow must be at least this many times the body length.
minShadowToBodyRatioSpinningTop variants1Both shadows must be strictly larger than the body by this ratio.
equalityToleranceTweezer-Bottom/Top0 (exact)How close low[i]/high[i] of the two candles must be.
confirmHammerPattern, HangingMan, ShootingStartrueRequire the 5th bar's confirmation candle. The *Unconfirmed variants flip this to false.
const wideDoji = new Doji({ precision: 0.005 });           // 0.5% relative tolerance
const fastHammer = new HammerPattern({ confirm: false });  // skip the confirmation candle
const looseTweezer = new TweezerBottom({ equalityTolerance: 0.0001 });

Combined scanners

If you want to scan a bar against many patterns at once, use one of the three combined scanners. They share the singleton OhlcBuffer declared inside the patterns module so you don't pay for per-pattern buffers.

import { AllCandlestickPatterns, BullishPatterns, BearishPatterns } from '@debut/indicators';

const all = new AllCandlestickPatterns();
const bull = new BullishPatterns();
const bear = new BearishPatterns();

for (const bar of bars) {
    const fired = all.nextValue(bar.open, bar.high, bar.low, bar.close);
    if (fired.length) console.log(bar.time, fired);
    // → e.g. [1700000000, ['BullishHammerStick', 'BullishMarubozu']]

    if (bull.nextValue(bar.open, bar.high, bar.low, bar.close)) console.log('any bullish');
    if (bear.nextValue(bar.open, bar.high, bar.low, bar.close)) console.log('any bearish');
}

AllCandlestickPatterns.nextValue returns the array of pattern names that fired on the bar; BullishPatterns / BearishPatterns return a single boolean ("did any pattern fire").

Singleton buffer & resetting between streams

All multi-bar patterns share one OhlcBuffer(5) declared at module scope in src/candlestick/patterns.ts. The first pattern that sees a brand-new bar advances the buffer; later calls within the same tick are dedup'd by OHLC equality. This means dropping in a fresh pattern instance is essentially free — there's no per-pattern ring allocation.

If you switch between independent bar streams (or want a clean slate between test cases), call BasePattern.reset():

import { BasePattern } from '@debut/indicators/lib/src/candlestick/patterns';

BasePattern.reset(); // clears the singleton OHLC ring + dedupe state

Namespaced import

If you'd rather not pull 35 symbols into scope:

import { Candlestick } from '@debut/indicators';

const doji = new Candlestick.Doji();
const all = new Candlestick.AllCandlestickPatterns();

Pattern catalog

LookbackPatterns
1 barDoji, DragonFlyDoji, GraveStoneDoji, BearishHammerStick, BullishHammerStick, BearishInvertedHammerStick, BullishInvertedHammerStick, BearishMarubozu, BullishMarubozu, BearishSpinningTop, BullishSpinningTop
2 barsBearishEngulfingPattern, BullishEngulfingPattern, BearishHarami, BullishHarami, BearishHaramiCross, BullishHaramiCross, DarkCloudCover, PiercingLine
3 barsAbandonedBaby, DownsideTasukiGap, EveningStar, EveningDojiStar, MorningStar, MorningDojiStar, ThreeBlackCrows, ThreeWhiteSoldiers
5 barsHammerPattern, HammerPatternUnconfirmed, HangingMan, HangingManUnconfirmed, ShootingStar, ShootingStarUnconfirmed, TweezerBottom, TweezerTop

Session Volume Profile

VolumeProfile aggregates traded volume across price rows and exposes POC, VAH / VAL with configurable tickSize, distribution, and session anchoring ('daily' by default — unbounded streams can't grow the row map forever).

import { VolumeProfile } from '@debut/indicators';
const vp = new VolumeProfile({ tickSize: 0.5 });
for (const bar of bars) {
    const { poc, val, vah, total } = vp.nextValue(bar);
}

Full options, formula, performance notes, and custom-session recipe: docs/VolumeProfile.md.

Utilities

ExportDescription
CircularBufferFixed-size ring buffer with at() / peek() / forEach(). Powers most rolling-window indicators.
SamplerSample-of-sample provider for stacking smoothing (e.g. SMA(SMA(SMA(...)))).
CorrelationStreaming Pearson correlation.
Level, UniLevelDynamic level (UniLevel: balanced around 0).
ExtremumsFractal-style local extrema.
CandlesPer-bar candlestick context (body, shadows, doji, trend) shared by pattern detectors.

Cross-SDK validation

Every ported indicator and candlestick pattern has a vitest-style spec in tests/<name>/<name>.spec.ts that:

  1. Generates deterministic synthetic OHLCV bars with a seeded LCG (see tests/lwc-fixtures.ts).
  2. Runs them through the streaming @debut/indicators class.
  3. Runs the same bars through the corresponding lwc calculate() (or ti for the older specs) — see the Test column in each indicator table for which oracle that pattern is matched against.
  4. Asserts numeric equality with epsilon ≤ 1e-9 (or set membership for boolean pattern firings).

Run npm test to execute the full suite.

Benchmarks

Apple M1 Pro, Node v16.14.0. Tested on dataset with 100k elements.

Indicator name@debut/indicators (ops/sec)technicalindicators (ops/sec)indicatorts (ops/sec)
AwesomeOscillator31823158
ADX35842x
ATR61313695
Bollinger Bands3479219
CCI15112158
DC474x74
PSAR1,453278666
EMA1,7204521,537
MACD1,41790467
ROC3,62564x
RSI1,23938315
SMA67865645
WEMA1,462455x
WMA28741x
Stochastic3402567

Benchmarks results is autogenerated by https://github.com/debut-js/indicators-benchmark

License

GPL-3.0

版本与发布记录

@debut/indicators 共发布 57 个版本,首次发布于 2021/05/26;过去 12 个月发布了 3 个版本。

版本发布日期距今
2.0.1latest2026/05/165 个月前
2.0.02026/05/096 个月前
1.4.22026/04/286 个月前
1.3.222024/11/032 年前
1.3.212024/09/222 年前
1.3.202024/03/092 年前

关于 @debut/indicators 的常见问题

@debut/indicators 是什么?

Implementation of most popular technical stock indicators for debut environment

如何安装 @debut/indicators?

在项目目录运行 npm install @debut/indicators,或使用 pnpm add / yarn add / bun add。

@debut/indicators 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@debut/indicators 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@debut/indicators 可以商用吗?

@debut/indicators 使用 GPL-3.0 许可。强 Copyleft:分发包含该代码的软件时,整个作品需以 GPL-3.0 兼容许可开源,并附带专利与反锁定条款。仅内部使用不触发此义务。以上为概括,不构成法律意见,请以许可原文为准。

@debut/indicators 的下载量有多少?

根据 npm 官方下载统计,@debut/indicators 在 2026/10/12 – 2026/11/10 这 30 天内被下载 5,160 次,日均约 172 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@debut/indicators 还在维护吗?

最新版本 2.0.1 发布于 2026/05/16(5 个月前);至今共发布 57 个版本,其中过去 12 个月发布了 3 个;首次发布于 2021/05/26。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。