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()afterhasValue()):number | undefined - Warm-up: A value from the first candle with non-zero volume; the window is complete after
lengthcandles.
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()afterhasValue()):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()afterhasValue()):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()afterhasValue()):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()afterhasValue()):KlingerOscillatorValuevalue: number | undefinedsignal: 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()afterhasValue()):number - Warm-up: Returns 50 on the first candle and a partial-window value until
period + 1candles.
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()afterhasValue()):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()afterhasValue()):PercentageVolumeOscillatorValuevalue: number | undefinedsignal: number | undefinedhistogram: 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()afterhasValue()):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()afterhasValue()):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()afterhasValue()):VolumeProfileValue | undefinedpocLevel: number | undefinedpocVolume: number | undefinedvalueAreaHigh: number | undefinedvalueAreaLow: number | undefinedprofileData: VolumeProfileRow[] | undefinedtotalVolume: number | undefined
VolumeProfileOptionsis{ numberOfBars: number; rowSize: number; valueAreaPercent: number }.VolumeProfileRowis{ priceLevel: number; upVolume: number; downVolume: number; totalVolume: number; isValueArea: boolean; isPOC: boolean }.- Warm-up: Available from the first candle; representative once
numberOfBarscandles 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);
});