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

    Function highLowBands

    • High Low Bands — a smoothed median price with bands a fixed percentage either side of it:

      middle = MA((high + low) / 2, period)      ${prefix}Middle
      upper = middle × (1 + percent/100) ${prefix}Upper
      lower = middle × (1 − percent/100) ${prefix}Lower

      Appends three columns. Reads high and low — never the close, which is what separates it from envelope (a percent band around a smoothed close) and from starcBands (a volatility band around one).

      The arithmetic is envelope's applied to a different centre. With medianPrice on the series, this study is envelope({ column: 'medianPrice', maType, percent }), and a test pins the two equal bar-for-bar rather than leaving that in prose.

      The one place the identity can part company is maType: 'sma' over a series with missing cells: envelope reads a column and takes the K2 engine's column door (rows, not contributors), while this study smooths a derived array and takes the array door (period finite values). At the default 'trima', and for every type but sma/ema, both routes are the same call and the identity is bit-exact.

      It ships anyway, for the reason this package ships vocabulary at all: the composition needs a scratch column on the series (and a caller who does not want medianPrice in their schema has to drop it again), the corpus names the study (assessment §6.2), and "High Low Bands" on a chart legend should not require the reader to reconstruct which column the envelope was pointed at. The step-0 finding is recorded rather than hidden: nothing new is computed here.

      The half-width option is percent — the same number, in the same units (percent of the centre), as envelope's percent, and the same spelling on purpose. ChartIQ draws this indicator with the label "shift"; the builder first followed that label, and the integrator renamed it: a package that spells one knob two ways is a footgun, and a consumer who has written envelope({ percent }) should be able to write highLowBands({ percent }) without looking it up. (The type / maType split is different in kind — those name different roles.)

      The corpus entry names only "MA of median price × (1 ± shift%)" and does not pin the average. The triangular moving average is the one this study is conventionally drawn with — it double-smooths, which is the point of a band you want to read as a slow envelope rather than a fast one — so 'trima' is the default. The whole shared MaType menu is available; maType (not type) because the average is an ingredient rather than the output.

      TA-Lib has no High Low Bands, so the oracle is a pandas replication with the analytic first valid bar asserted and the identity against envelope-over-medianPrice checked on the TypeScript side, where the two can be compared as the same expression rather than through a fixture.

      • All three columns start together, at the chosen average's own first bar over the derived median-price array. trima at period 10 lands at bar 9; the composed types land later (see movingAverageValues). The median price is a derived array, so it goes through the K2 engine's ARRAY door — every window type, sma included, waits for period finite values, so a gap blanks every window containing it rather than averaging a short window.
      • Multiplicative, not additive: the bands are a percentage of the centre, so the channel is wider at higher prices. That makes the study linear in price (scaling scales all three columns) but not shift-equivariant — adding a constant moves the centre by it and the bands by more. Both pinned by property tests, and it is the honest consequence of a percent band (starcBands, an ATR band, is the translation-invariant alternative).
      • A negative centre inverts the bands. middle × (1 + percent/100) is below middle when the centre is negative — reachable only by redirecting high/low at columns that can go negative. Nothing reorders them; envelope has the same property, and clamping would hide an input problem rather than fix one.
      • No division, so no zero-denominator case: a flat stretch gives three parallel lines a fixed percentage apart.

      Type Parameters

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

      Parameters

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