UNPKG

trading-signals

Version:

Technical indicators to run technical analysis with JavaScript / TypeScript.

120 lines 4.46 kB
import { IndicatorSeries } from '../../base/Indicator.js'; export class PSAR extends IndicatorSeries { accelerationStep; accelerationMax; state = { acceleration: 0, extreme: null, isLong: null, lastSar: null, prePreviousCandle: null, previousCandle: 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.state.lastSar !== null; } getRequiredInputs() { return 2; } update(candle, replace) { const { high, low } = candle; this.trackState(replace); const state = this.state; if (!state.previousCandle) { state.previousCandle = candle; return null; } if (state.lastSar === null) { const currentMidpoint = (high + low) / 2; const previousMidpoint = (state.previousCandle.high + state.previousCandle.low) / 2; state.isLong = currentMidpoint >= previousMidpoint; if (state.isLong) { state.extreme = high; state.lastSar = state.previousCandle.low; } else { state.extreme = low; state.lastSar = state.previousCandle.high; } state.acceleration = this.accelerationStep; state.prePreviousCandle = state.previousCandle; state.previousCandle = candle; return this.setResult(state.lastSar, replace); } let sar = (state.extreme - state.lastSar) * state.acceleration + state.lastSar; if (state.isLong) { const hasPrevPrev = state.prePreviousCandle != null; if (hasPrevPrev && low < sar) { if (state.prePreviousCandle.low < sar) { sar = state.prePreviousCandle.low; } sar = state.previousCandle.low < sar ? state.previousCandle.low : sar; } else if (state.previousCandle.low < sar) { sar = state.previousCandle.low; } if (high > state.extreme) { state.extreme = high; if (state.acceleration < this.accelerationMax) { state.acceleration += this.accelerationStep; if (state.acceleration > this.accelerationMax) { state.acceleration = this.accelerationMax; } } } if (low < sar) { state.isLong = false; sar = state.extreme; state.extreme = low; state.acceleration = this.accelerationStep; } } else { const hasPrevPrev = state.prePreviousCandle != null; if (hasPrevPrev && high > sar) { if (state.prePreviousCandle.high > sar) { sar = state.prePreviousCandle.high; } sar = state.previousCandle.high > sar ? state.previousCandle.high : sar; } else if (state.previousCandle.high > sar) { sar = state.previousCandle.high; } if (low < state.extreme) { state.extreme = low; state.acceleration += this.accelerationStep; if (state.acceleration > this.accelerationMax) { state.acceleration = this.accelerationMax; } } if (high > sar) { state.isLong = true; sar = state.extreme; state.extreme = high; state.acceleration = this.accelerationStep; if (sar >= low) { sar = low - 0.01; } } } state.lastSar = sar; state.prePreviousCandle = state.previousCandle; state.previousCandle = candle; return this.setResult(sar, replace); } getResultOrThrow() { return super.getResultOrThrow(); } } //# sourceMappingURL=PSAR.js.map