UNPKG

trading-signals

Version:

Technical indicators to run technical analysis with JavaScript / TypeScript.

121 lines 4.48 kB
import { IndicatorSeries } from '../../base/Indicator.js'; export class PSAR extends IndicatorSeries { accelerationStep; accelerationMax; acceleration = 0; extreme = null; lastSar = null; isLong = null; previousCandle = null; prePreviousCandle = null; constructor(config) { super(); this.accelerationStep = config.accelerationStep; this.accelerationMax = config.accelerationMax; if (this.accelerationStep <= 0) { throw new Error('Acceleration step must be greater than 0'); } if (this.accelerationMax <= this.accelerationStep) { throw new Error('Acceleration max must be greater than acceleration step'); } } get isStable() { return this.lastSar !== null; } getRequiredInputs() { return 2; } update(candle, replace) { const { high, low } = candle; const notEnoughData = !this.previousCandle || this.lastSar === null; if (replace && notEnoughData) { this.previousCandle = candle; return null; } if (!this.previousCandle) { this.previousCandle = candle; return null; } if (this.lastSar === null) { const currentMidpoint = (high + low) / 2; const previousMidpoint = (this.previousCandle.high + this.previousCandle.low) / 2; this.isLong = currentMidpoint >= previousMidpoint; if (this.isLong) { this.extreme = high; this.lastSar = this.previousCandle.low; } else { this.extreme = low; this.lastSar = this.previousCandle.high; } this.acceleration = this.accelerationStep; this.prePreviousCandle = this.previousCandle; this.previousCandle = candle; return this.setResult(this.lastSar, replace); } let sar = (this.extreme - this.lastSar) * this.acceleration + this.lastSar; if (this.isLong) { const hasPrevPrev = this.prePreviousCandle != null; if (hasPrevPrev && low < sar) { if (this.prePreviousCandle.low < sar) { sar = this.prePreviousCandle.low; } sar = this.previousCandle.low < sar ? this.previousCandle.low : sar; } else if (this.previousCandle.low < sar) { sar = this.previousCandle.low; } if (high > this.extreme) { this.extreme = high; if (this.acceleration < this.accelerationMax) { this.acceleration += this.accelerationStep; if (this.acceleration > this.accelerationMax) { this.acceleration = this.accelerationMax; } } } if (low < sar) { this.isLong = false; sar = this.extreme; this.extreme = low; this.acceleration = this.accelerationStep; } } else { const hasPrevPrev = this.prePreviousCandle != null; if (hasPrevPrev && high > sar) { if (this.prePreviousCandle.high > sar) { sar = this.prePreviousCandle.high; } sar = this.previousCandle.high > sar ? this.previousCandle.high : sar; } else if (this.previousCandle.high > sar) { sar = this.previousCandle.high; } if (low < this.extreme) { this.extreme = low; this.acceleration += this.accelerationStep; if (this.acceleration > this.accelerationMax) { this.acceleration = this.accelerationMax; } } if (high > sar) { this.isLong = true; sar = this.extreme; this.extreme = high; this.acceleration = this.accelerationStep; if (sar >= low) { sar = low - 0.01; } } } this.lastSar = sar; this.prePreviousCandle = this.previousCandle; this.previousCandle = candle; return this.setResult(sar, replace); } getResultOrThrow() { return super.getResultOrThrow(); } } //# sourceMappingURL=PSAR.js.map