@pond-ts/financial API Reference
    Preparing search index...

    Function parabolicSar

    • Parabolic SAR (J. Welles Wilder Jr., 1978) — the canonical multi-column state machine, and kernel K6's first consumer.

      A stop that trails the trend and accelerates towards it, reversing side whenever price crosses it:

      SAR[i+1] = SAR[i] + AF × (EPSAR[i])
      

      where EP is the extreme point of the current leg (the highest high while long, the lowest low while short) and AF starts at step, grows by step on each new extreme, and is capped at maxStep. When price penetrates the stop the side reverses, SAR is overridden with the leg's EP, and AF resets. The advance is clamped so a printed stop never sits inside the last two bars' ranges.

      Reads high and low only — the close plays no part in Wilder's rule.

      • ${prefix} — the stop value (psar at the default prefix).
      • ${prefix}Trend+1 while the stop trails below price, −1 above.

      The side is the half consumers need and cannot reliably recover: a chart draws the dot below the bar when long and above it when short, and psar < low is not a safe derivation because the clamp can print a stop exactly on an extreme (the advance is clamped to min(sar, prevLow, low), so equality is reachable, and then a strict comparison flips the dot to the wrong side). So the flag is carried out of the machine rather than re-derived from its output.

      Two columns means a prefix, per the studies README's uniform shape. The value column is the bare prefix rather than ${prefix}Line, which is a departure from macd's ${prefix}Line/Signal/Hist, and deliberate: MACD's three columns are three peers with no principal among them, whereas Parabolic SAR is one number and the trend is an annotation on it. Naming the value psarLine would make this the one study whose principal output is not reachable under the name the caller passed, and psar() would leave no column called psar. The precedent it follows is the single-output studies' bare output (atr, obv), not MACD's.

      TA-Lib's SAR(high, low, acceleration, maximum) is the reference and this matches it exactly (0.0 maximum absolute difference across (0.02, 0.2), (0.05, 0.5) and (0.01, 0.1) on the oracle's 80 bars, asserted in the generator). Three details of Wilder's rule are ambiguous in prose and are pinned to TA-Lib's reading:

      • The initial side comes from Wilder's −DM over the first one-bar move: short if the low fell further than the high rose, long otherwise (including on a tie and on an inside bar). Measured, not recalled.
      • The first printed bar is bar 1, and TA-Lib treats "yesterday" as "today" for its clamp on that bar only.
      • The clamp uses the last two bars, both on a reversal override and on an ordinary advance.

      SAREXT (which adds offset-on-reverse and independent long/short acceleration parameters) is a different function with a different output convention — it signs the short-side output negative — and is out of scope.

      Length-preserving: bar 0 is undefined on both columns (the seed needs a predecessor) and every bar from 1 on carries a value, matching TA-Lib's look-back of 1.

      A missing high or low resets the machine ([PND-SFOLD]): that bar is undefined on both columns, and the next two complete bars re-seed the side from scratch. That is a deliberate delta from TA-Lib, which does not check for NaN at all and whose comparisons against one are all false — measured on an interior hole, TA-Lib emits a full column of numbers with no gap in it. The reasoning for resetting is on kernels/fold.ts: a SAR that did not see a bar cannot know whether it flipped, and a wrong side never washes out.

      • In the units of the price: scaling every bar by k scales the stop by k and leaves the trend unchanged; adding c shifts it by c. It does not normalise (contrast rsi).
      • step and maxStep are rates, not bar counts, so they are validated as positive finite numbers rather than by assertPeriod. maxStep below step would cap the factor before its first increment; that is rejected.
      • A flat bar (high === low) is ordinary input — the machine reads both, and neither a division nor a degenerate window arises anywhere in the rule, so there is no zero-denominator case to guard.

      Type Parameters

      • S extends SeriesSchema
      • const Prefix extends string = "psar"

      Parameters

      Returns TimeSeries<
          readonly [
              S[0],
              ValueColumnsForSchema<
                  readonly [
                      S[0],
                      ValueColumnsForSchema<S>,
                      OptionalNumberColumn<Prefix>,
                  ],
              >,
              OptionalNumberColumn<`${Prefix}Trend`>,
          ],
      >