UNPKG

fast-technical-indicators

Version:

High-performance technical indicators with zero dependencies - compatible with technicalindicators package

76 lines (75 loc) 2.68 kB
function trueRange(high, low, previousClose) { const highLow = high - low; const highPrevClose = Math.abs(high - previousClose); const lowPrevClose = Math.abs(low - previousClose); return Math.max(highLow, highPrevClose, lowPrevClose); } export function atr(input) { const { period = 14, high, low, close } = input; if (high.length !== low.length || low.length !== close.length || close.length < period + 1) { return []; } const result = []; const trueRanges = []; // Calculate true ranges (skip first value since we need previous close) for (let i = 1; i < close.length; i++) { const tr = trueRange(high[i], low[i], close[i - 1]); trueRanges.push(tr); } // Calculate initial ATR using simple average let sum = 0; for (let i = 0; i < period; i++) { sum += trueRanges[i]; } let currentATR = sum / period; result.push(currentATR); // Calculate subsequent ATR using Wilder's smoothing for (let i = period; i < trueRanges.length; i++) { currentATR = ((currentATR * (period - 1)) + trueRanges[i]) / period; result.push(currentATR); } return result; } export class ATR { constructor(input) { this.highValues = []; this.lowValues = []; this.closeValues = []; this.trueRanges = []; this.initialized = false; this.period = input.period || 14; } nextValue(high, low, close) { this.highValues.push(high); this.lowValues.push(low); this.closeValues.push(close); // Need at least 2 closes to calculate true range if (this.closeValues.length < 2) { return undefined; } // Calculate true range const previousClose = this.closeValues[this.closeValues.length - 2]; const tr = trueRange(high, low, previousClose); this.trueRanges.push(tr); if (!this.initialized) { if (this.trueRanges.length === this.period) { // Calculate initial ATR using simple average const sum = this.trueRanges.reduce((acc, tr) => acc + tr, 0); this.currentATR = sum / this.period; this.initialized = true; return this.currentATR; } return undefined; } // Calculate ATR using Wilder's smoothing this.currentATR = ((this.currentATR * (this.period - 1)) + tr) / this.period; return this.currentATR; } getResult() { if (!this.initialized || this.currentATR === undefined) { return []; } return [this.currentATR]; } } ATR.calculate = atr;