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

    Function swingIndex

    • Swing Index (J. Welles Wilder Jr., New Concepts in Technical Trading Systems, 1978) — one bar's "real" price change, once the open, the high, the low and the previous bar are all taken into account:

      A = |high − prevClose|   B = |low − prevClose|   D = |high − low|

      K = max(A, B)
      R = A0.5·B + 0.25·|prevClose − prevOpen| if A is the largest of A, B, D
      = B0.5·A + 0.25·|prevClose − prevOpen| if B is
      = D + 0.25·|prevClose − prevOpen| if D is

      ${output} = 50 · ( (close − prevClose)
      + 0.5·(close − open)
      + 0.25·(prevClose − prevOpen) ) / R · (K / limit)

      Every term, in words:

      • close − prevClose is the bar's net move, the thing a naive change would report on its own.
      • 0.5·(close − open) adds half of today's own body, so a bar that closed strongly counts for more than one that merely drifted.
      • 0.25·(prevClose − prevOpen) adds a quarter of yesterday's body, which is what makes the index a swing rather than a per-bar reading: it carries a memory of the last bar's conviction.
      • R normalises by a true-range-like quantity that leans on whichever of the three spans dominated the bar, so the reading is comparable across quiet and violent sessions.
      • K / limit scales by how large today's gap against yesterday's close was, relative to the instrument's limit move — which is what bounds the result to −100 … +100.

      Wilder's own reading is that the sign of the swing, and the level a sequence of them accumulates to (accumulativeSwingIndex), identify the real trend under the noise of individual bars.

      T is a fact about the instrument, not about the study: it is the exchange's daily limit move for that futures contract. The library cannot guess it, and every possible default is wrong in a way that does not announce itself:

      • Defaulting to 1 (what several charting packages do) silently rescales the reading by the instrument's price level, so the ±100 bound the study is defined by no longer holds and two symbols' swing indices are no longer comparable — which is the one thing the parameter exists to guarantee.
      • Defaulting to the bar's own range would make K/limit a ratio of two quantities that both move with volatility, i.e. a different indicator wearing this one's name.

      So it is a required option, the way correlation's benchmark is: the one number the caller must supply because only they know it. A caller trading an instrument with no limit move (equities, FX, crypto) passes the scale they want the reading normalised by — the instrument's typical daily range is the usual choice — and the docstring, rather than a default, is what tells them that is what they are choosing.

      A limit of 0 is a division by zero and is rejected, along with negatives and non-finite values.

      • Bar 0 is undefined — every term reads yesterday. Length-preserving, with a warm-up of exactly one row.
      • R === 0undefined. R is zero only when today's high, today's low, yesterday's close and yesterday's open are the same number — a tape that has not moved for two bars. K is zero on exactly those bars too, so the expression is 0/0 however it is grouped, and nothing forces the numerator to zero with it (it reads today's close and open, which a redirected close need not place inside today's range). Pinned by a test.
      • Scale-EQUIVARIANT, and invariant only if limit scales too. This is the one study in the momentum group that is not scale-invariant, and the true statement has to name the parameter: every term of the numerator, of R and of K is a difference of two prices, so multiplying every price by k multiplies all three by kN/R is unchanged, and the reading therefore scales by k through the K/limit factor alone. Scaling limit by k as well leaves the reading unchanged. Both halves are pinned as property tests, and they are what tells this study apart from one that dropped the K/limit factor: that one would be scale-invariant.
      • Shift-invariant. Every term being a difference of two prices, adding a constant to every price changes nothing at all. Pinned.
      • No TA-Lib function, so the oracle is a pandas replication with the analytic first-valid bar asserted, the ±100 bound checked at a limit at least as large as the largest K, and two discriminating separations measured (dropping the K/limit factor, and using the plain-range D branch unconditionally).

      Type Parameters

      • S extends SeriesSchema
      • const Output extends string = "si"

      Parameters

      Returns TimeSeries<
          readonly [S[0], ValueColumnsForSchema<S>, OptionalNumberColumn<Output>],
      >