Volatility, bands and ranges

True range, bands, channels and choppiness measures. See the indicator reference for how to read a signature, and Indicators for the construction and guarding rules.

BBW

Bollinger BandWidth as TradingView plots it: the distance between the bands in percent of their basis, (upper − lower) / basis × 100 (4.5 for bands 4.5% apart).

new BBW(sourceIndicator: Indicator<number>, period: number, stdDevMultiplier: number = 2)
Parameter Type Default Meaning
sourceIndicator Indicator<number> required The number stream.
period number required Bollinger length.
stdDevMultiplier number 2 Standard deviations between the basis and each band (2 by default).
  • Input: A number stream whose values are never undefined.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value on candle period.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new BBW(candles.close, 20);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value === undefined) return;
  manager.debugLog('BBW', value);
});

BBWP

Bollinger BandWidth Percentile, The_Caretaker's: the share, in percent, of the previous lookback BBW values (fewer at first) lower than or equal to the current one.

new BBWP(sourceIndicator: Indicator<number>, period: number, lookback: number)
Parameter Type Default Meaning
sourceIndicator Indicator<number> required The number stream.
period number required Bollinger length.
lookback number required How many BBW values to rank against.
  • Input: A number stream whose values are never undefined.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value on candle period + 2.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new BBWP(candles.close, 13, 252);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value === undefined) return;
  manager.debugLog('BBWP', value);
});

Bollinger

Bollinger bands: the maPeriod SMA (mean) plus and minus stdDevMultiplier standard deviations.

new Bollinger(sourceIndicator: Indicator<number>, maPeriod: number = 20, stdDevMultiplier: number = 2)
Parameter Type Default Meaning
sourceIndicator Indicator<number> required The number stream (usually closes).
maPeriod number 20 Window length.
stdDevMultiplier number 2 Band width in standard deviations.
  • Input: A number stream whose values are never undefined (candles.close).
  • Value (getValue() after hasValue()): BollingerValue
    • upper: number | undefined
    • mean: number | undefined
    • lower: number | undefined
  • Warm-up: Fields are undefined until maPeriod candles have been seen.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new Bollinger(candles.close, 20, 2);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value.upper === undefined || value.lower === undefined || value.mean === undefined) return;
  manager.debugLog('upper', value.upper, 'mean', value.mean, 'lower', value.lower);
});

Chop

Choppiness index: 100 × log10(Σ TR / (highest high − lowest low)) / log10(period); high values mean a sideways market.

new Chop(highIndicator: Indicator<number | undefined>, lowIndicator: Indicator<number | undefined>, trIndicator: Indicator<number | undefined>, period: number)
Parameter Type Default Meaning
highIndicator Indicator<number | undefined> required The high stream (candles.high).
lowIndicator Indicator<number | undefined> required The low stream (candles.low).
trIndicator Indicator<number | undefined> required The true range (new TR(candles)).
period number required Window length.
  • Input: Three number streams: highs, lows and true range.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value on candle period; not finite when the window's highest high equals its lowest low.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new Chop(candles.high, candles.low, new TR(candles), 14);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value === undefined || !Number.isFinite(value)) return;
  manager.debugLog('chop', value);
});

Choppy

Counts monotonic runs among the last six closes: type rates the current run ('none', 'weak', 'medium', 'strong') and line counts trending candles among the last ten.

new Choppy(candleIndicator: Indicator<Candle>)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
  • Input: The candle series.
  • Value (getValue() after hasValue()): ChoppyValue
    • type: ChoppyType
    • line: number
  • ChoppyType is 'none' | 'weak' | 'medium' | 'strong'.
  • Warm-up: type is 'none' until six candles have been seen; line fills over ten candles.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new Choppy(candles);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  manager.debugLog('run', value.type, 'trending candles out of 10', value.line);
});

DC

Donchian channel MIDLINE: (highest high + lowest low) / 2 over extremePeriod candles, current included. For the upper and lower channel lines use Extreme.

new DC(candleIndicator: Indicator<Candle>, extremePeriod: number)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
extremePeriod number required Window length, current candle included.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number
  • Warm-up: A number from the first candle (partial window until extremePeriod candles).
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new DC(candles, 20);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  manager.debugLog('Donchian midline', value);
});

FindMarketBottom

Williams VIX Fix bottom finder: wvf = 100 × (highest close over 22 − low) / highest close, with Bollinger and percentile ranges; alert is true when wvf spikes above them.

new FindMarketBottom(candleIndicator: ICandleIndicator, bollingerLength: number = 20, bollingerMult: number = 2.0, percentileLookback: number = 50, highPercentile: number = 0.85, lowPercentile: number = 1.01)
Parameter Type Default Meaning
candleIndicator ICandleIndicator required The candle series.
bollingerLength number 20 Bollinger length on wvf.
bollingerMult number 2.0 Bollinger multiplier.
percentileLookback number 50 Look-back for the percentile range.
highPercentile number 0.85 Upper range factor (0.85 = 85% of the highest wvf).
lowPercentile number 1.01 Lower range factor.
  • Input: The candle series.
  • Value (getValue() after hasValue()): FindMarketBottomValue
    • wvf: number | undefined
    • upperBand: number | undefined
    • midLine: number | undefined
    • lowerBand: number | undefined
    • rangeHigh: number | undefined
    • rangeLow: number | undefined
    • alert: boolean
  • Warm-up: alert is always a boolean; band fields are undefined until bollingerLength and percentileLookback values exist (about 50 candles with the defaults).
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new FindMarketBottom(candles);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value.alert) manager.debugLog('possible bottom, wvf', value.wvf);
});

KeltnerChannels

Keltner channels: an EMA of the close (middle) plus and minus multiplier ATRs.

new KeltnerChannels(candleIndicator: ICandleIndicator, period: number = 20, multiplier: number = 2, atrPeriod: number = 10)
Parameter Type Default Meaning
candleIndicator ICandleIndicator required The candle series.
period number 20 EMA length.
multiplier number 2 Channel width in ATRs.
atrPeriod number 10 ATR length.
  • Input: The candle series.
  • Value (getValue() after hasValue()): { upper: number | undefined; middle: number | undefined; lower: number | undefined; }
    • upper: number | undefined
    • middle: number | undefined
    • lower: number | undefined
  • Warm-up: Fields are undefined until both the EMA (candle period) and the ATR (candle atrPeriod + 1) are ready.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new KeltnerChannels(candles, 20, 2, 10);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value.upper === undefined || value.lower === undefined) return;
  manager.debugLog('upper', value.upper, 'lower', value.lower);
});

TR

True range: max(high − low, |high − previous close|, |low − previous close|). Smooth it with RMA for an ATR (TradingView's ta.atr).

new TR(candleIndicator: Indicator<Candle>, handleNa: boolean = true)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
handleNa boolean true Count high − low on the first candle, which has no previous close (true by default, as TradingView's ATR does); false leaves that candle undefined, as its DMI does.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: A value from the first candle; from the second with handleNa set to false.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new TR(candles);

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value === undefined) return;
  manager.debugLog('true range', value);
});
Browse the documentation