fast-technical-indicators
Version:
High-performance technical indicators with zero dependencies - compatible with technicalindicators package
65 lines (64 loc) • 2.13 kB
JavaScript
export function minusdm(input) {
const { high, low, period = 14 } = input;
if (!high || !low || high.length !== low.length || high.length < 2) {
return [];
}
const minusDMValues = [];
// Calculate raw Minus DM values
for (let i = 1; i < high.length; i++) {
const upMove = high[i] - high[i - 1];
const downMove = low[i - 1] - low[i];
// Minus DM = downMove if downMove > upMove and downMove > 0, else 0
let minusDM = 0;
if (downMove > upMove && downMove > 0) {
minusDM = downMove;
}
minusDMValues.push(minusDM);
}
if (minusDMValues.length < period) {
return [];
}
const result = [];
// Calculate initial smoothed Minus DM (simple average of first period)
let smoothedMinusDM = minusDMValues.slice(0, period).reduce((sum, val) => sum + val, 0);
result.push(smoothedMinusDM);
// Calculate subsequent smoothed Minus DM using Wilder's smoothing
for (let i = period; i < minusDMValues.length; i++) {
smoothedMinusDM = ((smoothedMinusDM * (period - 1)) + minusDMValues[i]) / period;
result.push(smoothedMinusDM);
}
return result;
}
export class MinusDM {
constructor(input) {
this.highValues = [];
this.lowValues = [];
this.period = input.period || 14;
if (input.high && input.low && input.high.length === input.low.length) {
for (let i = 0; i < input.high.length; i++) {
this.nextValue(input.high[i], input.low[i]);
}
}
}
nextValue(high, low) {
this.highValues.push(high);
this.lowValues.push(low);
const result = minusdm({
high: this.highValues,
low: this.lowValues,
period: this.period
});
if (result.length > 0) {
return result[result.length - 1];
}
return undefined;
}
getResult() {
return minusdm({
high: this.highValues,
low: this.lowValues,
period: this.period
});
}
}
MinusDM.calculate = minusdm;