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

    Function trueStrengthIndex

    • True Strength Index (William Blau) — the bar-over-bar change, smoothed twice, divided by its own magnitude smoothed the same way:

      Δ        = price[i] − price[i−1]
      ${prefix} = 100 · EMA(EMA(Δ, longPeriod), shortPeriod)
      / EMA(EMA(|Δ|, longPeriod), shortPeriod)
      ${prefix}Signal = EMA(${prefix}, signalPeriod)

      Appends two columns, bounded −100 … +100. The numerator is net movement and the denominator is total movement over the same smoothing, so the ratio is "what fraction of the recent motion went one way" — +100 is an unbroken run of up bars, 0 is as much down as up. Double smoothing is what makes it readable: a single-smoothed version of the same ratio is as noisy as the price.

      The line is named ${prefix}, not ${prefix}Line — the trix shape, with the signal keeping the family suffix.

      Blau writes them r and s, and most vendors label them "Long" and "Short". Both bare words are position vocabulary in a financial package — "long" reads as a side, not a length — and every other period option here ends in Period (kPeriod, atrPeriod, signalPeriod, wmaPeriod, …). So they carry the suffix, matching coppock's longPeriod / shortPeriod.

      The order is not symmetric: longPeriod is applied first, to the raw change, and shortPeriod to its output. Swapping them is a real change, not a relabelling — measured on the oracle input, the swapped build sits 15.93 away on a line that spans −28.7 … +80.7 — and the generator asserts that separation.

      No TA-Lib TSI, so the oracle is a pandas replication. What it can borrow from TA-Lib is the smoothing itself: the generator rebuilds an EMA stage on TA-Lib's own SMA seed over the change array and requires it to match talib.EMA bit-exactly (5.6e-16, measured), so the stage arithmetic is vendor-checked even though the assembly is not. The EMAs themselves are pond's — first-sample seed, α = 2/(span+1) — as everywhere else in the package (the macd precedent).

      Some write-ups smooth the percentage change rather than the price change. That is a different indicator; this is Blau's, on the raw difference, which is what makes the ratio scale-invariant without a division per bar.

      The change costs bar 0; each EMA stage then steps over the previous stage's warm-up rather than seeding on it, so on gap-free input the line first lands on bar longPeriod + shortPeriod − 1 (37 at the defaults) and the signal signalPeriod − 1 later (43). Each column is emitted where it is defined rather than both waiting for the slower.

      • A zero denominator → undefined, and there is deliberately NO guard for it. The denominator is an EMA of absolute values, so it is zero only when every change the recursion has consumed is exactly zero — a perfectly flat column. Apply the test rather than the precedent: the numerator is then forced to zero too (|numerator| ≤ denominator by construction), so the division is a literal 0/0, which is already NaN and already a missing cell. An if (den === 0) branch here would change no output — measured, mutating it away fails no test — so it is not written. (Contrast disparityIndex, whose numerator is not forced to zero: there a zero denominator gives ±∞ and the guard is load-bearing.) A test on a constant series pins that both columns come back empty.
      • Bounded −100 … +100 by the same inequality, on any input.
      • Scale-invariant AND shift-invariant: both legs are built from differences, so k·price + c leaves both columns unchanged (pinned). This is the opposite of kst and priceMomentumOscillator, whose rates of change read levels and therefore move under a shift.
      • A leading gap shifts the start; an interior gap costs the bar and the bar after it (the difference reads a predecessor), and the EMAs then skip and carry on — the ema family's rule, so nothing propagates to the end.

      Type Parameters

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

      Parameters

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