Skip to content

Developers

Indicator SDK

The full API of the built-in technical indicators: how to call each one from an algorithm, its settings and their limits, what it gives back, and the errors a bad setting raises. To write your own, see Custom indicators. For what each indicator measures and how it is computed, see the indicator catalogue; for what indicators can and cannot tell you, Indicators explained.

Each built-in indicator is a function named by its key. Called on its own it uses your session’s instrument and timeframe. Called on a timeframe or an instrument, it uses that one:

function onIntervalClose() {
const fast = sma(20);
const hourlyRsi = H1.rsi(14);
const gbpMacd = INSTRUMENTS["GBP_USD:OANDA"].macd(12, 26, 9);
const gbpDailyAtr = INSTRUMENTS["GBP_USD:OANDA"].D1.atr(14);
log(fast, hourlyRsi, gbpMacd[0], gbpDailyAtr);
}
  • Values update when a bar closes. During onTick you get the value at the last close.
  • They are warmed up. Each indicator runs over bars from before your start date, so it has a value from the first bar of the run.
  • Each set of settings is one indicator. sma(20) and sma(50) are two; calling sma(20) in several places costs the same as calling it once. An algorithm can use at most 10.
  • Settings are checked when the run starts. A setting out of range stops the run with the indicator’s message, such as “SMA periods must be an integer” or “SMA maximum periods is 100”.
  • Call each indicator with literal settings or externals, so Cloud9Trader can find them in your code before the run starts.

An indicator that draws one line gives a number. One that draws several gives a list, in the order the table shows: bollinger(20, 2) gives [lower, upper, middle]. Some give one number without their optional signal setting and a list with it. The Ichimoku Cloud’s last two items are [low, high] pairs.

The call forms below are copied from the SDK’s type definitions. Each key links to its full entry in the reference.

Key Call What you get
adl adl(): number Accumulation Distribution Line.
adx adx(periods: number): [number | null, number, number] Average Directional Index: [ADX, +DI, -DI], 0 to 100. ADX is null until it has warmed up, after the DIs.
aroon aroon(periods: number): number[] Aroon: [Aroon Up, Aroon Down], 0 to 100.
aroonOscillator aroonOscillator(periods: number): number Aroon Oscillator: Aroon Up minus Aroon Down.
atr atr(periods: number): number Average True Range, Wilder-smoothed.
awesomeOscillator awesomeOscillator(fastPeriods: number, slowPeriods: number): number Awesome Oscillator in pips: SMA of the bar midpoint, fast less slow.
bollinger bollinger(periods: number, deviations: number): number[] Bollinger Bands: [lower, upper, middle].
bollingerB bollingerB(periods: number, deviations: number): number Bollinger %B: where the close sits between the bands, 0 at the lower band and 1 at the upper.
bollingerBandwidth bollingerBandwidth(periods: number, deviations: number): number Bollinger Bandwidth: the band width as a percentage of the middle band.
camarillaPivot camarillaPivot(): number[] Camarilla Pivot Points from the previous UTC day: [R4, R3, R2, R1, S1, S2, S3, S4].
cci cci(periods: number, constant: number, overboughtLine?: number, oversoldLine?: number): number Commodity Channel Index. The two lines only change the chart.
chaikinOscillator chaikinOscillator(fastPeriods: number, slowPeriods: number): number Chaikin Oscillator: fast EMA of the Accumulation Distribution Line less slow.
chandelierExit chandelierExit(periods: number, multiplier: number): number[] Chandelier Exit: [short exit, long exit].
cmf cmf(periods: number): number Chaikin Money Flow.
cmo cmo(periods: number): number
cmo(periods: number, signalPeriods: number): number[]
Chande Momentum Oscillator, or [oscillator, signal] with signalPeriods.
cog cog(periods: number, signalPeriods?: number): number[] Center of Gravity Oscillator: [oscillator], or [oscillator, signal] with signalPeriods.
coppock coppock(firstRoCPeriods: number, wmaPeriods: number, secondRoCPeriods: number): number Coppock Curve.
dailyPivot dailyPivot(): number[] Daily Pivot: [R3, R2, R1, pivot, S1, S2, S3].
dema dema(periods: number): number Double Exponential Moving Average: 2 × EMA − EMA of the EMA.
dpo dpo(periods: number): number[] Detrended Price Oscillator: [DPO, SMA].
elderBBPower elderBBPower(periods: number): number[] Elder Bull/Bear Power: [bull power, bear power].
ema ema(periods: number): number Exponential Moving Average.
emaEnvelope emaEnvelope(periods: number, envelope: number): number[] Exponential Moving Average Envelope: [lower, upper, EMA]. envelope is a percentage.
emv emv(periods: number): number Ease of Movement.
fibonacciPivot fibonacciPivot(): number[] Fibonacci Pivot Points from the previous UTC day: [R3, R2, R1, pivot, S1, S2, S3].
fisherTransform fisherTransform(periods: number): number[] Fisher Transform: [Fisher, signal].
forceIndex forceIndex(periods: number): number Force Index.
gapo gapo(periods: number): number Gopalakrishnan Range Index.
historicalVolatility historicalVolatility(periods: number, tradingDaysPerYear: number): number Historical Volatility: annualised standard deviation of log returns, in percent.
hullMa hullMa(periods: number): number Hull Moving Average, from weighted moving averages.
ichimokuCloud ichimokuCloud(conversionLinePeriods: number, baseLinePeriods: number, leadingSpanPeriods: number, laggingSpanPeriods: number): Array<number | [number, number]> Ichimoku Cloud: [conversion line, base line, leading span A, leading span B, lagging span, green cloud, red cloud]. The clouds are [low, high] pairs.
keltnerChannels keltnerChannels(emaPeriods: number, atrPeriods: number, atrMultiplier: number): number[] Keltner Channels: [lower, upper, EMA].
kst kst(firstROCPeriods: number, secondROCPeriods: number, thirdROCPeriods: number, fourthROCPeriods: number, firstSMAPeriods: number, secondSMAPeriods: number, thirdSMAPeriods: number, fourthSMAPeriods: number): number
kst(firstROCPeriods: number, secondROCPeriods: number, thirdROCPeriods: number, fourthROCPeriods: number, firstSMAPeriods: number, secondSMAPeriods: number, thirdSMAPeriods: number, fourthSMAPeriods: number, signalSMA: number): number[]
Know Sure Thing, or [KST, signal] with signalSMA.
linearRegression linearRegression(periods: number): number Linear Regression: the end point of the least-squares line through the closes.
macd macd(fastEMAPeriods: number, slowEMAPeriods: number): number
macd(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[]
MACD in pips, or [MACD, signal, histogram] with signalEMAPeriods.
macdHistogram macdHistogram(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number MACD Histogram in pips: MACD minus its signal line.
massIndex massIndex(emaPeriods: number, summationPeriods: number): number Mass Index.
mfi mfi(periods: number): number Money Flow Index, 0 to 100.
momentum momentum(periods: number): number Momentum in pips: the close less the close periods bars ago.
obv obv(): number On Balance Volume.
parabolicSar parabolicSar(step: number, maximum: number): number Parabolic SAR: the stop for this bar; below the close in a rise, above it in a fall.
pgo pgo(periods: number): number Pretty Good Oscillator.
pmo pmo(firstEMAPeriods: number, secondEMAPeriods: number): number
pmo(firstEMAPeriods: number, secondEMAPeriods: number, signalEMAPeriods: number): number[]
Price Momentum Oscillator, or [PMO, signal] with signalEMAPeriods.
ppo ppo(fastEMAPeriods: number, slowEMAPeriods: number): number
ppo(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[]
Percentage Price Oscillator, or [histogram, signal, PPO] with signalEMAPeriods.
priceChannels priceChannels(periods: number): number[] Price Channels: [lower, upper, middle].
pvo pvo(fastEMAPeriods: number, slowEMAPeriods: number): number
pvo(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[]
Percentage Volume Oscillator, or [PVO, signal, histogram] with signalEMAPeriods.
qStick qStick(periods: number): number QStick in pips.
roc roc(periods: number): number Rate of Change, in percent.
rsi rsi(periods: number): number Relative Strength Index, Wilder-smoothed, 0 to 100.
sma sma(periods: number): number Simple Moving Average.
smaEnvelope smaEnvelope(periods: number, envelope: number): number[] Simple Moving Average Envelope: [lower, upper, SMA]. envelope is a percentage.
smma smma(periods: number): number Smoothed (Wilder’s) Moving Average, also called RMA.
standardDeviation standardDeviation(periods: number): number Standard deviation of closes, in pips.
stochRsi stochRsi(periods: number): number Stochastic RSI, 0 to 1.
stochasticOscillator stochasticOscillator(periods: number, smaPeriods: number): number[] Stochastic Oscillator: [%K, %D], 0 to 100.
supertrend supertrend(periods: number, multiplier: number): number Supertrend: below the close in a rise, above it in a fall.
tema tema(periods: number): number Triple Exponential Moving Average.
trix trix(periods: number): number
trix(periods: number, signalPeriods: number): number[]
TRIX in percent, or [TRIX, signal] with signalPeriods.
tsi tsi(firstPeriods: number, secondPeriods: number): number
tsi(firstPeriods: number, secondPeriods: number, signalPeriods: number): number[]
True Strength Index, or [TSI, signal] with signalPeriods.
uo uo(shortPeriods: number, mediumPeriods: number, longPeriods: number): number Ultimate Oscillator, 0 to 100.
volume volume(periods?: number): number[] Volume: [the bar’s volume]. periods is ignored.
vtx vtx(periods: number): number[] Vortex Indicator: [-VI, +VI].
vwap vwap(): number Volume Weighted Average Price, reset at 00:00 UTC each day.
vwma vwma(periods: number): number Volume Weighted Moving Average of closes.
williamsR williamsR(periods: number): number Williams %R, -100 to 0.
woodiePivot woodiePivot(): number[] Woodie’s Pivot Points from the previous UTC day: [R2, R1, pivot, S1, S2].
wma wma(periods: number): number Weighted Moving Average.

Every built-in indicator, in the table’s order. Each entry is generated from the indicator’s own code, so the settings, their limits and the error messages are the ones the platform checks. Where a message shows {fieldName}, the run’s message names the setting, such as MACD fastEMAPeriods must be an integer.

adl(): number;

Marc Chaikin’s running total of money flow volume. Each bar’s volume is counted as buying or selling in proportion to where the close sits within the bar’s range.

money flow multiplier = ((CLOSE - LOW) - (HIGH - CLOSE)) / (HIGH - LOW) from -1 to +1
money flow volume = multiplier * VOLUME
ADL = previous ADL + money flow volume

A bar with no range (HIGH = LOW) adds nothing. The line starts from zero at the first bar run, so its level depends on where the run starts; only its direction and divergences mean anything.

Parameters: none.

Returns: one number, drawn on its own axis.

What it measures, its formula and a chart

Average Directional Index (ADX), with the Directional Indicators +DI and −DI

Section titled “Average Directional Index (ADX), with the Directional Indicators +DI and −DI”
adx(periods: number): [number | null, number, number];

J. Welles Wilder’s measure of trend strength, from New Concepts in Technical Trading Systems (1978). +DI and −DI say which way the market has been pushing; ADX says how hard, whichever way that is.

up move = HIGH − previous HIGH
down move = previous LOW − LOW
+DM = up move if it is positive and larger than the down move, else 0
−DM = down move if it is positive and larger than the up move, else 0
TR = max(HIGH − LOW, |HIGH − previous CLOSE|, |LOW − previous CLOSE|)
+DI = 100 × Wilder(+DM, periods) / Wilder(TR, periods)
−DI = 100 × Wilder(−DM, periods) / Wilder(TR, periods)
DX = 100 × |+DI − −DI| / (+DI + −DI)
ADX = Wilder(DX, periods)

Wilder’s smoothing starts from the mean of the first periods values and then takes (previous × (periods − 1) + value) / periods, as for the Average True Range. Wilder smoothed running sums rather than means, which gives the same +DI and −DI because both sides of each ratio are smoothed alike. With no movement at all the DIs and DX are 0, as TA-Lib gives.

Parameters: periods, 1 to 100 (14 is standard).

Returns: [ADX, +DI, −DI], each 0 to 100, on their own axis. The DIs have no value for the first periods bars, and ADX for the first 2 × periods − 1.

Errors: a setting that fails a check stops the run with one of these messages:

  • ADX periods must be a number
  • ADX periods must be an integer
  • ADX maximum periods is 100
  • ADX periods must be greater than zero

What it measures, its formula and a chart

aroon(periods: number): number[];

Tushar Chande’s measure of how recently price made its high and its low. Over a lookback of periods bars (plus the bar that just closed, so periods + 1 bars in all):

Aroon Up = 100 * (periods - bars since the highest HIGH) / periods
Aroon Down = 100 * (periods - bars since the lowest LOW) / periods

A high made on the bar that just closed gives 100; one made periods bars ago gives 0. Where the extreme was reached more than once, the most recent counts. This matches StockCharts and TradingView.

Parameters: periods, 1 to 100 (25 is standard).

Returns: [Aroon Up, Aroon Down], 0 to 100, on their own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Aroon periods must be a number
  • Aroon periods must be an integer
  • Aroon maximum periods is 100
  • Aroon periods must be greater than zero

What it measures, its formula and a chart

aroonOscillator(periods: number): number;

Aroon Up minus Aroon Down, from -100 to +100.

Parameters: periods, 1 to 100 (25 is standard).

Returns: one number, drawn as an area on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Aroon Oscillator periods must be a number
  • Aroon Oscillator periods must be an integer
  • Aroon Oscillator maximum periods is 100
  • Aroon Oscillator periods must be greater than zero

What it measures, its formula and a chart

atr(periods: number): number;

J. Welles Wilder’s measure of volatility: the average of the true range, which widens a bar’s range to include any gap from the previous close.

true range = max(HIGH - LOW, |HIGH - previous CLOSE|, |LOW - previous CLOSE|)
first ATR = mean of the first `periods` true ranges
ATR = (previous ATR * (periods - 1) + true range) / periods

This is Wilder’s smoothing, an EMA with k = 1/periods, as StockCharts and Wilder’s book give it. Some platforms offer an SMA or a standard EMA of the true range instead, which gives different values. The first bar run has no previous close and only sets one.

Parameters: periods, 1 to 100 (14 is standard).

Returns: one number, on its own axis. No value for the first periods bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • Average True Range periods must be a number
  • Average True Range periods must be an integer
  • Average True Range maximum periods is 100
  • Average True Range periods must be greater than zero

What it measures, its formula and a chart

awesomeOscillator(fastPeriods: number, slowPeriods: number): number;

Bill Williams’ momentum measure: a fast simple moving average of each bar’s midpoint less a slow one, in pips, drawn as columns.

median = (HIGH + LOW) / 2
AO = (SMA(median, fastPeriods) − SMA(median, slowPeriods)) / PIP_SIZE

Williams fixed the lengths at 5 and 34; they are settings here, with those defaults. The value is in pips, as MACD’s is, so one threshold reads the same on every currency pair.

Parameters: fastPeriods (5) and slowPeriods (34), 1 to 200, fast below slow.

Returns: one number, in pips, on its own axis, drawn as columns. No value for the first slowPeriods − 1 bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • Awesome Oscillator {name} must be a number
  • Awesome Oscillator {name} must be an integer
  • Awesome Oscillator maximum {name} is 200
  • Awesome Oscillator {name} must be at least 1
  • Awesome Oscillator slowPeriods must be greater than fastPeriods

What it measures, its formula and a chart

bollinger(periods: number, deviations: number): number[];

John Bollinger’s volatility bands: a simple moving average of closes with bands a number of standard deviations above and below it.

middle = SMA(periods)
sigma = population standard deviation of the same `periods` closes
upper = middle + deviations * sigma
lower = middle - deviations * sigma

Bollinger specifies the population standard deviation (dividing by periods, not periods - 1), which is what this uses; some packages use the sample form and draw slightly wider bands.

Parameters: periods, 1 to 100; deviations, a positive number (2 is standard).

Returns: [lower, upper, middle], drawn as a shaded band with a dashed middle line.

Errors: a setting that fails a check stops the run with one of these messages:

  • Bollinger Bands periods must be a number
  • Bollinger Bands periods must be an integer
  • Bollinger Bands maximum periods is 100
  • Bollinger Bands periods must be greater than zero
  • Bollinger Bands deviation multiplier must be a number
  • Bollinger Bands deviation multiplier must be greater than zero

What it measures, its formula and a chart

bollingerB(periods: number, deviations: number): number;

Where the close sits relative to the Bollinger Bands.

%B = (CLOSE - lower band) / (upper band - lower band)

1 is the upper band, 0 the lower band and 0.5 the middle line; it goes above 1 or below 0 when the close is outside the bands. Where the bands have no width (every close equal) there is no value.

Parameters: periods, 1 to 100; deviations, a positive number (20 and 2 are standard).

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Bollinger Band %B periods must be a number
  • Bollinger Band %B periods must be an integer
  • Bollinger Band %B maximum periods is 100
  • Bollinger Band %B periods must be greater than zero
  • Bollinger Band %B deviation multiplier must be a number
  • Bollinger Band %B deviation multiplier must be greater than zero

What it measures, its formula and a chart

bollingerBandwidth(periods: number, deviations: number): number;

The width of the Bollinger Bands as a percentage of the middle band.

Bandwidth = (upper band - lower band) / middle band * 100
= 2 * deviations * sigma / SMA * 100

Parameters: periods, 1 to 100; deviations, a positive number.

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Bollinger Bandwidth periods must be a number
  • Bollinger Bandwidth periods must be an integer
  • Bollinger Bandwidth maximum periods is 100
  • Bollinger Bandwidth periods must be greater than zero
  • Bollinger Bandwidth deviation multiplier must be a number
  • Bollinger Bandwidth deviation multiplier must be greater than zero

What it measures, its formula and a chart

camarillaPivot(): number[];

Nick Scott’s Camarilla levels: four resistance and four support levels set close around the previous trading day’s close, at fractions of its range scaled by 1.1.

R4 = CLOSE + (HIGH − LOW) × 1.1 / 2 S4 = CLOSE − (HIGH − LOW) × 1.1 / 2 of the previous day
R3 = CLOSE + (HIGH − LOW) × 1.1 / 4 S3 = CLOSE − (HIGH − LOW) × 1.1 / 4
R2 = CLOSE + (HIGH − LOW) × 1.1 / 6 S2 = CLOSE − (HIGH − LOW) × 1.1 / 6
R1 = CLOSE + (HIGH − LOW) × 1.1 / 12 S1 = CLOSE − (HIGH − LOW) × 1.1 / 12

Days are UTC days, as for dailyPivot: the levels shown on Sunday come from Friday’s bar, and Monday’s from Friday and the Sunday session together (Friday’s high and low widened by Sunday’s, and Sunday’s close).

Parameters: none.

Returns: [R4, R3, R2, R1, S1, S2, S3, S4], eight lines on the price chart.

What it measures, its formula and a chart

cci(periods: number, constant: number, overboughtLine?: number, oversoldLine?: number): number;

Donald Lambert’s measure of how far the typical price has strayed from its average, scaled by the average distance from that average.

typical price = (HIGH + LOW + CLOSE) / 3
CCI = (typical price - SMA(typical price)) / (constant * mean deviation(typical price))

Mean deviation is the mean absolute distance from the SMA over the same periods bars. Lambert chose the constant 0.015 so that about 70 to 80% of values fall between -100 and +100. Where every typical price in the window is equal the deviation is zero, and the CCI is 0.

Parameters: periods, 1 to 100 (20 is standard); constant, positive (0.015); overboughtLine, an integer of 0 or more (100); oversoldLine, an integer of 0 or less (-100).

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • CCI periods must be a number
  • CCI periods must be an integer
  • CCI maximum periods is 100
  • CCI periods must be greater than 0
  • CCI constant must be a number
  • CCI constant must be greater than 0
  • CCI overbought line must be a number
  • CCI overbought line must be an integer
  • CCI overbought line must be a positive integer
  • CCI oversold line must be a number
  • CCI oversold line must be an integer
  • CCI oversold line must be a negative integer
  • CCI overbought line must be greater than oversold line

What it measures, its formula and a chart

chaikinOscillator(fastPeriods: number, slowPeriods: number): number;

Marc Chaikin’s momentum of the Accumulation Distribution Line (adl): a fast EMA of the line less a slow one, like a MACD of buying and selling pressure instead of price.

money flow volume = ((CLOSE − LOW) − (HIGH − CLOSE)) / (HIGH − LOW) × VOLUME (0 if HIGH = LOW)
ADL = running total of money flow volume
Chaikin = EMA(ADL, fastPeriods) − EMA(ADL, slowPeriods)

The ADL’s level depends on where it was started, but the oscillator does not: the same amount is added to both EMAs, and the difference takes it away. Each EMA is seeded with the mean of its first values, as TA-Lib’s ADOSC is once warmed up.

Parameters: fastPeriods (3) and slowPeriods (10), 1 to 200, fast below slow.

Returns: one number, in volume units, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Chaikin Oscillator {name} must be a number
  • Chaikin Oscillator {name} must be an integer
  • Chaikin Oscillator maximum {name} is 200
  • Chaikin Oscillator {name} must be at least 1
  • Chaikin Oscillator slowPeriods must be greater than fastPeriods

What it measures, its formula and a chart

chandelierExit(periods: number, multiplier: number): number[];

Charles Le Beau’s volatility trailing stop: a multiple of the Average True Range hung from the highest high (for long positions) or stood on the lowest low (for short positions) of the last periods bars.

long exit = highest HIGH of the last `periods` bars - multiplier * ATR(periods)
short exit = lowest LOW of the last `periods` bars + multiplier * ATR(periods)

Parameters: periods, 1 to 100; multiplier, a positive number.

Returns: [short exit, long exit], drawn as two separate lines. No value until the ATR has warmed up.

Errors: a setting that fails a check stops the run with one of these messages:

  • Chandelier Exit periods must be a number
  • Chandelier Exit periods must be an integer
  • Chandelier Exit maximum periods is 100
  • Chandelier Exit periods must be greater than zero
  • Chandelier Exit multiplier must be a number
  • Chandelier Exit multiplier must be greater than zero

What it measures, its formula and a chart

cmf(periods: number): number;

Marc Chaikin’s measure of buying and selling pressure over a window: the money flow volume of the last periods bars as a fraction of their total volume.

money flow multiplier = ((CLOSE - LOW) - (HIGH - CLOSE)) / (HIGH - LOW) from -1 to +1
money flow volume = multiplier * VOLUME
CMF = sum of money flow volume / sum of VOLUME, over `periods` bars

A bar with no range (HIGH = LOW) has a multiplier of 0. CMF runs from -1 to +1.

Parameters: periods, 1 to 100 (20 is standard).

Returns: one number, drawn as a filled spline on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Chaikin Money Flow periods must be a number
  • Chaikin Money Flow periods must be an integer
  • Chaikin Money Flow maximum periods is 100
  • Chaikin Money Flow periods must be greater than zero

What it measures, its formula and a chart

cmo(periods: number): number;
cmo(periods: number, signalPeriods: number): number[];

Tushar Chande’s momentum oscillator: the balance of up moves against down moves over a window.

up = sum of positive close-to-close changes over `periods` bars
down = sum of the sizes of negative changes over the same bars
CMO = 100 * (up - down) / (up + down)

Unlike the RSI it uses plain sums, with no smoothing, so it reacts faster and reaches its extremes more often. It runs from -100 to +100. A window with no movement at all gives 0. The optional signal line is an EMA of the CMO.

Parameters: periods, 1 to 100 (14 is common); signalPeriods, optional, 1 to 100 (9).

Returns: one number, or [cmo, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Chande Momentum Oscillator periods must be a number
  • Chande Momentum Oscillator periods must be an integer
  • Chande Momentum Oscillator maximum periods is 100
  • Chande Momentum Oscillator periods must be greater than zero
  • Chande Momentum Oscillator signalPeriods must be a number
  • Chande Momentum Oscillator signalPeriods must be an integer
  • Chande Momentum Oscillator maximum signalPeriods is 100
  • Chande Momentum Oscillator signalPeriods must be greater than or equal to zero

What it measures, its formula and a chart

cog(periods: number, signalPeriods?: number): number[];

John Ehlers’ oscillator: the “balance point” of the last periods closes, each weighted by how many bars ago it was, so that it turns with price with very little lag.

COG = -(1 * C[0] + 2 * C[1] + ... + periods * C[periods - 1]) / (C[0] + C[1] + ... + C[periods - 1])

where C[0] is the close of the bar that just closed. The newest close has the smallest weight, as in Ehlers’ definition, so the line rises when price rises. The value is always negative, near -(periods + 1) / 2; only its turns and crossings matter. Ehlers applied it to the median price (HIGH + LOW) / 2; this uses the close, as TradingView’s default does. The optional signal line is an EMA of the COG.

Parameters: periods, 1 to 100 (10 is common); signalPeriods, optional, 1 to 100.

Returns: [cog], or [cog, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Center of Gravity Oscillator periods must be a number
  • Center of Gravity Oscillator periods must be an integer
  • Center of Gravity Oscillator maximum periods is 100
  • Center of Gravity Oscillator periods must be greater than zero
  • Center of Gravity Oscillator signalPeriods must be a number
  • Center of Gravity Oscillator signalPeriods must be an integer
  • Center of Gravity Oscillator maximum signalPeriods is 100
  • Center of Gravity Oscillator signalPeriods must be greater than or equal to zero

What it measures, its formula and a chart

coppock(firstRoCPeriods: number, wmaPeriods: number, secondRoCPeriods: number): number;

Edwin Coppock’s long-term momentum indicator, first published in Barron’s in 1962: a weighted moving average of the sum of two rates of change.

Coppock = WMA(wmaPeriods) of (ROC(firstRoCPeriods) + ROC(secondRoCPeriods))

where ROC(n) = (CLOSE - close n bars ago) / close n bars ago * 100 and the WMA weights the newest value most. Coppock designed it for monthly charts with 14, 11 and 10 periods.

Parameters: firstRoCPeriods, wmaPeriods, secondRoCPeriods, each 1 to 100 (14, 10, 11).

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Coppock Curve {fieldName} must be a number
  • Coppock Curve {fieldName} must be an integer
  • Coppock Curve {fieldName} maximum is 100
  • Coppock Curve {fieldName} must be greater than 0

What it measures, its formula and a chart

dailyPivot(): number[];

The classic floor-trader pivot and its three support and three resistance levels, worked out from the previous trading day’s high, low and close and held for the whole of the next day.

pivot = (HIGH + LOW + CLOSE) / 3 of the previous day
R1 = 2 * pivot - LOW S1 = 2 * pivot - HIGH
R2 = pivot + (HIGH - LOW) S2 = pivot - (HIGH - LOW)
R3 = R1 + (HIGH - LOW) S3 = S1 - (HIGH - LOW)

Days are UTC days. FX trades from Sunday evening to Friday evening, so the levels shown on Sunday come from Friday’s bar, and Monday’s come from Friday and the Sunday session together (Friday’s high and low widened by Sunday’s, and Sunday’s close).

Parameters: none.

Returns: [R3, R2, R1, pivot, S1, S2, S3], seven lines on the price chart.

What it measures, its formula and a chart

dema(periods: number): number;

Patrick Mulloy’s moving average (Technical Analysis of Stocks & Commodities, 1994), which removes most of an EMA’s lag by subtracting the EMA of the EMA. It is not an EMA applied twice.

EMA1 = EMA(CLOSE, periods)
EMA2 = EMA(EMA1, periods)
DEMA = 2 × EMA1 − EMA2

Each EMA starts from the SMA of its first periods inputs and then takes k = 2 / (periods + 1), as TA-Lib computes it.

Parameters: periods, 1 to 200 (20 is common).

Returns: one number, drawn on the price. No value for the first 2 × periods − 2 bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • DEMA periods must be a number
  • DEMA periods must be an integer
  • DEMA maximum periods is 200
  • DEMA periods must be at least 1

What it measures, its formula and a chart

dpo(periods: number): number[];

Removes the trend from price to show its cycles, by comparing a past close with a moving average centred on it.

displacement = floor(periods / 2) + 1
DPO = close `displacement` bars ago - SMA(periods)

Because it compares a past price, the DPO is drawn displacement bars back, under the price it describes, together with the SMA it was measured from. That makes it unsuitable as a live signal; it is a tool for measuring cycle length from peak to peak.

Parameters: periods, 1 to 100 (20 is common).

Returns: [dpo, sma]: the DPO as an area on its own axis and the SMA on the price chart, both shifted back.

Errors: a setting that fails a check stops the run with one of these messages:

  • DPO periods must be a number
  • DPO periods must be an integer
  • DPO maximum periods is 100
  • DPO periods must be greater than zero

What it measures, its formula and a chart

elderBBPower(periods: number): number[];

Alexander Elder’s measure of how far the bulls pushed price above its consensus value, and the bears below it, on each bar, taking an EMA of closes as that value.

Bull Power = HIGH - EMA(periods)
Bear Power = LOW - EMA(periods)

Parameters: periods, 1 to 100.

Returns: [bull power, bear power], two column series on their own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Elder Bull/Bear Power periods must be a number
  • Elder Bull/Bear Power periods must be an integer
  • Elder Bull/Bear Power maximum periods is 100
  • Elder Bull/Bear Power periods must be greater than 0

What it measures, its formula and a chart

ema(periods: number): number;

A moving average that weights recent closes more heavily, with weights falling away geometrically into the past. Each bar moves the average a fixed fraction of the way towards the new close:

k = 2 / (periods + 1)
EMA = EMA[previous] + k * (CLOSE - EMA[previous])

The first value is seeded with the simple average of the first periods closes, as StockCharts and most charting packages do. Because every past close keeps some weight, an EMA needs a long warm-up before the seed stops mattering: this one runs over 2 x periods bars before the start.

Parameters: periods, 1 to 200.

Returns: one number, drawn on the price chart.

Errors: a setting that fails a check stops the run with one of these messages:

  • EMA periods must be a number
  • EMA periods must be an integer
  • EMA maximum periods is 200
  • EMA periods must be greater than 0

What it measures, its formula and a chart

emaEnvelope(periods: number, envelope: number): number[];

Two bands a fixed percentage above and below an exponential moving average of closes.

middle = EMA(periods)
upper = middle * (1 + envelope / 100)
lower = middle * (1 - envelope / 100)

Parameters: periods, 1 to 100; envelope, a percentage above 0 and up to 100.

Returns: [lower, upper, ema], drawn as a shaded band.

Errors: a setting that fails a check stops the run with one of these messages:

  • EMA Envelope periods must be a number
  • EMA Envelope periods must be an integer
  • EMA Envelope maximum periods is 100
  • EMA Envelope periods must be greater than 0
  • EMA Envelope envelope must be a number
  • EMA Envelope envelope percent must be greater than zero
  • EMA Envelope envelope percent must be below 100

What it measures, its formula and a chart

emv(periods: number): number;

Richard Arms’ measure of how far price moves for a given volume: large moves on light volume are “easy”, small moves on heavy volume are “hard”.

distance moved = (HIGH + LOW) / 2 - previous (HIGH + LOW) / 2
box ratio = (VOLUME / 100,000,000) / (HIGH - LOW)
EMV(1) = distance moved / box ratio
EMV = SMA(periods) of EMV(1)

The 100,000,000 scale is StockCharts’ choice for share volumes; on FX tick volume it makes the values large, but the shape and the zero line are what matter. A bar with no range or no volume counts as no movement (0).

Parameters: periods, 1 to 100 (14 is standard).

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Ease of Movement periods must be a number
  • Ease of Movement periods must be an integer
  • Ease of Movement maximum periods is 100
  • Ease of Movement periods must be greater than zero

What it measures, its formula and a chart

fibonacciPivot(): number[];

The classic pivot with its support and resistance levels set at Fibonacci fractions of the previous trading day’s range: 38.2%, 61.8% and 100% of it above and below the pivot.

pivot = (HIGH + LOW + CLOSE) / 3 of the previous day
R1 = pivot + 0.382 × (HIGH − LOW) S1 = pivot − 0.382 × (HIGH − LOW)
R2 = pivot + 0.618 × (HIGH − LOW) S2 = pivot − 0.618 × (HIGH − LOW)
R3 = pivot + (HIGH − LOW) S3 = pivot − (HIGH − LOW)

Days are UTC days, as for dailyPivot: the levels shown on Sunday come from Friday’s bar, and Monday’s from Friday and the Sunday session together (Friday’s high and low widened by Sunday’s, and Sunday’s close).

Parameters: none.

Returns: [R3, R2, R1, pivot, S1, S2, S3], seven lines on the price chart.

What it measures, its formula and a chart

fisherTransform(periods: number): number[];

John Ehlers’ transform of price into a near-Gaussian distribution, so that turning points show as sharp, clear peaks instead of rounded ones.

position = 2 * (midpoint - lowest midpoint) / (highest midpoint - lowest midpoint) - 1
over `periods` bars, where midpoint = (HIGH + LOW) / 2; -1 to +1
value = EMA(5) of position (Ehlers' 0.33 / 0.67 weighting), clamped to +/-0.999
fisher = EMA(3) of ln((1 + value) / (1 - value)) (Ehlers' 0.5 / 0.5 weighting)
signal = the previous bar's fisher

The clamp keeps the logarithm finite when price sits at the edge of its range for several bars, as Ehlers’ own code does. A window with no range at all puts price in the middle (0).

Parameters: periods, 1 to 100 (9 or 10 is common).

Returns: [fisher, signal], on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Fisher Transform periods must be a number
  • Fisher Transform periods must be an integer
  • Fisher Transform maximum periods is 100
  • Fisher Transform periods must be greater than 0

What it measures, its formula and a chart

forceIndex(periods: number): number;

Alexander Elder’s measure of the force behind a move: how far price moved, weighted by how much volume moved it.

force(1) = (CLOSE - previous CLOSE) * VOLUME
Force Index = EMA(periods) of force(1), seeded with the SMA of the first `periods` values

Parameters: periods, 1 to 100 (13 is standard).

Returns: one number, on its own axis, drawn as a filled area.

Errors: a setting that fails a check stops the run with one of these messages:

  • Force Index periods must be a number
  • Force Index periods must be an integer
  • Force Index maximum periods is 100
  • Force Index periods must be greater than zero

What it measures, its formula and a chart

gapo(periods: number): number;

Jayanthi Gopalakrishnan’s measure of how erratic a market is: the logarithm of its range over a window, scaled by the logarithm of the window’s length.

GAPO = ln(highest HIGH - lowest LOW over `periods` bars) / ln(periods)

The range is in price units, so the level depends on the instrument’s price; compare readings on one instrument over time, not across instruments. A window with no range has no logarithm, so it gives no value.

Parameters: periods, 2 to 100 (5 is common). One period has no logarithm to divide by.

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Gopalakrishnan Range Index periods must be a number
  • Gopalakrishnan Range Index periods must be an integer
  • Gopalakrishnan Range Index maximum periods is 100
  • Gopalakrishnan Range Index periods must be at least 2

What it measures, its formula and a chart

historicalVolatility(periods: number, tradingDaysPerYear: number): number;

How much the price has been moving, as the annualised standard deviation of its returns in percent: the “realised volatility” that option traders compare with implied volatility.

return = ln(CLOSE / previous CLOSE)
HV = 100 × sample standard deviation of the last `periods` returns × √(bars per year)

Bars per year: for bars of a day or shorter, tradingDaysPerYear × the bars in a day, so hourly FX bars with 252 count 6,048; for longer bars, the calendar year, so weekly bars count 52. Use 252 for markets that close at weekends, such as FX and stocks, and 365 for crypto, which trades every day. The standard deviation is the sample one (dividing by periods − 1), the textbook estimator; TradingView’s ta.stdev divides by periods and so reads slightly lower.

Parameters: periods, 2 to 200 (20 is common), and tradingDaysPerYear, 1 to 366 (252).

Returns: one number, a percentage, on its own axis. No value for the first periods bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • Historical Volatility periods must be a number
  • Historical Volatility periods must be an integer
  • Historical Volatility maximum periods is 200
  • Historical Volatility periods must be at least 2
  • Historical Volatility tradingDaysPerYear must be a number
  • Historical Volatility tradingDaysPerYear must be from 1 to 366

What it measures, its formula and a chart

hullMa(periods: number): number;

Alan Hull’s moving average (2005), built from weighted moving averages to be both smooth and quick. Doubling a short WMA and taking away a long one projects the trend forward, and a WMA of the result over √periods smooths it again.

raw = 2 × WMA(CLOSE, floor(periods / 2)) − WMA(CLOSE, periods)
HMA = WMA(raw, floor(√periods))

The WMAs weight the newest value n and the oldest 1, as the wma built-in does. Lengths are rounded down, as Hull’s own formula and TradingView’s ta.hma round them.

Parameters: periods, 4 to 200 (9 or 20 are common). Below 4, √periods rounds down to 1 and the second smoothing does nothing.

Returns: one number, drawn on the price. No value until periods closes and then floor(√periods) raw values have been gathered, about periods + √periods bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • Hull MA periods must be a number
  • Hull MA periods must be an integer
  • Hull MA maximum periods is 200
  • Hull MA periods must be at least 4

What it measures, its formula and a chart

ichimokuCloud(conversionLinePeriods: number, baseLinePeriods: number, leadingSpanPeriods: number, laggingSpanPeriods: number): Array<number | [number, number]>;

Goichi Hosoda’s system of five lines, each the midpoint of a high-low range, two of them projected forward to form the “cloud”.

Tenkan-sen (conversion line) = (highest HIGH + lowest LOW) / 2 over conversionLinePeriods (9)
Kijun-sen (base line) = (highest HIGH + lowest LOW) / 2 over baseLinePeriods (26)
Senkou Span A (leading A) = (Tenkan-sen + Kijun-sen) / 2, drawn baseLinePeriods bars ahead
Senkou Span B (leading B) = (highest HIGH + lowest LOW) / 2 over leadingSpanPeriods (52), drawn baseLinePeriods bars ahead
Chikou Span (lagging span) = CLOSE, drawn laggingSpanPeriods bars back

The cloud is the area between the two leading spans: green while Span A is above Span B, red while it is below. The forward displacement is the base-line period, 26 by default, as in Hosoda’s original and on most platforms.

Parameters: conversionLinePeriods, baseLinePeriods, leadingSpanPeriods, laggingSpanPeriods, each 1 to 100 (9, 26, 52, 26 are standard).

Returns: [Tenkan-sen, Kijun-sen, Senkou Span A, Senkou Span B, Chikou Span, green cloud range, red cloud range]; the two ranges are drawn as fills.

Errors: a setting that fails a check stops the run with one of these messages:

  • Ichimoku Cloud {fieldName} must be a number
  • Ichimoku Cloud {fieldName} must be an integer
  • Ichimoku Cloud {fieldName} must be greater than zero
  • Ichimoku Cloud {fieldName} maximum value is 100

What it measures, its formula and a chart

keltnerChannels(emaPeriods: number, atrPeriods: number, atrMultiplier: number): number[];

Bands set a multiple of the Average True Range above and below an exponential moving average. This is the modern form popularised by Linda Bradford Raschke and used by StockCharts; Chester Keltner’s 1960 original used a 10-day SMA of the typical price and the average daily range.

middle = EMA(emaPeriods) of closes
upper = middle + atrMultiplier * ATR(atrPeriods)
lower = middle - atrMultiplier * ATR(atrPeriods)

Parameters: emaPeriods, atrPeriods, each 1 to 100; atrMultiplier, a positive number.

Returns: [lower, upper, ema], drawn as a shaded band with a dashed middle line. No value until both the EMA and the ATR have warmed up.

Errors: a setting that fails a check stops the run with one of these messages:

  • Keltner Channels EMA periods must be a number
  • Keltner Channels EMA periods must be an integer
  • Keltner Channels EMA maximum periods is 100
  • Keltner Channels EMA periods must be greater than 0
  • Keltner Channels Average True Range periods must be a number
  • Keltner Channels Average True Range periods must be an integer
  • Keltner Channels Average True Range maximum periods is 100
  • Keltner Channels Average True Range periods must be greater than zero
  • Keltner Channels Average True Range multiplier must be a number
  • Keltner Channels Average True Range multiplier must be greater than zero

What it measures, its formula and a chart

kst(firstROCPeriods: number, secondROCPeriods: number, thirdROCPeriods: number, fourthROCPeriods: number, firstSMAPeriods: number, secondSMAPeriods: number, thirdSMAPeriods: number, fourthSMAPeriods: number): number;
kst(firstROCPeriods: number, secondROCPeriods: number, thirdROCPeriods: number, fourthROCPeriods: number, firstSMAPeriods: number, secondSMAPeriods: number, thirdSMAPeriods: number, fourthSMAPeriods: number, signalSMA: number): number[];

Martin Pring’s momentum oscillator: four rates of change over rising timeframes, each smoothed, then weighted so the longer ones count more.

RCMA n = SMA(nth SMA periods) of ROC(nth ROC periods), for n = 1 to 4
KST = RCMA1 * 1 + RCMA2 * 2 + RCMA3 * 3 + RCMA4 * 4
signal = SMA(signalSMA) of KST

Each ROC is in percent: 100 * (CLOSE - CLOSE n bars ago) / CLOSE n bars ago. Pring’s standard settings are ROC 10, 15, 20, 30; SMA 10, 10, 10, 15; signal 9.

Parameters: four ROC periods, each greater than the last, and four SMA periods, all 1 to 100; signalSMA, optional, 1 to 100.

Returns: one number, or [kst, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Know Sure Thing secondROCPeriods must be greater than firstROCPeriods
  • Know Sure Thing thirdROCPeriods must be greater than secondROCPeriods
  • Know Sure Thing fourthROCPeriods must be greater than thirdROCPeriods
  • Know Sure Thing {fieldName} must be a number
  • Know Sure Thing {fieldName} must be an integer
  • Know Sure Thing {fieldName} must be greater than zero
  • Know Sure Thing {fieldName} maximum value is 100

What it measures, its formula and a chart

Linear Regression (Least Squares Moving Average)

Section titled “Linear Regression (Least Squares Moving Average)”
linearRegression(periods: number): number;

The end point of the straight line that best fits the last periods closes: where the trend line drawn through the window says the price should be now. It is TA-Lib’s LINEARREG and TradingView’s ta.linreg with no offset.

fit CLOSE = a + b × x over the window by least squares, x = 0 for the oldest close
value = a + b × (periods − 1)

Because it projects the fitted slope to the newest bar, it follows a steady trend with no lag, unlike a moving average, and overshoots at turns.

Parameters: periods, 2 to 200 (14 or 20 are common).

Returns: one number, drawn on the price. No value until the window of periods closes is full.

Errors: a setting that fails a check stops the run with one of these messages:

  • Linear Regression periods must be a number
  • Linear Regression periods must be an integer
  • Linear Regression maximum periods is 200
  • Linear Regression periods must be at least 2

What it measures, its formula and a chart

Moving Average Convergence Divergence (MACD)

Section titled “Moving Average Convergence Divergence (MACD)”
macd(fastEMAPeriods: number, slowEMAPeriods: number): number;
macd(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[];

Gerald Appel’s trend-following momentum indicator: the gap between a fast and a slow EMA of the close.

MACD = (EMA(fast) - EMA(slow)) / PIP_SIZE
signal = EMA(signal periods) of MACD, seeded with the SMA of its first values
histogram = MACD - signal

On this platform MACD is in pips, not price units, so that one threshold reads the same on every currency pair. An algorithm that compares MACD with a number of pips can use it directly; multiply by INSTRUMENT.PIP_SIZE to get the textbook price value.

Parameters: fastEMAPeriods (12) and slowEMAPeriods (26), 1 to 100, fast below slow; signalEMAPeriods, optional, 1 to 100 (9).

Returns: the MACD in pips, or [macd, signal, histogram] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • MACD slowEMAPeriods must be greater than fastEMAPeriods
  • MACD {fieldName} must be a number
  • MACD {fieldName} must be an integer
  • MACD {fieldName} maximum is 100
  • MACD {fieldName} must be greater than 0

What it measures, its formula and a chart

macdHistogram(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number;

The gap between the MACD and its signal line on its own, drawn as columns. See macd for the MACD itself; like it, the histogram is in pips.

histogram = MACD(fast, slow) - EMA(signal periods) of MACD

Parameters: fastEMAPeriods (12), slowEMAPeriods (26) and signalEMAPeriods (9), 1 to 100, fast below slow.

Returns: one number in pips, on its own axis, drawn as columns.

Errors: a setting that fails a check stops the run with one of these messages:

  • MACD slowEMAPeriods must be greater than fastEMAPeriods
  • MACD {fieldName} must be a number
  • MACD {fieldName} must be an integer
  • MACD {fieldName} maximum is 100
  • MACD {fieldName} must be greater than 0

What it measures, its formula and a chart

massIndex(emaPeriods: number, summationPeriods: number): number;

Donald Dorsey’s reversal indicator: it watches the bar range widen and narrow, without regard to direction, to catch the “bulge” that tends to come before a trend reverses.

single EMA = EMA(emaPeriods) of (HIGH - LOW)
double EMA = EMA(emaPeriods) of the single EMA
Mass Index = sum over `summationPeriods` bars of (single EMA / double EMA)

Each EMA is seeded with the SMA of its first values. With the standard 9 and 25 the index hovers around 25.

Parameters: emaPeriods (9) and summationPeriods (25), 1 to 100.

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Mass Index {fieldName} must be a number
  • Mass Index {fieldName} must be an integer
  • Mass Index {fieldName} maximum is 100
  • Mass Index {fieldName} must be greater than zero

What it measures, its formula and a chart

mfi(periods: number): number;

Gene Quong and Avrum Soudack’s volume-weighted RSI: it compares the money flowing in on rising bars with the money flowing out on falling ones.

typical price = (HIGH + LOW + CLOSE) / 3
raw money flow = typical price * VOLUME
a bar's flow is positive when its typical price is above the previous bar's, negative when
below, and counts on neither side when unchanged
money ratio = sum of positive flows / sum of negative flows over `periods` bars
MFI = 100 - 100 / (1 + money ratio)

It runs from 0 to 100. A window with only positive flow gives 100, only negative flow 0, and no flow at all 0 (TA-Lib’s convention).

Parameters: periods, 1 to 100 (14 is standard).

Returns: one number, 0 to 100, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Money Flow Index periods must be a number
  • Money Flow Index periods must be an integer
  • Money Flow Index maximum periods is 100
  • Money Flow Index periods must be greater than zero

What it measures, its formula and a chart

momentum(periods: number): number;

How far the close has moved over a window, in pips: the difference that the Rate of Change (roc) expresses as a percentage.

Momentum = (CLOSE − CLOSE `periods` bars ago) / PIP_SIZE

As with MACD, the value is in pips rather than price units, so one threshold reads the same on every currency pair. Multiply by INSTRUMENT.PIP_SIZE for the textbook price difference.

Parameters: periods, 1 to 200 (10 is common).

Returns: one number, in pips, on its own axis. No value until periods earlier closes are kept.

Errors: a setting that fails a check stops the run with one of these messages:

  • Momentum periods must be a number
  • Momentum periods must be an integer
  • Momentum maximum periods is 200
  • Momentum periods must be at least 1

What it measures, its formula and a chart

obv(): number;

Joe Granville’s running total of volume, added on up closes and taken away on down closes, on the idea that volume leads price.

OBV = previous OBV + VOLUME when CLOSE is above the previous close
previous OBV - VOLUME when CLOSE is below it
previous OBV when it is unchanged

The total starts at zero on the first bar of the run, so only its direction and its slope carry meaning, never its level.

Parameters: none.

Returns: one number, on its own axis.

What it measures, its formula and a chart

parabolicSar(step: number, maximum: number): number;

J. Welles Wilder’s trailing stop, from New Concepts in Technical Trading Systems (1978). It follows the trend from behind, accelerating towards price as the trend extends, and when price crosses it the position is reversed and the SAR jumps to the other side.

next SAR = SAR + AF × (EP − SAR)

EP, the extreme point, is the highest high of a rise or the lowest low of a fall. AF, the acceleration factor, starts at step and rises by step each time the trend makes a new extreme, up to maximum. In a rise the SAR may not go above the lows of this bar or the one before; in a fall, not below their highs. When a bar’s low touches the SAR of a rise (or its high the SAR of a fall), the trend reverses: the SAR becomes the old EP, EP becomes this bar’s extreme, and AF starts again at step.

This follows TA-Lib’s SAR, including how it starts: the first two bars decide the first trend (a fall if the second bar’s low drops further than its high rises, else a rise), and the first SAR is the first bar’s low in a rise or its high in a fall. The value on a bar is the SAR that applied during it, set at the previous close, which is what charting platforms plot.

Parameters: step, above 0 to 1 (0.02 is standard), and maximum, at least step and at most 1 (0.2 is standard).

Returns: one number, drawn on the price as a dotted line until charts can draw markers. No value for the first bar.

Errors: a setting that fails a check stops the run with one of these messages:

  • Parabolic SAR step must be a number
  • Parabolic SAR step must be greater than 0 and at most 1
  • Parabolic SAR maximum must be a number
  • Parabolic SAR maximum must be at least the step and at most 1

What it measures, its formula and a chart

pgo(periods: number): number;

Mark Johnson’s breakout oscillator: how far the close is from its moving average, measured in average true ranges.

true range = the greatest of HIGH - LOW, |HIGH - previous CLOSE|, |LOW - previous CLOSE|
PGO = (CLOSE - SMA(periods) of CLOSE) / EMA(periods) of true range

The EMA of true range is seeded with the SMA of its first values, as in Johnson’s definition (the old version used the Wilder-smoothed ATR, a slower average). A market with no range at all gives no value.

Parameters: periods, 1 to 100 (89 is Johnson’s own; 14 to 21 are common on intraday charts).

Returns: one number, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Pretty Good Oscillator periods must be a number
  • Pretty Good Oscillator periods must be an integer
  • Pretty Good Oscillator maximum periods is 100
  • Pretty Good Oscillator periods must be greater than zero

What it measures, its formula and a chart

pmo(firstEMAPeriods: number, secondEMAPeriods: number): number;
pmo(firstEMAPeriods: number, secondEMAPeriods: number, signalEMAPeriods: number): number[];

Carl Swenlin’s DecisionPoint oscillator: a one-bar rate of change, smoothed twice.

ROC(1) = (CLOSE / previous CLOSE) * 100 - 100
first = custom smoothing over `firstEMAPeriods` of ROC(1)
PMO = custom smoothing over `secondEMAPeriods` of (10 * first)
signal = EMA(signalEMAPeriods) of PMO

DecisionPoint’s “custom smoothing” is an EMA with the multiplier 2 / periods, not the usual 2 / (periods + 1); the signal line is an ordinary EMA. Each average is seeded with the SMA of its first values. Standard settings are 35, 20 and 10.

Parameters: firstEMAPeriods (35) and secondEMAPeriods (20), 2 to 100; signalEMAPeriods, optional, 1 to 100 (10).

Returns: one number, or [pmo, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Price Momentum Oscillator firstEMAPeriods and secondEMAPeriods must be at least 2
  • Price Momentum Oscillator {fieldName} must be a number
  • Price Momentum Oscillator {fieldName} must be an integer
  • Price Momentum Oscillator {fieldName} maximum is 100
  • Price Momentum Oscillator {fieldName} must be greater than 0

What it measures, its formula and a chart

ppo(fastEMAPeriods: number, slowEMAPeriods: number): number;
ppo(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[];

The MACD expressed as a percentage of the slow average, so that it can be compared across instruments and across time whatever the price level.

PPO = 100 * (EMA(fast) - EMA(slow)) / EMA(slow)
signal = EMA(signal periods) of PPO, seeded with the SMA of its first values
histogram = PPO - signal

The signal line now starts on the bar that completes its seed and includes that bar; before GH-461 it was seeded one bar late from the values before it.

Parameters: fastEMAPeriods (12) and slowEMAPeriods (26), 1 to 100, fast below slow; signalEMAPeriods, optional, 1 to 100 (9).

Returns: one number, or [histogram, signal, ppo] with a signal period (in that order, which algorithms rely on), on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Price Percentage Oscillator slowEMAPeriods must be greater than fastEMAPeriods
  • Price Percentage Oscillator {fieldName} must be a number
  • Price Percentage Oscillator {fieldName} must be an integer
  • Price Percentage Oscillator {fieldName} maximum is 100
  • Price Percentage Oscillator {fieldName} must be greater than 0

What it measures, its formula and a chart

priceChannels(periods: number): number[];

Richard Donchian’s channel: the highest high and the lowest low of the last periods bars, with the midpoint between them.

upper = highest HIGH of the last `periods` bars
lower = lowest LOW of the last `periods` bars
middle = (upper + lower) / 2

The window includes the bar that just closed, so a close at a new high lifts the upper line on the same bar. Breakout systems (the Turtle rules among them) compare price with the channel of the bars before, which is this channel one bar back.

Parameters: periods, 1 to 100.

Returns: [lowest low, highest high, middle], drawn as a shaded band with a dashed middle line.

Errors: a setting that fails a check stops the run with one of these messages:

  • Price Channels periods must be a number
  • Price Channels periods must be an integer
  • Price Channels maximum periods is 100
  • Price Channels periods must be greater than zero

What it measures, its formula and a chart

pvo(fastEMAPeriods: number, slowEMAPeriods: number): number;
pvo(fastEMAPeriods: number, slowEMAPeriods: number, signalEMAPeriods: number): number[];

The PPO applied to volume: how far a fast average of volume is above or below a slow one, as a percentage of the slow one.

PVO = 100 * (EMA(fast) of VOLUME - EMA(slow) of VOLUME) / EMA(slow) of VOLUME
signal = EMA(signal periods) of PVO
histogram = PVO - signal

Every EMA is seeded with the SMA of its first values. Before GH-461 this indicator called the ema built-in, which averages closing prices, so it was a second PPO and never looked at volume.

Parameters: fastEMAPeriods (12) and slowEMAPeriods (26), 1 to 100, fast below slow; signalEMAPeriods, optional, 1 to 100 (9).

Returns: one number, or [pvo, signal, histogram] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Price Volume Oscillator slowEMAPeriods must be greater than fastEMAPeriods
  • Price Volume Oscillator {fieldName} must be a number
  • Price Volume Oscillator {fieldName} must be an integer
  • Price Volume Oscillator {fieldName} maximum is 100
  • Price Volume Oscillator {fieldName} must be greater than 0

What it measures, its formula and a chart

qStick(periods: number): number;

Tushar Chande’s measure of buying and selling pressure: the average body of recent candles, positive when bars close above their opens.

QStick = SMA(periods) of (CLOSE - OPEN) / PIP_SIZE

On this platform QStick is in pips, so one threshold reads the same on every currency pair. Multiply by INSTRUMENT.PIP_SIZE for the textbook price value.

Parameters: periods, 1 to 100 (8 is common).

Returns: one number in pips, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • QStick periods must be a number
  • QStick periods must be an integer
  • QStick maximum periods is 100
  • QStick periods must be greater than zero

What it measures, its formula and a chart

roc(periods: number): number;

The plainest momentum measure: how far the close has moved over a window, as a percentage.

ROC = 100 * (CLOSE - CLOSE `periods` bars ago) / CLOSE `periods` bars ago

Parameters: periods, 1 to 100 (12 is common).

Returns: one number, a percentage, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Rate Of Change periods must be a number
  • Rate Of Change periods must be an integer
  • Rate Of Change maximum periods is 100
  • Rate Of Change periods must be greater than zero

What it measures, its formula and a chart

rsi(periods: number): number;

J. Welles Wilder’s momentum oscillator: the share of recent movement that has been upward.

change = CLOSE - previous CLOSE
average gain = Wilder average of the gains (positive changes, losses counting as 0)
average loss = Wilder average of the losses (sizes of negative changes)
RSI = 100 - 100 / (1 + average gain / average loss)

The first averages are the plain means of the first periods changes; after that each is (previous average * (periods - 1) + this bar’s value) / periods. It runs from 0 to 100. Only gains gives 100; no movement at all gives 0 (TA-Lib’s convention).

Before GH-461 the seed was wrong: any falling bar reset the running total of gains to zero (and any rising bar the losses), and the first change was taken from the bar’s own open.

Parameters: periods, 1 to 100 (14 is Wilder’s).

Returns: one number, 0 to 100, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • RSI periods must be a number
  • RSI periods must be an integer
  • RSI maximum periods is 100
  • RSI periods must be greater than zero

What it measures, its formula and a chart

sma(periods: number): number;

The arithmetic mean of the last periods closes. Every close in the window carries the same weight, so the average responds to a new price only by 1/periods of its change, and responds again when that price drops out of the window periods bars later.

SMA = (C[0] + C[1] + ... + C[periods - 1]) / periods

where C[0] is the close of the bar that just closed and C[n] the close n bars earlier.

Parameters: periods, 1 to 100.

Returns: one number, drawn on the price chart.

Errors: a setting that fails a check stops the run with one of these messages:

  • SMA periods must be a number
  • SMA periods must be an integer
  • SMA maximum periods is 100
  • SMA periods must be greater than zero

What it measures, its formula and a chart

smaEnvelope(periods: number, envelope: number): number[];

Two bands a fixed percentage above and below a simple moving average of closes.

middle = SMA(periods)
upper = middle * (1 + envelope / 100)
lower = middle * (1 - envelope / 100)

Parameters: periods, 1 to 100; envelope, a percentage above 0 and up to 100.

Returns: [lower, upper, middle], drawn as a shaded band with a dashed middle line.

Errors: a setting that fails a check stops the run with one of these messages:

  • SMA Envelope periods must be a number
  • SMA Envelope periods must be an integer
  • SMA Envelope maximum period is 100
  • SMA Envelope periods must be greater than 0
  • SMA Envelope envelope must be a number
  • SMA Envelope envelope percent must be greater than zero
  • SMA Envelope envelope percent must be below 100

What it measures, its formula and a chart

Smoothed Moving Average (SMMA), also called the Running Moving Average (RMA)

Section titled “Smoothed Moving Average (SMMA), also called the Running Moving Average (RMA)”
smma(periods: number): number;

The moving average J. Welles Wilder used inside RSI, ATR and ADX: an exponential average whose weight on the newest close is 1/periods instead of the EMA’s 2/(periods + 1), so it reacts about half as fast as an EMA of the same length.

first SMMA = SMA of the first `periods` closes
SMMA = (previous SMMA × (periods − 1) + CLOSE) / periods

An SMMA of N periods follows an EMA of 2N − 1 periods. MetaTrader calls it the Smoothed Moving Average and TradingView ta.rma; both start it as here.

Parameters: periods, 1 to 200 (14 is common, after Wilder).

Returns: one number, drawn on the price. No value for the first periods − 1 bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • SMMA periods must be a number
  • SMMA periods must be an integer
  • SMMA maximum periods is 200
  • SMMA periods must be at least 1

What it measures, its formula and a chart

standardDeviation(periods: number): number;

The population standard deviation of the closes over a window: how widely price is spread around its average, the measure behind Bollinger Bands.

mean = SMA(periods) of CLOSE
SD = sqrt(sum of (CLOSE - mean)^2 over `periods` bars / periods) / PIP_SIZE

On this platform it is in pips, so one threshold reads the same on every currency pair. Multiply by INSTRUMENT.PIP_SIZE for the value in price units.

Parameters: periods, 1 to 100 (20 is common).

Returns: one number in pips, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Standard Deviation (Volatility) periods must be a number
  • Standard Deviation (Volatility) periods must be an integer
  • Standard Deviation (Volatility) maximum periods is 100
  • Standard Deviation (Volatility) periods must be greater than zero

What it measures, its formula and a chart

stochRsi(periods: number): number;

Tushar Chande and Stanley Kroll’s stochastic of the RSI: where today’s RSI sits within its own range over a window, which makes it faster and more sensitive than the RSI itself.

StochRSI = (RSI - lowest RSI) / (highest RSI - lowest RSI), over `periods` RSI values

It uses the platform’s rsi with the same periods. It runs from 0 to 1. A window in which the RSI did not move gives 0 (TA-Lib’s convention).

Parameters: periods, 1 to 100 (14 is standard).

Returns: one number, 0 to 1, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • StochRSI periods must be a number
  • StochRSI periods must be an integer
  • StochRSI maximum periods is 100
  • StochRSI periods must be greater than zero

What it measures, its formula and a chart

stochasticOscillator(periods: number, smaPeriods: number): number[];

George Lane’s oscillator: where the close sits within the high-low range of a window.

%K = 100 * (CLOSE - lowest LOW) / (highest HIGH - lowest LOW), over `periods` bars
%D = SMA(smaPeriods) of %K

This is the “fast” stochastic. It runs from 0 to 100. A window with no range gives 0 (TA-Lib’s convention). Before GH-461 it took the range from closes only, which pinned %K to 0 or 100 far more often than Lane’s definition does.

Parameters: periods, 1 to 100 (14); smaPeriods, 1 to 100 (3).

Returns: [%K, %D], 0 to 100, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Stochastic Oscillator periods must be a number
  • Stochastic Oscillator periods must be an integer
  • Stochastic Oscillator maximum period is 100
  • Stochastic Oscillator periods must be greater than 0
  • Stochastic Oscillator smaPeriods must be a number
  • Stochastic Oscillator smaPeriods must be an integer
  • Stochastic Oscillator smaPeriods must be greater than 0

What it measures, its formula and a chart

supertrend(periods: number, multiplier: number): number;

Olivier Seban’s trailing stop: a band a multiple of the Average True Range from the bar’s midpoint, which ratchets in the direction of the trend and flips sides when price closes through it.

middle = (HIGH + LOW) / 2
basic upper = middle + multiplier × ATR(periods)
basic lower = middle − multiplier × ATR(periods)
upper = basic upper if it is below the previous upper, or the previous close was
above the previous upper; else the previous upper
lower = basic lower if it is above the previous lower, or the previous close was
below the previous lower; else the previous lower
Supertrend = lower in a rise, upper in a fall

A fall turns into a rise when the close goes above the upper band, and a rise into a fall when the close goes below the lower band. The ATR is Wilder’s, as the atr built-in gives it, and the first trend is a fall, as TradingView’s ta.supertrend starts.

Parameters: periods for the ATR, 1 to 100 (10 is common), and multiplier, greater than 0 (3 is common).

Returns: one number, drawn on the price. Compare it with CLOSE for the direction: below the close is a rise. No value until the ATR has one.

Errors: a setting that fails a check stops the run with one of these messages:

  • Supertrend periods must be a number
  • Supertrend periods must be an integer
  • Supertrend maximum periods is 100
  • Supertrend periods must be greater than zero
  • Supertrend multiplier must be a number
  • Supertrend multiplier must be greater than zero

What it measures, its formula and a chart

tema(periods: number): number;

Patrick Mulloy’s second lag-reduced average, from the same 1994 article as DEMA. It combines an EMA with the EMAs of itself so that their lags cancel.

EMA1 = EMA(CLOSE, periods)
EMA2 = EMA(EMA1, periods)
EMA3 = EMA(EMA2, periods)
TEMA = 3 × EMA1 − 3 × EMA2 + EMA3

Each EMA starts from the SMA of its first periods inputs and then takes k = 2 / (periods + 1), as TA-Lib computes it. TRIX is the rate of change of EMA3.

Parameters: periods, 1 to 200 (20 is common).

Returns: one number, drawn on the price. No value for the first 3 × periods − 3 bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • TEMA periods must be a number
  • TEMA periods must be an integer
  • TEMA maximum periods is 200
  • TEMA periods must be at least 1

What it measures, its formula and a chart

trix(periods: number): number;
trix(periods: number, signalPeriods: number): number[];

Jack Hutson’s oscillator: the one-bar percentage change of a triple-smoothed EMA of the close. The triple smoothing filters out moves shorter than the period, leaving the underlying trend.

single = EMA(periods) of CLOSE
double = EMA(periods) of single
triple = EMA(periods) of double
TRIX = 100 * (triple - previous triple) / previous triple
signal = EMA(signalPeriods) of TRIX

Each EMA is seeded with the SMA of its first values. Before GH-461 the previous triple EMA was only updated when a signal line was asked for, so without one TRIX measured the change from a fixed starting point instead of from the previous bar.

Parameters: periods, 1 to 100 (15 is common); signalPeriods, optional, 1 to 100 (9).

Returns: one number, a percentage, or [trix, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • TRIX periods must be a number
  • TRIX periods must be an integer
  • TRIX maximum periods is 100
  • TRIX periods must be greater than 0
  • TRIX signalPeriods must be a number
  • TRIX signalPeriods must be an integer
  • TRIX maximum signalPeriods is 100
  • TRIX signalPeriods must be greater than or equal to 0

What it measures, its formula and a chart

tsi(firstPeriods: number, secondPeriods: number): number;
tsi(firstPeriods: number, secondPeriods: number, signalPeriods: number): number[];

William Blau’s double-smoothed momentum oscillator: the smoothed one-bar change of the close, divided by the smoothed size of that change.

change = CLOSE - previous CLOSE
TSI = 100 * EMA(second, EMA(first, change)) / EMA(second, EMA(first, |change|))
signal = EMA(signalPeriods) of TSI

Each EMA is seeded with the SMA of its first values. It runs from -100 to +100. A market that has not moved at all gives 0.

Parameters: firstPeriods (25) and secondPeriods (13), 1 to 100; signalPeriods, optional, 1 to 100 (7 to 12).

Returns: one number, or [tsi, signal] with a signal period, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • True Strength Index {fieldName} must be a number
  • True Strength Index {fieldName} must be an integer
  • True Strength Index {fieldName} must be greater than zero
  • True Strength Index {fieldName} maximum value is 100

What it measures, its formula and a chart

uo(shortPeriods: number, mediumPeriods: number, longPeriods: number): number;

Larry Williams’ oscillator: buying pressure as a share of the true range, averaged over three timeframes at once so that a signal on one is confirmed by the others.

buying pressure = CLOSE - min(LOW, previous CLOSE)
true range = max(HIGH, previous CLOSE) - min(LOW, previous CLOSE)
average n = sum of buying pressure / sum of true range, over the last n bars
UO = 100 * (4 * average(short) + 2 * average(medium) + average(long)) / 7

It runs from 0 to 100. A window with no range at all has no average, so it gives no value.

Parameters: shortPeriods (7), mediumPeriods (14) and longPeriods (28), 1 to 100, each greater than the last.

Returns: one number, 0 to 100, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Ultimate Oscillator mediumPeriods must be greater than shortPeriods
  • Ultimate Oscillator longPeriods must be greater than mediumPeriods
  • Ultimate Oscillator {fieldName} must be a number
  • Ultimate Oscillator {fieldName} must be an integer
  • Ultimate Oscillator {fieldName} maximum is 100
  • Ultimate Oscillator {fieldName} must be greater than 0

What it measures, its formula and a chart

volume(periods?: number): number[];

The volume of each bar, drawn as columns under the price chart. On FX venues this is tick volume (the number of price updates in the bar), which tracks real traded volume closely enough to read activity from.

Parameters: periods is accepted and ignored, as algorithms have always been able to pass one.

Returns: [volume], a one-item list (algorithms read volume()\[0\]), on its own axis.

What it measures, its formula and a chart

vtx(periods: number): number[];

Etienne Botes and Douglas Siepman’s pair of lines measuring upward and downward trend movement, after the vortices in flowing water.

+VM = |HIGH - previous LOW| -VM = |LOW - previous HIGH|
true range = the greatest of HIGH - LOW, |HIGH - previous CLOSE|, |LOW - previous CLOSE|
+VI = sum of +VM / sum of true range, over `periods` bars
-VI = sum of -VM / sum of true range, over the same bars

Before GH-461 the movements were not made absolute, so -VI and +VI could cancel themselves out within the window. A window with no range at all gives no values.

Parameters: periods, 1 to 100 (14 is standard).

Returns: [-VI, +VI], on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Vortex Indicator periods must be a number
  • Vortex Indicator periods must be an integer
  • Vortex Indicator maximum period is 100
  • Vortex Indicator periods must be greater than 0

What it measures, its formula and a chart

vwap(): number;

The average price traded so far in the session, each bar weighted by its volume. Institutions use it as a benchmark for the quality of their fills, which is why intraday traders watch it.

typical price = (HIGH + LOW + CLOSE) / 3
VWAP = Σ(typical price × VOLUME) / Σ VOLUME, over the bars of the session so far

The session is the UTC day: the sums start again with the first bar that opens at or after 00:00 UTC. That suits FX and crypto, which trade around the clock; stocks will want the exchange session once the platform carries them. On FX the volume is the broker’s tick volume, the number of price changes, not the amount traded, so the weights are a proxy. A bar is in the session it opens in: TIME is the bar’s close, so its open is TIME − INTERVAL_MS.

VWAP needs the whole session, so there is no value until the first session boundary has been seen. The run-up asks for a day of bars, capped at 1000, so on charts of an hour or more the first value is on the first bar shown; on minute charts the start of the chart can be blank until the next 00:00 UTC. A session with no volume yet has no value.

Parameters: none.

Returns: one number, drawn on the price. No value before the first 00:00 UTC in the data.

Errors: a setting that fails a check stops the run with one of these messages:

  • VWAP resets each day, so it needs bars shorter than a day

What it measures, its formula and a chart

vwma(periods: number): number;

A simple moving average in which each close counts in proportion to the volume traded on its bar, so busy bars move it more than quiet ones.

VWMA = Σ(CLOSE × VOLUME) / Σ VOLUME, over the last `periods` bars

On FX the volume is the broker’s tick volume, the number of price changes in the bar, so the weights are a proxy for activity. With no volume over the whole window there is no value.

Parameters: periods, 1 to 200 (20 is common).

Returns: one number, drawn on the price. No value for the first periods − 1 bars.

Errors: a setting that fails a check stops the run with one of these messages:

  • VWMA periods must be a number
  • VWMA periods must be an integer
  • VWMA maximum periods is 200
  • VWMA periods must be at least 1

What it measures, its formula and a chart

williamsR(periods: number): number;

Larry Williams’ oscillator: where the close sits within the high-low range of a window, measured down from the top. It is the fast stochastic %K turned upside down and shifted to run from -100 to 0.

%R = -100 * (highest HIGH - CLOSE) / (highest HIGH - lowest LOW), over `periods` bars

A window with no range gives 0 (TA-Lib’s convention). Before GH-461 it took the range from closes only, and its axis was set to 0 to 100, so every value plotted off the bottom of the panel.

Parameters: periods, 1 to 100 (14 is standard).

Returns: one number, -100 to 0, on its own axis.

Errors: a setting that fails a check stops the run with one of these messages:

  • Williams %R periods must be a number
  • Williams %R periods must be an integer
  • Williams %R maximum period is 100
  • Williams %R periods must be greater than 0

What it measures, its formula and a chart

woodiePivot(): number[];

The pivot as Ken Wood calculates it: the previous trading day’s close counts twice, so the pivot leans toward where the day ended.

pivot = (HIGH + LOW + 2 × CLOSE) / 4 of the previous day
R1 = 2 × pivot − LOW S1 = 2 × pivot − HIGH
R2 = pivot + (HIGH − LOW) S2 = pivot − (HIGH − LOW)

Some charting packages weight the current day’s open instead of the previous close; this is the previous-close form, which needs nothing from the day in progress.

Days are UTC days, as for dailyPivot: the levels shown on Sunday come from Friday’s bar, and Monday’s from Friday and the Sunday session together (Friday’s high and low widened by Sunday’s, and Sunday’s close).

Parameters: none.

Returns: [R2, R1, pivot, S1, S2], five lines on the price chart.

What it measures, its formula and a chart

wma(periods: number): number;

A moving average with linear weights: the newest close counts periods times, the one before it periods - 1 times, and so on down to 1 for the oldest close in the window.

WMA = (periods * C[0] + (periods - 1) * C[1] + ... + 1 * C[periods - 1]) / (periods * (periods + 1) / 2)

where C[0] is the close of the bar that just closed. The divisor is the sum of the weights.

Parameters: periods, 1 to 100.

Returns: one number, drawn on the price chart.

Errors: a setting that fails a check stops the run with one of these messages:

  • WMA periods must be a number
  • WMA periods must be an integer
  • WMA maximum periods is 100
  • WMA periods must be greater than 0

What it measures, its formula and a chart