Volume

Indicators that weigh price by traded volume. See the indicator reference for how to read a signature, and Indicators for the construction and guarding rules.

ChaikinMoneyFlow

Chaikin money flow: Σ(money-flow volume) / Σ(volume) over length, between −1 and 1.

new ChaikinMoneyFlow(candleIndicator: Indicator<Candle>, length: number = 20)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
length number 20 Window length.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: A value from the first candle with non-zero volume; the window is complete after length candles.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new ChaikinMoneyFlow(candles, 20);

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

ChaikinOscillator

Fast EMA minus slow EMA of cumulative accumulation/distribution.

new ChaikinOscillator(candleIndicator: Indicator<Candle>, fastLength: number = 3, slowLength: number = 10)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
fastLength number 3 Fast EMA length; integer from 1 to 5,000.
slowLength number 10 Slow EMA length; integer from 1 to 5,000.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value after the longer EMA has enough valid samples (10 candles with defaults). The Smart Chart preloads at least 2,000 candles and 30 times the longest length, capped at 5,000 candles.
  • A flat high/low contributes zero. A missing contribution leaves the cumulative state intact and produces no value on that candle; the next valid candle resumes it.
  • Restart precision was measured against the full-history reference on BTCUSDT 1h, BTCUSDT 1D and ETHUSDT 4h. The 2,000-candle floor also covers cancellation round-off from different cumulative origins.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new ChaikinOscillator(candles, 3, 10);

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

EaseOfMovement

SMA of midpoint change multiplied by the candle range and a divisor, divided by volume.

new EaseOfMovement(candleIndicator: Indicator<Candle>, length: number = 14, divisor: number = 10000)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
length number 14 SMA length; integer from 1 to 5,000.
divisor number 10000 Volume scaling factor; integer from 1 to 1,000,000,000,000. It is not a lookback length.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value after length valid midpoint changes (15 candles with defaults). The Smart Chart preloads 30 times length, with a 200-candle floor.
  • A zero or missing volume gives a missing movement sample; SMA skips that sample instead of treating it as zero.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new EaseOfMovement(candles, 14, 10000);

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

EldersForceIndex

EMA of close-to-close price change multiplied by volume.

new EldersForceIndex(candleIndicator: Indicator<Candle>, length: number = 13)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
length number 13 EMA length; integer from 1 to 5,000.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value after length valid close changes (14 candles with defaults). The Smart Chart preloads 30 times length, with a 200-candle floor, capped at 5,000 candles.
  • EMA is seeded with an SMA of valid force samples. Zero volume contributes zero; missing volume produces no value for that candle and preserves the EMA state.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new EldersForceIndex(candles, 13);

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

KlingerOscillator

EMA 34 minus EMA 55 of signed volume, with an EMA 13 signal.

new KlingerOscillator(candleIndicator: Indicator<Candle>)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
  • Input: The candle series.
  • Value (getValue() after hasValue()): KlingerOscillatorValue
    • value: number | undefined
    • signal: number | undefined
  • Warm-up: Oscillator after 55 valid volume samples; signal after 67. The Smart Chart preloads 1,000 candles, measured against full-history references.
  • These three periods are fixed by the built-in. Volume is positive when hlc3 rises or is unchanged, negative otherwise; the first comparison takes negative volume.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new KlingerOscillator(candles);

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

MFI

Money flow index: a volume-weighted RSI of the typical price, between 0 and 100.

new MFI(candleIndicator: Indicator<Candle>, period: number = 14)
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
period number 14 Window length.
  • Input: The candle series.
  • Value (getValue() after hasValue()): number
  • Warm-up: Returns 50 on the first candle and a partial-window value until period + 1 candles.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new MFI(candles, 14);

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

OnBalanceVolume

On-balance volume: a running total that adds the candle volume when the price rises and subtracts it when it falls.

new OnBalanceVolume(priceIndicator: Indicator<number | undefined>, volumeIndicator: Indicator<number>)
Parameter Type Default Meaning
priceIndicator Indicator<number | undefined> required The price stream (candles.close).
volumeIndicator Indicator<number> required The volume stream (candles.volume).
  • Input: Two number streams: price and volume.
  • Value (getValue() after hasValue()): number
  • Warm-up: A number (starting at 0) from the first candle.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new OnBalanceVolume(candles.close, candles.volume);

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

PercentageVolumeOscillator

Percentage difference between fast and slow volume averages, with a signal average and a histogram.

new PercentageVolumeOscillator(candleIndicator: Indicator<Candle>, fastLength: number = 12, slowLength: number = 26, signalLength: number = 9, maType: string = 'EMA', signalMaType: string = 'EMA')
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
fastLength number 12 Fast average length; integer from 1 to 5,000.
slowLength number 26 Slow average length; integer from 1 to 5,000.
signalLength number 9 Signal average length; integer from 1 to 5,000.
maType string 'EMA' Oscillator average type: EMA or SMA.
signalMaType string 'EMA' Signal average type, chosen independently: EMA or SMA.
  • Input: The candle series.
  • Value (getValue() after hasValue()): PercentageVolumeOscillatorValue
    • value: number | undefined
    • signal: number | undefined
    • histogram: number | undefined
  • Warm-up: With defaults, oscillator after 26 valid volume samples; signal and histogram after 34. The Smart Chart preloads 30 times the longest length, with a 200-candle floor, capped at 5,000 candles.
  • Missing volume is skipped by the averages. A zero slow average produces no oscillator value.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new PercentageVolumeOscillator(candles, 12, 26, 9, 'EMA', 'EMA');

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

PMAR

Price-to-moving-average ratio: price / VWMA(price, volume, period).

new PMAR(priceIndicator: Indicator<number>, volumeIndicator: Indicator<number>, period: number)
Parameter Type Default Meaning
priceIndicator Indicator<number> required The price stream.
volumeIndicator Indicator<number> required The volume stream.
period number required VWMA length.
  • Input: Two number streams: price and volume.
  • Value (getValue() after hasValue()): number
  • Warm-up: A number from the first candle (partial VWMA window until period).
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new PMAR(candles.close, candles.volume, 20);

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

PMARP

PMAR percentile, The_Caretaker's: the share, in percent, of the previous lookback PMAR values (fewer at first) not above the current one.

new PMARP(priceIndicator: Indicator<number>, volumeIndicator: Indicator<number>, period: number, lookback: number)
Parameter Type Default Meaning
priceIndicator Indicator<number> required The price stream.
volumeIndicator Indicator<number> required The volume stream.
period number required VWMA length.
lookback number required How many PMAR values to rank against.
  • Input: Two number streams: price and volume.
  • Value (getValue() after hasValue()): number | undefined
  • Warm-up: First value on candle period + 1.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new PMARP(candles.close, candles.volume, 20, 350);

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

VolumeProfile

Volume profile over the last numberOfBars candles: volume per price row, point of control and value area.

new VolumeProfile(candleIndicator: Indicator<Candle>, options: VolumeProfileOptions = { numberOfBars: 150, rowSize: 24, valueAreaPercent: 70 })
Parameter Type Default Meaning
candleIndicator Indicator<Candle> required The candle series.
options VolumeProfileOptions { numberOfBars: 150, rowSize: 24, valueAreaPercent: 70 } { numberOfBars: 1 to 500, rowSize: price rows, valueAreaPercent: share of volume in the value area }. All three are required when you pass the object.
  • Input: The candle series.
  • Value (getValue() after hasValue()): VolumeProfileValue | undefined
    • pocLevel: number | undefined
    • pocVolume: number | undefined
    • valueAreaHigh: number | undefined
    • valueAreaLow: number | undefined
    • profileData: VolumeProfileRow[] | undefined
    • totalVolume: number | undefined
  • VolumeProfileOptions is { numberOfBars: number; rowSize: number; valueAreaPercent: number }.
  • VolumeProfileRow is { priceLevel: number; upVolume: number; downVolume: number; totalVolume: number; isValueArea: boolean; isPOC: boolean }.
  • Warm-up: Available from the first candle; representative once numberOfBars candles are in the window.
const symbol = 'BTC';
const candles = manager.getIntervalData(symbol, 60);
const indicator = new VolumeProfile(candles, { numberOfBars: 100, rowSize: 24, valueAreaPercent: 70 });

manager.onIntervalCandle(symbol, 60, () => {
  if (!indicator.hasValue()) return;
  const value = indicator.getValue();
  if (value === undefined || value.pocLevel === undefined) return;
  manager.debugLog('POC', value.pocLevel, 'value area', value.valueAreaLow, value.valueAreaHigh);
});
Browse the documentation