@elitechart/indicators
v0.1.1
Published
Technical-analysis indicator library for ChartForge — 50+ mathematically-correct indicators, tree-shakeable.
Downloads
64
Maintainers
Readme
@elitechart/indicators
Technical-analysis indicators for ChartForge — 30 pure functions covering moving averages, volatility bands, momentum oscillators, trend followers, volume-weighted indicators, and price-level overlays. Every indicator is a pure function with the signature (bars, params) => output — no hidden state, no DOM, safe for Web Workers, SSR, unit tests, and offline backtesting.
Install
pnpm add @elitechart/indicators@elitechart/core is a runtime peer for the Bar type and memoization helpers.
Quick example
import { sma, rsi, macd, bollinger } from '@elitechart/indicators';
const smaValues = sma(bars, { period: 20 });
// [null, null, …, 42045.3, 42048.1, …] ← `null` for warmup bars
const rsiValues = rsi(bars, { period: 14 });
const {
macd: line,
signal,
histogram,
} = macd(bars, {
fast: 12,
slow: 26,
signal: 9,
});
const { upper, middle, lower } = bollinger(bars, { period: 20, stdDev: 2 });Subpath imports (recommended)
For tightest bundles, import each indicator from its own subpath — same IndicatorFn signature, zero index-barrel cost:
import { rsi } from '@elitechart/indicators/rsi';
import { macd } from '@elitechart/indicators/macd';
import { bollinger } from '@elitechart/indicators/bollinger';Catalog
| Name | Subpath | Description | Inputs |
| ------------ | -------------- | ------------------------------------------- | ------------------------------------------- |
| sma | /sma | Simple moving average | period |
| ema | /ema | Exponential moving average | period |
| wma | /wma | Weighted moving average | period |
| vwma | /vwma | Volume-weighted moving average | period |
| dema | /dema | Double exponential moving average | period |
| tema | /tema | Triple exponential moving average | period |
| hullma | /hullma | Hull moving average | period |
| bollinger | /bollinger | Bollinger Bands (upper/middle/lower) | period, stdDev |
| bollingerB | /bollinger-b | %B oscillator from Bollinger | period, stdDev |
| keltner | /keltner | Keltner Channels (ATR-based bands) | period, multiplier |
| donchian | /donchian | Donchian Channels (rolling high/low) | period |
| stdev | /stdev | Rolling standard deviation | period |
| rsi | /rsi | Relative Strength Index (Wilder) | period |
| stochastic | /stochastic | Stochastic oscillator (%K, %D) | kPeriod, dPeriod, smooth |
| macd | /macd | MACD line, signal, histogram | fast, slow, signal |
| cci | /cci | Commodity Channel Index | period |
| roc | /roc | Rate of Change | period |
| williamsR | /williams-r | Williams %R | period |
| aroon | /aroon | Aroon up / Aroon down | period |
| tsi | /tsi | True Strength Index | long, short |
| atr | /atr | Average True Range (Wilder) | period |
| adx | /adx | Average Directional Index (+DI / -DI / ADX) | period |
| psar | /psar | Parabolic SAR | step, max |
| supertrend | /supertrend | SuperTrend overlay | period, multiplier |
| obv | /obv | On-Balance Volume | – |
| vwap | /vwap | Session Volume-Weighted Average Price | – |
| mfi | /mfi | Money Flow Index | period |
| cmf | /cmf | Chaikin Money Flow | period |
| pivots | /pivots | Floor pivots (P / R1-R3 / S1-S3) | kind |
| ichimoku | /ichimoku | Ichimoku Kinko Hyo (5 lines) | tenkan, kijun, senkou, displacement |
Output shape
Single-line indicators return a ReadonlyArray<number | null> aligned one-to-one with the input bars. null marks the warmup period — never 0, never NaN. Multi-line indicators return a tagged record (e.g. bollinger → { upper, middle, lower }, ichimoku → { tenkan, kijun, senkouA, senkouB, chikou }).
Custom indicator
Match the IndicatorFn shape and you can plug it into the same memoization + overlay pipeline as the built-ins:
import type { IndicatorFn, LineOutput } from '@elitechart/indicators';
import type { Bar } from '@elitechart/core';
interface ZScoreParams {
readonly period: number;
}
export const zscore: IndicatorFn<ZScoreParams, LineOutput> = (bars: ReadonlyArray<Bar>, { period }) => {
const out: Array<number | null> = new Array(bars.length).fill(null);
for (let i = period - 1; i < bars.length; i++) {
let sum = 0;
for (let j = i - period + 1; j <= i; j++) sum += bars[j].close;
const mean = sum / period;
let varSum = 0;
for (let j = i - period + 1; j <= i; j++) {
const d = bars[j].close - mean;
varSum += d * d;
}
const sd = Math.sqrt(varSum / period);
out[i] = sd === 0 ? 0 : (bars[i].close - mean) / sd;
}
return out;
};Memoizing in the paint loop
Pair with memoizeSingle from @elitechart/core to skip rework during pan/zoom — overlays only need to recompute when bars change:
import { memoizeSingle } from '@elitechart/core';
import { sma } from '@elitechart/indicators/sma';
const fastSma = memoizeSingle((bars) => sma(bars, { period: 20 }));Numerical accuracy
Every indicator has unit tests verifying warmup boundaries, edge cases (empty input, single bar, NaN guards), and numerical stability against authoritative fixtures (Wilder's smoothing for ATR/RSI/ADX, Bollinger's original formula). Outputs are deterministic.
Compatibility
- Node 20.11+. DOM-free; works in Bun, Deno (with appropriate types), and any JS runtime.
- Browsers evergreen Chrome / Safari / Firefox / Edge.
- SSR safe — no top-level globals.
- Tree-shakeable ESM + CJS dual emit, named exports only,
sideEffects: false. Subpath imports give the tightest bundle.
Links
License
MIT — see LICENSE.
