Indicators
138 entries. What each one takes, what it returns, and a working example.
Accelerator Oscillator (AC) — Bill Williams momentum-acceleration oscillator. AC = AO - sma(AO, signal), where AO = sma(hl2, fast) - sma(hl2, slow).
Series: the AC value (the difference between AO and the signal SMA of AO). Insufficient early bars are None.
Note
Above/below the zero line and the color change (rising/falling bar) indicate the acceleration direction; unlike AO, it measures whether momentum is accelerating or decelerating.
v = ac() plot(v)
Adds the acceleration oscillator as a line below the chart; above zero means acceleration is rising.
Accumulation/Distribution line (CUMULATIVE). Bar contribution = ((close-low)-(high-close))/(high-low) x volume; zero contribution when high==low.
Note
Computed from the chart OHLCV; takes no arguments. accdist is CUMULATIVE (a line) while iii/wvad are per-bar values - do not confuse them.
When to use
To combine volume with price action and gauge accumulation/distribution pressure.
plot(accdist())
Plots the accumulation/distribution line in a separate pane; a rising line means buying pressure is building.
Accumulation/Distribution Line: cumulative sum of money flow volume ((C-L)-(H-C))/(H-L)*V, reflecting buying/selling pressure.
A series containing the cumulative Accumulation/Distribution value.
Note
Takes no parameters; it uses the bars' H/L/C/V values directly. On bars where (H-L)=0, that bar's contribution is taken as zero.
plot(adl(), "ADL")
Plots the accumulation/distribution line named "ADL" in a separate pane; if price rises while the line falls, the move is not backed by volume.
Directional Index — trend strength (uses H/L/C).
A series that measures trend strength between 0 and 100.
Note
Uses high/low/close. It measures the strength of the trend, not its direction; above 25 is considered a strong trend, and a separate filter is needed for direction. An adx > 25 filter screens out misleading signals in a sideways market.
When to use
To measure how strong a trend is (independent of its direction). Used as a filter to run trend-following strategies only when a strong trend is present.
Limits
It does not tell direction — only strength. Below 25 the market is considered directionless/flat. It is lagging by nature.
Not for
Do not use it alone to generate trade direction; direction comes from dmi/di lines or a separate trend filter.
Tip
An adx > 25 filter screens out misleading signals in a sideways market.
Uses high/low/close. It measures the strength of the trend, not its direction; above 25 is considered a strong trend, and a separate filter is needed for direction.
An adx > 25 filter screens out misleading signals in a sideways market.
plot(adx(14), "ADX")
Plots the 14-bar trend strength; above 25 is considered a strong trend.
strong = adx(14) > 25 bgcolor(strong ? "#26a69a26" : na)
Tints the background light green while the trend is strong (adx>25).
alligator(jaw_len=13, teeth_len=8, lips_len=5)
Williams Alligator: three forward-shifted SMMAs of hl2 (jaw 13/+8, teeth 8/+5, lips 5/+3). Returns record.jaw/.teeth/.lips.
Record:.jaw,.teeth,.lips series (each a forward-shifted SMMA; insufficient early bars are None).
Note
SMMA = rma. Shifts: jaw 8, teeth 5, lips 3 bars forward. Due to the shift, the first valid values start on the 20th/12th/7th bar respectively.
a=alligator(13, 8, 5) plot(a.jaw) plot(a.teeth) plot(a.lips)
Adds the three Alligator lines (jaw, teeth, lips) over price; when they separate there is a trend, when they intertwine the market is flat.
alma(source, length, offset=0.85, sigma=6)
Arnaud Legoux Moving Average: a Gaussian-weighted moving average that reduces lag while smoothing noise; offset shifts the bell within the window and sigma sets its width.
An Arnaud Legoux Moving Average series.
Note
The result is None for the first length-1 bars; if there is a None value in the window, that bar returns None.
plot(alma(close, 9, 0.85, 6))
Draws the 9-bar ALMA of the close over price; it turns with less lag than a plain moving average.
Awesome Oscillator: sma(hl2,5) - sma(hl2,34).
A series giving the Awesome Oscillator value; the first slow-1 bars are None due to insufficient data.
Note
The calculation is done over the (high+low)/2 average price; positive values show upward momentum and negative values downward momentum.
plot(ao(5, 34))
Plots the Awesome Oscillator in a separate pane; crossing zero upward says momentum has turned up.
apo(source?, fast=12, slow=26)
Absolute Price Oscillator — the difference between the fast and slow exponential moving averages of the source: EMA(fast) − EMA(slow).
A single series containing the EMA(fast) − EMA(slow) difference; the first (slow−1) bars are None.
Note
The EMA is computed with the SMA-seeded Wilder convention; the first valid value appears on the bar where the slow period completes.
v=apo(close, 12, 26) plot(v)
Plots the gap between the fast and slow exponential averages in a separate pane; above zero the short term has overtaken the long term.
Aroon indicator: measures trend strength from bars since the most recent high/low (0-100); osc=up-down.
Returns a record:.up (upward strength 0-100),.down (downward strength 0-100),.osc (up - down, -100..100).
Note
The window covers the last length+1 bars including this bar. up=100 indicates that a new highest peak occurred on this bar, down=100 indicates that a new lowest bottom occurred on this bar. The first length bars are None.
plot(aroon(14).osc)
Plots the Aroon oscillator (up strength minus down strength) in a separate pane; near +100 means a strong uptrend, near −100 a strong downtrend.
Accumulation Swing Index (Wilder): cumulative sum of the Swing Index, accumulating directional price movement into a single continuous line.
The cumulative Accumulation Swing Index series. The first bar is None.
Note
Uses Wilder's K/R/SI formula; requires O/H/L/C. The first bar returns None because there is no prev close.
a=asi(300) plot(a)
Draws the accumulation swing index as a single line; rising and falling together with price confirms the strength of the move.
The average of the true ranges of the last N bars; it tells how much the market moves, in price units. It says nothing about direction, only size. Used to set a stop distance or a band width independently of the symbol: 2×ATR scales to each symbol's own movement.
An Average True Range series that measures volatility in price units.
Note
It uses high, low and close; it does not take a separate source argument. Commonly used to set stop distances. close ± multiplier*atr(14) is a common pattern for stop distance.
When to use
To measure volatility in price units; to set stop-loss/take-profit distance or position size. It adapts to volatility and is symbol-independent.
Limits
It carries no directional information, only the size of the move. It uses high/low/close and takes no separate source argument.
Not for
It is not for overbought/oversold or trend direction. For percentage volatility, scale it with atr(14)/close.
Tip
close ± multiplier*atr(14) is a common pattern for stop distance.
It uses high, low and close; it does not take a separate source argument. Commonly used to set stop distances.
close ± multiplier*atr(14) is a common pattern for stop distance.
plot(atr(14), "ATR")
Plots the 14-bar average true range (volatility).
stop = close - 2 * atr(14) plot(stop, "Stop-loss")
Plots a volatility-adaptive stop-loss level 2 ATR below the close.
bb(source, length=20, stddev=2)
Bollinger Bands: draws two bands around an average that widen and narrow with the price's own volatility. It returns three values at once — `.upper`, `.middle`, `.lower` — read separately with a dot. The bands narrow in a quiet market and open when movement starts; the squeeze itself is often read as a warning of a coming move.
A three-field record:.upper (upper band),.middle (middle band),.lower (lower band).
Note
A common expectation is that price recovers as it approaches the lower band and pulls back as it approaches the upper band. Increasing stddev widens the bands and makes touches rarer.
When to use
To draw a price envelope that widens and narrows with volatility. Narrowing bands show a squeeze, widening ones show activity; band touches are used to expect a pullback.
Limits
In a strong trend price can hug one band; do not treat every band touch as a reversal. The result is empty on the first length-1 bars.
Not for
It does not give the trend direction on its own; a separate filter is needed for direction. If you only want the band width numerically, bbw or kcw are more direct.
Tip
Increasing stddev widens the bands and makes touches rarer.
A common expectation is that price recovers as it approaches the lower band and pulls back as it approaches the upper band.
Increasing stddev widens the bands and makes touches rarer.
b = bb(close, 20, 2) plot(b.upper) plot(b.middle) plot(b.lower)
Plots the three bands (upper/middle/lower); the middle band is the 20-bar average.
b = bb(close, 20, 2.5) plotshape(close > b.upper, "Upper breakout")
Marks bars where the close pushes above the upper band.
bbw(source?, length=20, stddev=2)
Bollinger Band Width: (upper - lower) / middle, measuring volatility expansion/contraction.
The band width ratio for each bar (None for the first N insufficient bars).
Note
The middle band is found with the SMA and the upper/lower bands with ±stddev standard deviation; the result is the (upper-lower)/middle ratio. It shares the same math as Bollinger Bands (bb).
plot(bbw(close, 20, 2))
Plots Bollinger band width in a separate pane; narrowing means volatility is dropping, widening means a move has started.
Balance of Power — measures buyer/seller pressure per bar as (close-open)/(high-low); near +1 means buyers dominate, near -1 means sellers dominate.
Series: a Balance of Power value for each bar (between -1 and +1); 0 if the range (high-low) is 0.
Note
There is no smoothing; you can smooth the output with sma/ema to reduce noise. On bars containing missing (None) values, the result is None.
b=bop() plot(b) plot(sma(b, 14))
Plots balance of power and its 14-bar average as two lines in a separate pane; above zero shows buying pressure.
Commodity Channel Index — deviation from mean. Without a source it uses the H/L/C typical price; cci(close, 20) selects one. ±100 common.
A series that measures the deviation of price from its average.
Note
The ±100 bands are common thresholds; above +100 signals strong upward pressure and below −100 strong downward pressure. Uses H/L/C.
When to use
To measure how far price deviates from its typical average; to use the crossing of the ±100 bands as a momentum/breakout signal.
Limits
It swings without bounds (no fixed ceiling/floor); the thresholds are relative. It uses high/low/close.
Not for
Do not expect a fixed extreme level; it is read in context. It is not a trend-direction filter.
Tip
Above +100 signals strong upward and below −100 strong downward pressure.
Above +100 signals strong upward and below −100 strong downward pressure.
plot(cci(20), "CCI")
Plots the 20-bar commodity channel index; read against the ±100 bands.
c = cci(20) plotshape(crossover(c, -100), "Bounce off low")
Marks bars where CCI crosses above −100 (a possible bottom recovery).
Chaikin Oscillator — difference between fast and slow EMAs of the Accumulation/Distribution Line; measures money flow momentum.
The Chaikin Oscillator series values (the difference of the fast EMA and slow EMA of ADL).
Note
The first slow-1 bars return None due to insufficient data. chaikinosc_series computes ADL internally.
osc = chaikinosc(3, 10) plot(osc)
Plots the Chaikin oscillator in a separate pane; crossing zero upward says money inflow is accelerating.
chandeKrollStop(p=10, x=1, q=9)
Chande Kroll Stop — ATR-based trailing long/short stop levels, smoothed by a highest/lowest window. Returns a record with.long and.short series.
Record:.long (the long trailing-stop level) and.short (the short trailing-stop level) series.
Note
The first valid value appears (p-1)+(q-1) bars later (in practice p+q-1 bars, since the ATR helper requires p bars). It returns None on insufficient bars.
v=chandeKrollStop(10, 1, 9) plot(v.long) plot(v.short)
Draws two trailing stop levels over price: the lower line for long positions, the upper one for shorts.
Choppiness Index — measures whether the market is ranging (choppy) or trending. Values near 100 indicate sideways/choppy markets; values near 0 indicate a strong trend.
A Choppiness Index value between 0 and 100 for each bar; the first (length-1) bars are None.
Note
High values (typically >61.8) indicate a ranging/consolidating market, low values (typically <38.2) indicate a strong trend; it measures only trend strength/absence, not direction.
plot(chop(14))
Plots the choppiness index in a separate pane; above 60 the market is flat and range-bound, below 40 it is trending.
Chaikin Money Flow (−1..1) — volume-weighted money flow (uses H/L/C/V).
A Chaikin Money Flow series between −1 and 1.
Note
Positive = buying pressure (close in the upper half of the bar + volume), negative = selling. Uses H/L/C/V.
enterLong(cmf(20) > 0)
Opens a long position when money flow turns positive; it draws no line, it becomes the strategy's entry condition.
Chande Momentum Oscillator
A momentum series between -100 and +100.
Note
The first length bars return None; if all movement within the window is zero, it returns 0.
plot(cmo(9), title="CMO")
Plots the Chande momentum oscillator titled "CMO" in a separate pane; above +50 is considered overbought, below −50 oversold.
Center of Gravity (Ehlers)
The center-of-gravity oscillator value (single series).
Note
No value is produced on bars where the window sum is zero and on the first length-1 bars (None).
plot(cog(close, 10))
Plots the center-of-gravity line in a separate pane; it marks turning points earlier than plain moving averages.
coppock(source?, long=14, short=11, wmaLen=10)
Coppock Curve — WMA of the sum of long and short period rate-of-change; a long-term momentum oscillator.
The Coppock Curve values (a single series). The first bars are None when there is insufficient data.
Note
A rise above zero is interpreted as a long-term buy signal.
cop = coppock(close, 14, 11, 10) plot(cop)
Plots the Coppock curve in a separate pane; turning up from below zero is read as a long-term buy signal.
Rolling Pearson correlation of two series (−1..1). Pair selection: high = move together.
A rolling Pearson correlation series between −1 and 1.
Note
A value near 1 means moving together and a value near −1 means moving inversely; used in pair selection.
correlation(close, sym("LTCUSDT").close, 50)
Computes the relationship between this symbol's close and LTCUSDT's close over the last 50 bars; it draws nothing, a value near +1 means the two move together.
covariance(a, b, length, biased?)
Rolling covariance of two series (co-movement; UNSCALED unlike correlation). biased defaults to true → population (÷length); false → sample (÷length-1) — same convention as arrayVariance.
Rolling covariance series; the first length-1 bars and bars with missing values in the window are empty.
Note
Unlike correlation, covariance is UNSCALED (depends on the series units) and is not normalized to -1..1. Use correlation for a comparable measure.
plot(covariance(close, open, 20))
Plots the 20-bar co-movement of close and open in a separate pane; unlike correlation its scale is not normalised.
crsi(rsiLen=3, streakLen=2, rankLen=100)
Connors RSI — the average of three components: RSI of price, RSI of the streak length, and the percent rank of the rate of change. Measures short-term extremes.
A single series in the 0-100 range (the Connors RSI value).
Note
It is the average of three components: the RSI of close, the RSI of the consecutive up/down streak series, and the percent rank of the 1-bar change. The first valid value is produced after the rankLen bar.
v=crsi(3, 2, 100) plot(v)
Plots Connors RSI in a separate pane; it reacts faster than the classic RSI, above 90 and below 10 count as extremes.
Correlation Trend Indicator (Ehlers): Pearson correlation between price and the time index over the last `length` bars (-1..1).
A single series: a correlation value between -1 and 1 (the first length-1 bars are None).
Note
The time axis is fixed at 0..length-1 within the window; if the denominator is zero (constant price), it returns 0.0.
v=cti(close, 20) plot(v)
Plots the trend indicator measuring how price tracks time in a separate pane; near +1 means a steady rise, near −1 a steady fall.
Cumulative highest from the start of the chart.
A cumulative series holding the highest value seen from the start of the chart up to each bar (it never falls).
Note
Each bar is the maximum of all values so far; the value only rises when a new peak appears and never falls. Gap (na) values are skipped.
When to use
To track the all-time high or to compute the pullback from the peak (drawdown).
Limits
There is no window — it always accumulates from the start of the chart; for a rolling maximum use highest.
Not for
It is not for the highest of the last N bars (that is highest); cumMax covers the whole history.
plot(cumMax(close), "All-time high")
Plots the highest close seen since the start of the chart.
dd = (cumMax(close) - close) / cumMax(close) * 100 plot(dd, "Drawdown from peak %")
Plots how far, in percent, price has pulled back from its all-time high.
Cumulative lowest from the start of the chart.
A cumulative series holding the lowest value seen from the start of the chart up to each bar (it never rises).
Note
Each bar is the minimum of all values so far; the value only falls when a new bottom appears and never rises. Gap (na) values are skipped.
When to use
To track the all-time low or to follow floor levels.
Limits
There is no window — it always accumulates from the start of the chart; for a rolling minimum use lowest.
Not for
It is not for the lowest of the last N bars (that is lowest); cumMin covers the whole history.
plot(cumMin(close), "All-time low")
Plots the lowest close seen since the start of the chart.
plot(cumMin(low), "Lowest level")
Plots the lowest price (low) seen since the start of the chart.
cybercycle(source?, length=20)
Ehlers Cyber Cycle oscillator
A cycle value series oscillating around zero; the first 6 bars are None for warmup.
Note
Supports None-safe chaining: warmup Nones in the source series are preserved, and computation is done over the valid tail then mapped back to the original indices.
cc = cybercycle(close, 20) plot(cc, "Cyber Cycle") plot(0, "Zero")
Plots the cycle oscillator named "Cyber Cycle" with a zero line beside it in a separate pane; zero crossings mark where the cycle turns.
Ehlers Decycler — removes the high-pass component from the source to suppress short cycles and leave the trend: decycler = source - highpass(source, length).
A bar-by-bar Decycler series; the first 2 bars are None (high-pass initialization).
Note
decycler = source - highpass(source, length); it preserves the low-frequency trend and removes cycles shorter than length.
dc = decycler(close, 60) plot(dc)
Draws a trend line with short swings filtered out over price; it lags less than plain moving averages.
Double Exponential Moving Average (DEMA): combines an EMA of the source with an EMA of that EMA to produce a reduced-lag curve.
A double exponential moving average series.
Note
Because two nested EMAs are used, roughly the first 2*length-1 bars return None.
plot(dema(close, 20))
Draws the 20-bar double exponential average of the close over price; it turns faster than a plain average of the same length.
Average absolute deviation (ta.dev): mean of |source - sma(source, length)| over the window.
A mean absolute deviation series for each bar; the first (length-1) bars are None.
Note
basis = sma(source, length), dev = mean(|source - basis|) within the window.
plot(dev(close, 10))
Plots the average deviation of the close from its 10-bar average in a separate pane; a rise means price is moving away from the average.
Disparity Index: percentage distance of close from its own simple moving average. (close − sma(close, length)) / sma(close, length) × 100. Uses close when no source is given.
A single series: the percentage distance of the close from its SMA (%) for each bar.
Note
Oscillates around the zero line; extreme positive/negative values can point to overbought/oversold zones. The first (length−1) bars are empty due to warmup.
d = disparity(14) plot(d)
Plots how far the close sits from its own 14-bar average as a percentage, in a separate pane; above zero price is above the average.
Directional movement → returns record:.plus (+DI),.minus (−DI),.adx (trend strength).
A three-field record:.plus (+DI),.minus (−DI),.adx (0–100 trend strength).
Note
Direction: if +DI > −DI the uptrend dominates. Strength: adx > 20–25 means a meaningful trend. Fields are accessed with a dot.
d = dmi(14) enterLong(crossover(d.plus, d.minus) and d.adx > 20)
Opens a long position when +DI crosses above −DI while trend strength is over 20; it draws nothing, it becomes the strategy's entry condition.
Donchian Channels → record:.upper,.middle,.lower (highest/lowest).
A three-field record:.upper (highest high),.middle,.lower (lowest low).
Note
Common in breakout strategies: enter when price passes.upper, exit when it breaks.lower.
dc = donchian(20) enterLong(crossover(close, prev(dc.upper, 1)))
Opens a long position when price breaks above the previous bar's 20-bar high; the channel is not drawn, the breakout is used as a condition.
Detrended Price Oscillator: source displaced by length/2+1 bars minus the simple moving average of source over length, highlighting short-term cycles by removing the trend.
A Detrended Price Oscillator series; a detrended value that oscillates around zero.
Note
The shift is length/2+1 bars; the first length-1 bars return None. It does not follow the trend, but emphasizes short-term cycle peaks/troughs.
plot(dpo(close, 21))
Plots the detrended price oscillator in a separate pane; it exposes short-term cycle peaks and troughs.
Elder Ray — bull/bear power. bull = high - EMA(close, length); bear = low - EMA(close, length).
Record:.bull (the bull power series) and.bear (the bear power series).
Note
The EMA is computed over the close price; the first (length-1) bars are empty due to insufficient data.
er = elderray(13) plot(er.bull) plot(er.bear)
Plots bull and bear power as two lines in a separate pane; bull above zero means buyers dominate, bear below zero means sellers do.
Weights recent bars more heavily when averaging, so it catches turns earlier than `sma` but also gives more false signals. The influence of old bars never fully disappears, it just fades. Preferred in trend following when a fast reaction matters.
An exponential moving average series that gives more weight to recent bars.
Note
Catches price reversals earlier than sma; in return it may produce more misleading signals during sudden moves. Crossing two EMAs (e.g. 9 and 21) is a common fast trend filter.
When to use
When you need an average that reacts faster than the simple one; preferred for short-term trend following and crossover signals.
Limits
Because it weights recent bars it can produce more misleading signals in a noisy market. It uses a warm-up value at the start, so the value has not settled on the first bars.
Not for
Do not feed it a series that contains gaps (na) during warm-up — ema does not tolerate gaps. Pass a gap-free series or a raw price series (close) instead.
Tip
Crossing two EMAs (e.g. 9 and 21) is a common fast trend filter.
Catches price reversals earlier than sma; in return it may produce more misleading signals during sudden moves.
Crossing two EMAs (e.g. 9 and 21) is a common fast trend filter.
plot(ema(close, 21), "EMA21")
Plots the 21-bar exponential average; reflects price turns earlier than SMA.
f = ema(close, 9) s = ema(close, 21) plotshape(crossover(f, s), "Buy signal")
Places a mark when the fast EMA crosses above the slow one.
Ease of Movement: smoothed measure of how easily price moves relative to volume.
An Ease of Movement value for each bar (a series); the first length bars are None.
Note
Positive values indicate that price moves upward easily, negative values indicate easy downward movement, and values near zero indicate little price movement despite high volume.
plot(eom(length=14))
Plots ease of movement in a separate pane; above zero price is rising easily on little volume.
Fisher Transform oscillator (record:.fisher /.trigger).
Record:.fisher (the Fisher oscillator) and.trigger (the fisher value of the previous bar).
Note
No dependency beyond the math.log standard library. hl2 = (high+low)/2 is normalized over the last `length` bars; the value is clamped to ±0.999, and the fisher and normalized value are smoothed with the 0.5/0.66/0.67 coefficients (Ehlers convention).
f = fisher() plot(f.fisher)
Plots the Fisher transform in a separate pane; it produces sharp peaks at extremes, making turning points stand out.
Force Index: smooths the product of price change and volume with an EMA(length) to gauge the strength behind a move.
The Force Index series smoothed with an exponential moving average.
Note
Above the zero line indicates buying pressure, below it indicates selling pressure; the distance measures the strength of the move.
plot(forceindex(length=13))
Plots the force index in a separate pane; above zero shows buying pressure backed by volume.
Forecast Oscillator
An oscillator series in percentage terms; it oscillates around the zero line. Positive = price is above the forecast line, negative = below it.
Note
The first length-1 bars are empty due to warmup (None). It is plotted together with the zero line.
o = fosc(14) plot(o) plot(0)
Plots the forecast oscillator with a zero line beside it in a separate pane; above zero price sits above its own trend line.
Williams Fractal — reversal points over a 5-bar window. Up fractal when the middle bar's high exceeds both neighbors on each side; down fractal when its low is below all of them. Marks the center bar with a 2-bar lag.
Record:.up (up fractal, a bool series) and.down (down fractal, a bool series). The mark is placed on the middle bar and is delayed by 2 bars.
Note
Uses a 5-bar window; the first and last two bars cannot be computed (None). The comparison is a strict inequality (equality does not count as a fractal).
f=fractal() plot(f.up) plot(f.down)
Marks turning points over price: top fractals appear above, bottom fractals below.
Fractal Adaptive Moving Average (FRAMA) by Ehlers
A FRAMA value for each bar (the first length-1 bars are None).
Note
Uses the chart's high/low/close series. Based on the fractal dimension, it reacts quickly in a trend and slowly in a range.
f = frama(16) plot(f) plot(close)
Draws the fractal adaptive average together with the close over price, so you can compare side by side how much the average lags.
gator(jaw_len=13, jaw_shift=8, teeth_len=8, teeth_shift=5, lips_len=5, lips_shift=3)
Gator Oscillator
Record:.upper (the absolute jaw-teeth difference, ≥0) and.lower (the negative of the absolute teeth-lips difference, ≤0).
Note
Derived from the Alligator; computed with an SMMA (Wilder RMA) over the median price (H+L)/2 and shifted into the future. The value is empty on the first bars (equal to the shift + the period).
v=gator(13, 8, 8, 5, 5, 3) plot(v.upper) plot(v.lower)
Plots the upper and lower arms of the Gator oscillator in a separate pane; both growing means the trend is strengthening, both shrinking means the market is going quiet.
Hull Moving Average — low lag + smooth (catches turns early).
A Hull moving average series.
Note
Gives a smooth curve with low lag; shows reversals earlier than classic moving averages.
plot(hma(close, 20))
Draws the 20-bar Hull average of the close over price; it catches turns noticeably earlier than a plain average.
Historical Volatility (%) Uses close when no source is given.
A historical volatility series annualized, expressed as a percentage.
Note
It is computed over closing prices; the sample (N-1) standard deviation of the ln(close/close[1]) log returns is annualized with sqrt(365) and multiplied by 100. The first 'length' bars (while there are not enough returns) produce no value.
plot(hv(length=10), title="HV %")
Plots historical volatility as a percentage titled "HV %" in a separate pane; a rise means price swings are getting wider.
Intraday Intensity Index - per-bar value (NOT cumulative): (2*close - high - low) / ((high-low) * volume). Empty when the denominator is 0.
Note
Computed from the chart OHLCV; takes no arguments. accdist is CUMULATIVE (a line) while iii/wvad are per-bar values - do not confuse them.
When to use
To combine volume with price action and gauge accumulation/distribution pressure.
plot(iii())
Plots the intraday intensity index in a separate pane; it is computed per bar, not cumulatively.
inertia(length=20, rviLength=14)
Inertia (Cardwell) — RVI smoothed with linear regression; a trend-persistence indicator.
The Inertia series (a single value); the first (length-1)+(rviLength-1)+3 bars are None.
Note
RVI is computed with the swma method; when the denominator is zero, that bar returns None. Inertia > 0 indicates a bullish, < 0 a bearish bias.
myInertia = inertia(20, 14) plot(myInertia)
Plots the inertia indicator in a separate pane; above 50 the trend is continuing, below it is weakening.
kama(source, length=10, fast=2, slow=30)
Kaufman Adaptive Moving Average (KAMA): adapts its smoothing constant via the efficiency ratio, reacting fast in trends and slow in choppy ranges.
A Series containing the KAMA values; the first length bars are None.
Note
Efficiency ratio = |change over length bars| / |sum of the bar-by-bar changes|. A high ER means a trend, and KAMA approaches the fast coefficient; a low ER means a ranging market, and it approaches the slow coefficient.
k = kama(close, 10, 2, 30) plot(k)
Draws the Kaufman adaptive average over price; it tracks price closely in trends and flattens out in sideways markets, filtering false turns.
Keltner Channels → record:.upper,.middle,.lower (mid = ema, band = ±mult·atr).
A three-field record:.upper,.middle,.lower.
Note
Middle = ema(close, length); band = middle ± mult·atr(length). Similar to Bollinger but the band is scaled by ATR.
k = kc(20, 2) enterLong(crossover(close, k.upper))
Opens a long position when price breaks above the upper Keltner band; the channel is not drawn, the breakout is used as a condition.
kcw(source?, length=20, mult=1)
Keltner Channel Width = (upper-lower)/middle.
A series giving the Keltner channel width relative to the middle line (upper minus lower divided by the middle band).
Note
The middle line is ema(source, length) and the band distance is mult*atr(length); the result is 2*mult*atr/middle. A smaller value means a narrowing channel (squeeze), a larger one a widening channel (volatility). It uses high/low/close (for atr).
When to use
To numerically track a volatility squeeze (low width) or expansion; used as a threshold in post-squeeze breakout strategies.
Limits
It carries no direction. If the middle line is very close to zero (extremely low price) the result can be empty.
Not for
It is not for drawing the channel's own levels (upper/lower band) — that is what kc is for; this gives only the width.
plot(kcw(close, 20, 1.5), "Channel width")
Plots the Keltner channel width; low values indicate a squeeze.
squeeze = kcw(close, 20, 1.5) < 0.03 bgcolor(squeeze ? "#ffee5833" : na)
Tints the background yellow when width drops below 3% (a squeeze).
KDJ — stochastic-based momentum indicator..k and.d are smoothed stochastic lines,.j (=3K-2D) is a more sensitive early-reversal line.
Record:.k (the %K line),.d (the %D line),.j (3K−2D). The first length+m1+m2−2 bars are None.
Note
The J line can exceed the 0..100 range (intentional; an early overbought/oversold signal). If the Highest-Lowest range is zero, that bar is None.
k = kdj(9, 3, 3) plot(k.k) plot(k.d) plot(k.j)
Plots the three KDJ lines (K, D, J) in a separate pane; K crossing above D is read as a buy signal, below as a sell signal.
kst(source?, r1=10, r2=15, r3=20, r4=30, s1=10, s2=10, s3=10, s4=15, signal=9) ->.kst,.signal
Know Sure Thing (Pring) momentum oscillator: weighted sum of four smoothed ROCs plus a signal line.
Record:.kst (the main line) and.signal (the signal line).
Note
KST above/below the zero line indicates the long-term momentum direction, while KST crossing the signal indicates reversal signals.
k = kst(close) plot(k.kst) plot(k.signal)
Plots the KST line and its signal line in a separate pane; KST crossing above the signal is read as a long-term momentum turn.
kvo(fast=34, slow=55, signal=13)
Klinger Volume Oscillator: difference of fast/slow EMAs of trend-aware volume force, plus an EMA signal line.
Record:.kvo (the oscillator line) and.signal (the signal line).
Note
Volume force is computed from the trend determined by the direction of the intraday (H+L+C) value and the ratio of the high-low range to the cumulative measure. The first value appears on the slow bar.
k = kvo() plot(k.kvo)
Plots the Klinger volume oscillator in a separate pane; above zero volume is supporting the advance.
linreg(source, length, offset=0)
Linear regression value — endpoint of the least-squares line.
The value of the least-squares line at the last bar.
Note
Used to track the direction and slope of the trend in a smooth way.
plot(linreg(close, 20))
Draws the end value of the 20-bar regression line of the close over price, showing price's statistical trend as a smooth line.
macd(source, fast=12, slow=26, signal=9)
MACD → returns record:.macd,.signal,.histogram.
A three-field record:.macd (main line),.signal (signal line),.histogram (the difference of the two).
Note
Fields are accessed with a dot. First assign it to a variable: m = macd(close), then use m.macd and m.signal.
When to use
To track trend direction and momentum change together. The MACD line crossing the signal, or the histogram crossing zero, is a classic momentum signal.
Limits
It produces frequent, misleading crossovers in a flat/choppy market. fast must be < slow; otherwise the reading is inverted.
Not for
It does not give overbought/oversold levels (it swings without bounds) — that is what rsi/stoch are for. It is not a fixed support/resistance level either.
Tip
Access fields with a dot: first m = macd(close), then use m.macd, m.signal and m.histogram.
Access fields with a dot: first m = macd(close), then use m.macd, m.signal and m.histogram.
m = macd(close) plot(m.macd, "MACD") plot(m.signal, "Signal")
Plots the MACD main line together with the signal line; watch their crossovers.
m = macd(close, 12, 26, 9) plot(m.histogram, "Histogram", style="histogram")
Plots the difference of the two lines (histogram) as bars; the zero crossing marks a momentum turn.
mama(fastLimit=0.5, slowLimit=0.05)
MESA Adaptive Moving Average (Ehlers MAMA/FAMA): adapts to the cycle via Hilbert-transform phase; mama is fast, fama is slow. Record.mama /.fama.
Record:.mama (the fast adaptive MA) and.fama (the slow following MA). The first 6 bars are None due to warmup.
Note
Computed over the source (H+L)/2 (hl2). mama crossing fama upward is interpreted as a buy signal, crossing downward as a sell signal.
m = mama(0.5, 0.05) plot(m.mama) plot(m.fama) cross_up = m.mama > m.fama
Draws the MAMA and FAMA lines over price and stores in a variable whether MAMA is above FAMA; the crossover is read as a trend turn.
Mass Index — sums the ratio of a single 9-EMA to a double 9-EMA of the high-low range over length, flagging reversal bulges from range expansion.
A bar-by-bar Mass Index series; insufficient early bars are None.
Note
The inner EMAs have a fixed 9-period length (classic definition). A rise above 27 followed by a return below 26.5 (reversal bulge) signals a possible trend reversal.
v = massindex(25) plot(v)
Plots the mass index in a separate pane; rising above 27 and turning back signals the trend may reverse.
McGinley Dynamic — an adaptive moving average that speeds up or slows down with price velocity, hugging price during fast moves and smoothing during quiet periods.
A series containing a McGinley Dynamic value for each bar.
Note
k=0.6 is fixed. The first bar is seeded with the raw source, so there is no insufficient-data period (it produces no None).
md = mcginley(close, 14) plot(md)
Draws the McGinley Dynamic line over price; it moves closer to price in fast moves and drifts away in quiet periods.
Rolling median: the median of the last `length` bars of the source.
A series holding, for each bar, the median value of the last length bars.
Note
The first length-1 bars return None due to insufficient data. Unlike the average, the median is robust to outliers (extreme values).
plot(median(close, 20), "Median")
Draws the 20-bar median of the close named "Median" over price; it is less affected by occasional extreme bars than an average.
Money Flow Index — volume-weighted strength. Without a source it uses the H/L/C typical price; mfi(close, 14) selects one.
A money flow index series between 0 and 100.
Note
It is like an rsi that also takes volume into account; below 20 and above 80 are the extreme zones.
enterLong(crossunder(mfi(14), 20))
Opens a long position when the money flow index drops below 20; it draws no line, it is used as an oversold entry.
Most frequent value in the window (smallest on ties).
A series holding the most frequently repeated value in the window; on a tie the smallest value is chosen.
Note
It looks at the frequency of values in the last length bars; if several values share the top frequency it returns the smallest. The result is empty (na) on the first length-1 bars.
When to use
To find the most repeated level in discrete or rounded values (e.g. the most common value of rounded prices).
Limits
With continuous (decimal) prices most values are unique, so it usually returns the first value; a rounded/discrete input is generally needed for it to be meaningful. na on the first length-1 bars.
Not for
Do not use it in place of a mean or median — that is what sma/median are for; mode looks for the most frequent value.
plot(mode(close, 20), "Most frequent value")
Plots the most frequent close value over the last 20 bars.
plot(mode(round(close), 30), "Mode")
Plots the most frequent value of the rounded close over the last 30 bars.
Momentum: difference between the source price and the source price length bars ago (source - source[length]).
A series of the difference between source and source length bars ago.
Note
The result is empty (None) on the first length bars because there is not enough data.
plot(mom(close, 10))
Plots the difference between the close and 10 bars ago in a separate pane; above zero price is higher than it was 10 bars back.
Negative Volume Index - accumulates price change on bars where volume DROPS, carries otherwise. Seed value 1.0 matching the reference definition.
Note
A cumulative/multiplicative index seeded at 1.0, so values stay around 1.0 (e.g. 0.78-1.25). Do NOT confuse it with the classic 1000-based variant. NVI is read as "smart money", PVI as "the crowd".
When to use
To separate price action by volume state (low-volume vs high-volume days).
plot(nvi())
Plots the negative volume index in a separate pane; it only moves on bars where volume falls, tracking price direction on quiet days.
On-Balance Volume — cumulative volume flow.
A cumulative On-Balance Volume series.
Note
It adds volume when the close rises and subtracts it when it falls; shows the direction of volume flow.
plot(obv())
Plots cumulative volume flow in a separate pane; the line rising along with price means the move is backed by volume.
percentileLinear(source, length, percent)
Percentile via linear interpolation (rolling).
A series giving the linearly interpolated percentile of the values in the last length bars.
Note
This is the short-name form of the exact same computation as percentile_linear_interpolation: the window is sorted and the percentile is interpolated between two neighboring values. The result is empty on the first length-1 bars.
When to use
To obtain a slice of the price distribution smoothly with in-between values (when the short spelling is preferred).
Limits
It requires sorting; heavier over long windows. na on the first length-1 bars.
Not for
If you want an actual observation from the window, use percentileNearestRank.
plot(percentileLinear(close, 50, 75), "P75")
Plots the interpolated 75th percentile of the last 50 closes.
plot(percentileLinear(close, 30, 50), "Median")
pct=50 gives the median; plots the middle value of the last 30 bars.
percentileNearestRank(source, length, percent)
Percentile via nearest-rank method (rolling).
A series giving the nearest-rank percentile from the values in the last length bars (always an actual observation).
Note
This is the short-name form of the exact same computation as percentile_nearest_rank: the window is sorted and the actual value at the matching rank is returned (no interpolation). The result is empty on the first length-1 bars.
When to use
When you need an actual value from the window for a given percentile (when the short spelling is preferred).
Limits
It gives a stepped result; less smooth than the interpolated version. na on the first length-1 bars.
Not for
If you want a smooth, in-between threshold, percentileLinear is more suitable.
plot(percentileNearestRank(close, 50, 25), "P25")
Plots the actual value at the 25th percentile of the last 50 closes.
plot(percentileNearestRank(high, 50, 95), "P95")
Plots the 95th percentile of the last 50 highs as an upper band.
percentile_linear_interpolation(source, length, percent)
Percentile with linear interpolation.
A series giving the requested percentile of the values in the last length bars, computed with linear interpolation.
Note
The window is sorted and the percentile is found by a weighted transition (interpolation) between two neighboring values; the result need not equal an actual value in the window. pct 50 gives the median. The result is empty on the first length-1 bars.
When to use
To obtain a given slice of the price distribution (e.g. the 90th percentile of the last 50 bars) smoothly with in-between values; used to build adaptive bands/thresholds.
Limits
It requires sorting, so it is heavier over long windows. The result is empty on the first length-1 bars.
Not for
If you do not want an interpolated value but an actual observation from the window, use percentile_nearest_rank.
plot(percentile_linear_interpolation(close, 50, 90), "P90")
Plots the interpolated 90th percentile of the last 50 closes.
hi = percentile_linear_interpolation(high, 50, 95) plot(hi, "Upper 95% band")
Plots the 95th percentile of the last 50 highs as an adaptive upper band.
percentile_nearest_rank(source, length, percent)
Nearest-rank percentile.
A series giving the percentile selected by the nearest-rank method from the values in the last length bars (always an actual value in the window).
Note
The window is sorted and the actual value at the rank matching the percentile is returned; no interpolation is done, so the result is always one of the window's observations. The result is empty on the first length-1 bars.
When to use
When you need an actual price value from the window for a given percentile (cases where an interpolated value is undesirable).
Limits
It gives a stepped result; less smooth than the interpolated version. na on the first length-1 bars.
Not for
If you want a smooth, in-between threshold, percentile_linear_interpolation is more suitable.
plot(percentile_nearest_rank(close, 50, 90), "P90")
Plots the actual value at the 90th percentile of the last 50 closes.
lo = percentile_nearest_rank(low, 50, 10) plot(lo, "Lower 10% band")
Plots the 10th percentile of the last 50 lows as a lower band.
percentrank(source=close, length=20)
Percent rank: percentage of values over the last `length` bars that are less than or equal to the current value (0..100).
A percentile rank series between 0 and 100; the first length bars are None.
Note
The ratio of values within the last length bars that are less than or equal to the current value is computed as a percentage.
plot(percentrank(close, 20))
Plots where the close ranks within the last 20 bars, as a percentage, in a separate pane; near 100 means price is at the top of that window.
Pretty Good Oscillator — the distance of close from its N-bar average divided by the average true range; used to spot the start of trends.
A single series: (close - sma(close,length)) / ema(atr(length),length). The first ~2*length-1 bars are None.
Note
Since atr_series contains a None-warmup, it is not passed directly to ema; the valid tail is taken, ema is computed, and mapped back to the original indices. Because close is raw OHLC, no extra precaution is needed for sma. If the denominator is zero, that bar is None.
p = pgo(14) plot(p)
Plots the Pretty Good Oscillator in a separate pane; above +3 or below −3 signals a new trend is starting.
Classic daily pivot from previous day H/L/C, aligned to intraday bars.
The classic daily pivot level (from the previous day's H/L/C).
Note
It is aligned to the intraday bar; used as a support/resistance reference.
plot(pivot(), "Pivot")
Draws the classic pivot level computed from the previous day, named "Pivot", as a horizontal reference over price.
Array of pivot levels [P,R1,S1,...] (Traditional/Fibonacci/Woodie/Classic/Camarilla/DM). Result: Arr(len=11, [97.98980608998066, 102.87125151674475, 91.26689934718658, 109.59415825953883])
An 11-element array: [Pivot, R1, S1, R2, S2, R3, S3, R4, S4, R5, S5]; indexed with brackets (lv[0]=Pivot). Depending on the method the upper levels can be empty (na).
Note
Levels are computed from the high/low/close of the last COMPLETED period (the bars between the two starts marked by anchor). If type is omitted "Traditional" is used. Woodie and DM also account for the open; DM produces only Pivot, R1 and S1, with the rest empty. Index the array: lv = pivotLevels(...), then lv[0] is Pivot, lv[1] R1, lv[2] S1.
When to use
To automatically compute and draw periodic (e.g. weekly/monthly) pivot support-resistance levels according to an anchor series.
Limits
It returns a single current set of levels (not bar-by-bar); a completed period does not form until anchor is true at least twice. Unused levels stay na depending on the method. type must be a static string.
Not for
Do not expect a separate rolling pivot series per bar — the output is a fixed set of levels for the last completed period. For the classic single intraday pivot, pivot/r1/s1 are more direct.
Tip
Index the array: lv = pivotLevels(...), then lv[0] is Pivot, lv[1] R1, lv[2] S1.
Levels are computed from the high/low/close of the last COMPLETED period (the bars between the two starts marked by anchor). If type is omitted "Traditional" is used. Woodie and DM also account for the open; DM produces only Pivot, R1 and S1, with the rest empty.
Index the array: lv = pivotLevels(...), then lv[0] is Pivot, lv[1] R1, lv[2] S1.
lv = pivotLevels("Traditional", barIndex % 50 == 0) plot(lv[0], "Pivot") plot(lv[1], "R1") plot(lv[2], "S1")
Treating every 50th bar as a period start, plots the Pivot, R1 and S1 levels.
lv = pivotLevels("Fibonacci", barIndex % 100 == 0) plot(lv[0], "P") plot(lv[3], "R2") plot(lv[4], "S2")
Plots Pivot, R2 and S2 with the Fibonacci method over 100-bar periods.
pivothigh(leftbars=2, rightbars=2)
A peak: a bar with no higher bar within the given number of bars to its left and right. Because the bars on the right must form first, a peak is only confirmed that many bars LATER — it does not appear on the newest bar of a live chart. Used to build resistance levels or draw zones.
A series of pivot-high peak values; None on non-pivot bars. The value fills in with a rightbars-bar delay due to right-side confirmation.
Note
A pivot must be strictly greater than all of the leftbars bars to its left and the rightbars bars to its right (equality does not count as a pivot). Because right-side confirmation is required, the value appears rightbars bars after the pivot bar.
ph=pivothigh(2, 2) plot(ph)
Marks swing highs over price; a bar counts as a high only if it tops the two bars on each side, and it is confirmed two bars later.
pivotlow(leftbars=2, rightbars=2)
A trough: a bar with no lower bar within the given number of bars to its left and right. It works by the same rule as `pivothigh` and is likewise confirmed only after the bars on the right have formed. Used to build support levels.
The pivot-low price on the confirmation bar; empty (na) on non-pivot bars.
Note
The center bar must make a lower low than all of the leftbars bars to its left and the rightbars bars to its right. The value is written to the bar where the pivot is confirmed (center + rightbars); therefore there is no look-ahead. It is the low counterpart of the Pivot High indicator.
pl=pivotlow(2, 2) plot(pl)
Marks swing lows over price; a bar counts as a low only if it undercuts the two bars on each side, and it is confirmed two bars later.
ppo(source, fast=12, slow=26, signal=9)
Percentage Price Oscillator: percentage difference between fast and slow EMAs relative to the slow EMA, with a signal line (EMA of PPO) and histogram (PPO minus signal).
Record:.ppo (the oscillator %),.signal (the signal line),.hist (histogram = ppo - signal). The first slow-1 bars are None, while the signal/histogram start after the slow+signal-2 bar.
Note
Same logic as MACD but uses a percentage relative to the slow EMA instead of an absolute difference; this brings symbols at different price levels to a comparable scale.
p = ppo(close, 12, 26, 9) plot(p.ppo) plot(p.signal) plot(p.hist)
Plots the PPO line, its signal line and the histogram in a separate pane; it is like MACD but on a percentage scale, so symbols at different prices can be compared.
Previous completed daily close aligned to intraday bars.
The close of the previous full day (aligned to the intraday bar).
Note
For accessing the previous day's close on an intraday chart.
plot(prevClose(), "Prev Close")
Adds the previous full day's close as a horizontal line named "Prev Close" over price; it serves as a reference level on intraday charts.
Previous completed daily high aligned to intraday bars.
The high of the previous full day (aligned to the intraday bar).
plot(prevHigh(), "Prev High")
Adds the previous full day's high as a horizontal line named "Prev High"; you can watch whether it is broken during the day.
Previous completed daily low aligned to intraday bars.
The low of the previous full day (aligned to the intraday bar).
plot(prevLow(), "Prev Low")
Adds the previous full day's low as a horizontal line named "Prev Low"; you can watch whether it is broken during the day.
Positive Volume Index - accumulates price change on bars where volume RISES, carries otherwise. Seed value 1.0 matching the reference definition.
Note
A cumulative/multiplicative index seeded at 1.0, so values stay around 1.0 (e.g. 0.78-1.25). Do NOT confuse it with the classic 1000-based variant. NVI is read as "smart money", PVI as "the crowd".
When to use
To separate price action by volume state (low-volume vs high-volume days).
plot(pvi())
Plots the positive volume index in a separate pane; it only moves on bars where volume rises, tracking where the crowd is going.
pvo(fast=12, slow=26, signal=9)
Percentage Volume Oscillator
Record:.pvo (the oscillator value),.signal (the signal line),.hist (histogram = pvo - signal). The first N bars are None when data is insufficient.
Note
Same calculation logic as PPO, applied to volume instead of close. A positive PVO indicates that the fast volume average is above the slow one (increasing volume interest).
v = pvo(12, 26, 9) plot(v.pvo) plot(v.signal) plot(v.hist)
Plots the volume oscillator, its signal line and histogram in a separate pane; above zero volume has been picking up recently.
Price Volume Trend: cumulative ((close-close[1])/close[1])*volume; weights volume by the percentage price change to track the direction of buying/selling pressure.
The cumulative Price Volume Trend series (a single series).
Note
Standard cumulative PVT math is used. The first bar starts from 0; if the prev close is 0, that bar's contribution is skipped to avoid division by zero. Similar to OBV, but it weights by the percentage price change rather than the full volume.
plot(pvt())
Plots the price-volume trend in a separate pane; it accumulates volume weighted by the percentage change in price.
Price Zone Oscillator. Scales the EMA of (sign of price change times close) divided by the EMA of close, expressed as a percentage; above zero shows buying pressure, below zero selling pressure.
A single series: a PZO value for each bar (the first length-1 bars are None).
Note
ema_series starts with an SMA (Wilder), so the first valid value is on the length-1 bar.
o = pzo(14) plot(o) plot(0)
Plots the price zone oscillator with a zero line beside it in a separate pane; zero crossings show control passing between buyers and sellers.
Qstick — simple moving average of (close − open); measures candle-body buying/selling pressure.
The simple moving average of the close − open difference over a length window (a single series).
Note
A positive value indicates buyer dominance, a negative value indicates seller dominance; the first length-1 bars are None.
q = qstick(10) plot(q)
Plots the 10-bar average of close minus open in a separate pane; above zero most bars are closing higher than they opened.
plot(r1(), "R1")
Adds the first resistance level computed from the previous day as a horizontal line named "R1" over price.
plot(r2(), "R2")
Adds the second resistance level as a horizontal line named "R2"; it is watched as the next target once R1 is broken.
Rolling range: highest - lowest.
A series giving the difference between the highest and lowest value in the last length bars (the range width).
Note
It is computed as highest(source, length) − lowest(source, length); a volatility/range measure in price units. The result is empty on the first length-1 bars.
When to use
To measure the price spread (top-to-bottom distance) over a window; to build a squeeze/expansion or breakout threshold.
Limits
It carries no direction, only the width. For the bar-to-bar true range use tr, and for a single bar's high-low use high−low.
Not for
It is not for a single bar's high-low; this is the range over a length-bar window.
plot(range(close, 20), "20-bar range")
Plots the gap between the highest and lowest close over the last 20 bars.
plot(range(close, 10) / close * 100, "Range %")
Plots the 10-bar range relative to price as percentage volatility.
RCI (Rank Correlation Index): Spearman rank correlation between price rank and time rank over length, scaled to -100..100.
A series of RCI values between -100 and 100; the first length-1 bars are None.
Note
A value near +100 indicates a strong uptrend, a value near -100 indicates a strong downtrend. For equal prices the average rank is used.
plot(rci(close, 9))
Plots the rank correlation index in a separate pane; above +80 counts as a strong up bias, below −80 a strong down bias.
relvol(source?, length=14, stdevLen=10)
Relative Volatility Index — applies RSI logic to the rolling standard deviation of close (Dorsey). Up-bar and down-bar standard deviations are smoothed separately with Wilder RMA; rvi = 100*up/(up+down), bounded 0-100. source is an optional first argument (relvol(close, 14, 10)); defaults to close if omitted. In order and by name forms all give the same result: relvol(14, 10) · relvol(length=14, stdevLen=10) · relvol(close, 14, stdevLen=10).
A single series oscillating between 0 and 100 (the RVI value)
Note
The stdev of close is population based (divided by N). The up and down standard deviations are smoothed separately with Wilder RMA; therefore the first stdevLen-1 + length bars return None.
Limits
In order and by name forms all give the same result: relvol(close, 14, 10) · relvol(14, 10) · relvol(length=14, stdevLen=10) · relvol(close, 14, stdevLen=10).
plot(relvol(close, 14, 10))
Plots the relative volatility index in a separate pane; it reads like RSI but measures the direction of volatility rather than price.
Wilder RMA (running moving average) — building block of rsi/atr; reacts slower than ema.
A Wilder RMA series.
Note
The smoothing used inside rsi and atr. At the same period it reacts more slowly than ema.
plot(rma(close, 14))
Draws the 14-bar Wilder average of the close over price; this is the average used inside RSI and ATR, reacting more slowly than a plain exponential average.
rmi(source?, length=14, momentum=4)
Relative Momentum Index — a momentum variant of RSI where up/down differences are taken over `momentum` bars back, then Wilder-smoothed with rma(length): 100 * rma(up) / (rma(up) + rma(down)).
An RMI series in the 0–100 range; the warmup bars are None.
Note
The first valid value appears on the momentum + length - 1 bar (bar 17 with the defaults).
src = close r = rmi(src, 14, 4) plot(r, "RMI") plot(70, "Upper") plot(30, "Lower")
Plots the relative momentum index named "RMI" in a separate pane together with the 70 and 30 boundary lines; above 70 is overbought, below 30 oversold.
Rate of Change (percent).
A percent change (Rate of Change) series.
Note
Measures momentum; a positive value shows the speed of a rise and a negative value the speed of a fall.
enterLong(roc(close, 10) > 5)
Opens a long position when price has risen more than 5 percent over the last 10 bars; it draws no line, it is used as a momentum entry.
roofing(source?, hp=48, lp=10)
Ehlers Roofing Filter — a two-stage band-pass: a 2-pole high-pass filter (period hp) removes the low-frequency trend/DC, then a 2-pole Super Smoother (period lp) removes high-frequency noise, leaving a clean zero-centered oscillator.
A filtered oscillator series oscillating around zero; the first 2 bars are empty due to warmup.
Note
It is a two-stage band-pass filter: first a 2-pole high-pass with period hp filters the trend/DC component, then a Super Smoother with period lp filters the high-frequency noise. It is recursive; on a constant input the output falls to zero.
rf = roofing(close, 48, 10) plot(rf) plot(0)
Plots the roofing filter with a zero line beside it in a separate pane; it strips out both the long-term trend and the noise, leaving the cycle in between.
Compares the total strength of gains against losses over the last N bars and gives a number between 0 and 100. Above 70 is usually read as overbought and below 30 as oversold — but in a strong trend it can stay there for a long time, so it is not a reversal signal on its own. It reads more reliably in a sideways market.
A relative strength series that oscillates between 0 and 100.
Note
Above 70 is considered overbought and below 30 oversold. It is more reliable evaluated together with the trend direction rather than on its own. Lowering the length (e.g. 7) makes it more jittery, raising it makes it smoother.
When to use
To measure overbought/oversold zones or to look for divergence between price and the indicator. Its most reliable use is filtered together with the trend direction.
Limits
In a strong trend it can stay above 70 or below 30 for a long time; reading that alone as a reversal is misleading. The source series should have no gaps.
Not for
Not for measuring trend strength — adx does that. Do not decide trades on a threshold crossing alone; evaluate it together with direction.
Tip
Lowering the length (e.g. 7) makes it more jittery, raising it makes it smoother.
Above 70 is considered overbought and below 30 oversold. It is more reliable evaluated together with the trend direction rather than on its own.
Lowering the length (e.g. 7) makes it more jittery, raising it makes it smoother.
plot(rsi(close, 14), "RSI")
Plots the 14-bar relative strength index in the 0–100 range.
r = rsi(close, 14) bgcolor(r > 70 ? "#ef535026" : na)
Tints the background light red while RSI is above 70 (overbought warning).
Relative Vigor Index: swma(close-open)/swma(high-low) summed over length, signal=swma(rvi).
Record:.rvi (the main line) and.signal (the swma signal of rvi).
Note
SWMA has a fixed length of 4; it returns None on the first bars and when the denominator is zero.
v = rvi(10) plot(v.rvi) plot(v.signal)
Plots the relative vigor index and its signal line in a separate pane; the main line crossing above the signal is read as a buy signal.
Random Walk Index — measures how strongly price trends relative to a random walk. rwiHigh gauges uptrend strength, rwiLow downtrend strength. Access via.high /.low.
Record:.high (uptrend strength) and.low (downtrend strength). Above 1 is considered a sign of a trend, below 1 a sign of random/sideways movement.
Note
The first length bars return None. atr(k) is computed with Wilder ATR; the existing atr_series helper is called directly.
r = rwi(14) plot(r.high) plot(r.low)
Plots the up and down arms of the random walk index in a separate pane; when one is clearly above 1, the move is directional rather than random.
plot(s1(), "S1")
Adds the first support level computed from the previous day as a horizontal line named "S1" over price.
plot(s2(), "S2")
Adds the second support level as a horizontal line named "S2"; it is watched as the next stop once S1 gives way.
sar(start=0.02, inc=0.02, max=0.2)
Parabolic SAR (stop and reverse): trend-following stop levels driven by an accelerating factor, plotted as points that flip sides on trend reversals.
The Parabolic SAR values (a single series); it produces dots below price in an uptrend and above price in a downtrend.
Note
The first bar is None; the trend starts from the second bar. AF increases by inc at each new extreme point, is capped by max, and resets to the start value on a trend reversal.
plot(sar(0.02, 0.02, 0.2))
Scatters Parabolic SAR dots around price; dots below price mean an uptrend, and flipping above them marks a reversal.
Sums the closes of the last N bars and divides by the count, smoothing noise so the direction shows. A longer window makes the line slower and the signals later; a shorter one sticks to price and gives more false turns. It weights every bar equally — for a line more sensitive to recent bars use `ema`.
A series holding, for each bar, the arithmetic mean of the last length bars.
Note
The result is empty (na) on the first length-1 bars because there is not enough data. The larger the length, the smoother the line but the greater the lag.
When to use
To smooth price and read the main trend direction, or to use price being above/below the average as a signal. Crossing a short and a long length gives the classic crossover strategy.
Limits
The result is empty (na) on the first length-1 bars. Because it weights all bars equally it reacts to reversals later than ema and lags on sudden moves.
Not for
Not ideal if you want to catch reversals early — ema or more responsive averages (hma, wma) are better for that. It is not for measuring volatility either; that is what atr/stdev are for.
Tip
The larger the length, the smoother the line but the greater the lag.
The result is empty (na) on the first length-1 bars because there is not enough data.
The larger the length, the smoother the line but the greater the lag.
plot(sma(close, 20), "SMA20")
Plots the 20-bar simple average on the price panel.
fast = sma(close, 10) slow = sma(close, 50) plot(fast, "Fast") plot(slow, "Slow")
A fast and a slow average; their crossovers read as trend turns.
smi(length=10, smooth1=3, smooth2=3)
Stochastic Momentum Index
Record:.smi (Stochastic Momentum Index, -100..+100) and.signal (the smooth2 EMA of SMI).
Note
Uses the chart's H/L/C series. It returns None for the first length-1 bars plus the double-EMA lag. On bars where den=0, smi is None.
v = smi(10, 3, 3) plot(v.smi) plot(v.signal)
Plots the stochastic momentum index and its signal line in a separate pane; unlike the classic stochastic it oscillates around zero.
stc(source?, fast=23, slow=50, cycle=10)
Schaff Trend Cycle — a trend oscillator (0..100) derived by applying a double stochastic cycle to MACD
A single series oscillating between 0 and 100; used for trend direction and reversal points
Note
The first bars are empty until the slow EMA is ready (warmup equal to the slow length). The values come from MACD's double-stage stochastic cycle; they saturate at 0 or 100 in strong trends.
v=stc(close, 23, 50, 10) plot(v)
Plots the Schaff trend cycle in a separate pane; it swings between 0 and 100, and turning up from below 25 is read as the start of a trend.
Rolling standard deviation (volatility, for z-score).
A rolling standard deviation (volatility) series.
Note
Commonly used for the Z-score: (close − sma(close,n)) / stdev(close,n).
z = (close - sma(close,20)) / stdev(close,20)
Computes how many standard deviations the close sits from its 20-bar average; it draws nothing and keeps the result in a variable.
stoch(length=14, smoothK=1, smoothD=3, source?, highSrc?, lowSrc?)
Stochastic oscillator (0–100) → returns record:.k,.d. Default H/L/C; source/highSrc/lowSrc apply it to other series.
A two-field record:.k (fast line) and.d (signal line); between 0 and 100.
Note
Below 20 is considered oversold and above 80 overbought. Default high/low/close; with source/highSrc/lowSrc it can be applied to another series (e.g. an indicator output). It returns a two-field record: s = stoch(14,3,3), then use s.k and s.d.
When to use
To find where price closes within the last N-bar range and look for overbought/oversold and momentum turns. %K crossing %D is the classic signal.
Limits
It can give early counter-trend signals in a trending market. It uses high/low/close.
Not for
It is not for trend strength. If the raw %K is too noisy, increase smoothK.
Tip
It returns a two-field record: s = stoch(14,3,3), then use s.k and s.d.
Below 20 is considered oversold and above 80 overbought. Uses high/low/close.
It returns a two-field record: s = stoch(14,3,3), then use s.k and s.d.
s = stoch(14, 3, 3) plot(s.k, "%K") plot(s.d, "%D")
Plots the %K and %D lines together; read against the 20/80 bands.
s = stoch(14, 1, 3) plotshape(crossover(s.k, s.d), "K above D")
Marks bars where %K crosses above %D (momentum turns up).
stochRsi(rsiSource=close, rsiLen=14, stochLen=14, smoothK=3, smoothD=3)
Stochastic of RSI (0–100) → returns record:.k,.d. Measures overbought/oversold on RSI.
A two-field record:.k (fast line) and.d (signal line); between 0 and 100.
Note
First RSI is computed, then a stochastic is applied to the RSI; identical to stoch(stochLen, smoothK, smoothD, rsi, rsi, rsi). It is more sensitive than plain RSI because it measures RSI's position within its own range.
When to use
To catch momentum turns in RSI overbought/oversold zones early. %K crossing %D is the classic signal.
s = stochRsi(close, 14, 14, 3, 3) plot(s.k, "%K") plot(s.d, "%D")
Plots %K and %D over the RSI; read against the 20/80 bands.
s = stochRsi(close, 14, 14, 3, 3) plotshape(crossover(s.k, s.d), "K above D")
Marks bars where %K crosses above %D (RSI momentum turns up).
supersmoother(source, length=10)
Ehlers Super Smoother (2-pole Butterworth filter); smooths the price series with low lag.
A smoothed value series; the first 2 bars are None.
Note
A 2-pole Butterworth Super Smoother; the coefficient sum is 1 (DC gain 1), and it converges to the same constant on a constant input.
ss = supersmoother(close, 10) plot(ss)
Draws the super-smoothed price line over price; it cleans up noise with less lag than plain moving averages.
When .direction changes sign, the trend reverses. .line sits below price in an uptrend and above price in a downtrend.
Symmetrically weighted moving average with fixed length 4 and weights [1,2,2,1]/6.
A symmetrically weighted moving average series.
Note
The length is fixed (4) and the weights are [1,2,2,1]/6; therefore it does not take a length parameter. The first 3 bars return None due to warmup.
plot(swma(close))
Draws an average that smooths the last four closes with symmetric weights over price; it is a very short-window, light smoothing.
t3(source, length=8, vfactor=0.7)
Tillson T3 moving average: six chained EMAs blended with a volume factor for a low-lag, smooth line.
A Tillson T3 moving average series (the first bars are empty due to insufficient data).
Note
Because of the chain of six consecutive EMAs, roughly the first 6*(length-1) bars produce no value.
plot(t3(close, 8, 0.7))
Draws the Tillson T3 average over price; stacked exponential averages give a curve that is both smooth and low-lag.
Triple exponential moving average (TEMA): 3*EMA - 3*EMA(EMA) + EMA(EMA(EMA)), reducing lag relative to a single EMA.
A triple exponential moving average series (a value for each bar; the first 3·(length−1) bars are empty).
Note
TEMA compensates in a compound manner for the lag created by applying the EMA three times; it reacts faster to price reversals than the classic EMA.
plot(tema(close, 21))
Draws the 21-bar triple exponential average of the close over price; it turns faster than single and double averages of the same length.
Trend Intensity Index — ratio of summed positive deviations to total deviations (×100) over a window.
A single series in the 0-100 range; the first (majorLen-1 + minorLen-1) bars are None due to insufficient data.
Note
The 50 reference line separates direction: when the value is above 50, upward pressure dominates; when below, downward pressure dominates. If all deviations are zero, the result is taken as 50.
t = tii(60, 30) plot(t) plot(50)
Plots the trend intensity index together with a 50 line in a separate pane; above 50 the up bias is dominant.
True Range (no smoothing): max(H−L, |H−prevC|, |L−prevC|).
A True Range series.
Note
max(H−L, |H−prev C|, |L−prev C|); no smoothing. It is the unsmoothed form of ATR.
plot(tr())
Plots each bar's true range in a separate pane; because it accounts for gaps it can be wider than the raw high-low difference.
Triangular Moving Average (TRIMA): a double-smoothed moving average that weights the middle bars of the window most heavily by applying SMA twice to the source.
A series containing the triangular moving average value for each bar; the first (length-1) bars are None due to insufficient data.
Note
Computed with two nested SMAs: first an SMA with a ceil((n+1)/2) window, then an SMA with a floor(n/2)+1 window. The total warmup time is length-1 bars.
close_trima = trima(close, 20) plot(close_trima)
Draws the 20-bar triangular average of the close over price; it weights the middle of the window more, so its tip is smooth.
TRIX: momentum oscillator measuring the 1-bar percent rate of change of a triple-smoothed EMA of the source, scaled by 10000.
The TRIX value for each bar (insufficient first bars are None).
Note
Due to the triple EMA, roughly the first 3*(length-1)+1 bars return None; division by zero is guarded.
plot(trix(close, 18))
Plots TRIX in a separate pane; crossing zero upward shows momentum has changed direction, and triple smoothing keeps it noise-free.
Time Series Forecast: one-bar-ahead projection of the linear regression line.
A one-bar-ahead linear regression forecast for each bar; the first length-1 bars are None.
Note
Identical to linreg(source, length, offset=-1); offset=-1 projects the line onto the next bar (x=length).
src = close f = tsf(src, 14) plot(f)
Draws the time series forecast over price; it projects the regression line one bar ahead, so it runs in front of price.
tsi(source?, long=25, short=13)
True Strength Index (TSI): double-EMA of price momentum divided by double-EMA of absolute momentum, times 100.
A TSI momentum series that oscillates between -100 and +100.
Note
Momentum is the difference of the source from the previous bar; because of the double EMA smoothing, roughly the first long+short+1 bars return None.
plot(tsi(close, 25, 13))
Plots the true strength index in a separate pane; double smoothing makes it one of the least noisy momentum oscillators.
ttmsqueeze(length=20, bbMult=2, kcMult=1.5)
TTM Squeeze — detects when Bollinger Bands contract inside the Keltner Channel. Squeeze ON (.on) marks low-volatility compression that often precedes a breakout; momentum (.mom) shows directional strength.
Record:.on (bool — is the squeeze on) and.mom (float — the linear-regression momentum).
Note
.on is None for the first length+1 bars due to ATR warmup;.mom returns None for the first ~2*length-2 bars, since linreg warmup is added on top of the source warmup. The BB standard deviation is population (biased) based, consistent with the bbands convention.
sq = ttmsqueeze(20, 2, 1.5) plot(sq.mom, "TTM Momentum") barcolor(sq.on, "#ff5252")
Plots squeeze momentum named "TTM Momentum" in a separate pane and colours the bars red while the squeeze lasts; when the colouring stops, the move has begun.
ulcerindex(source?, length=14)
Ulcer Index — downside-only volatility (risk) measure: root-mean-square of percent drawdowns from the rolling highest close. Uses close when no source is given.
An Ulcer Index value for each bar (≥ 0); the first length-1 bars are None.
Note
Penalizes only declines (drawdowns); unlike standard deviation, upward movement does not increase risk. A higher value = a deeper/longer decline.
ui = ulcerindex(14) plot(ui)
Plots the ulcer index in a separate pane; it measures only the depth and duration of drawdowns, so it reads as a risk gauge.
Ultimate Oscillator: a 0-100 momentum oscillator combining buying-pressure/true-range ratios over three periods (fast/mid/slow) with 4-2-1 weights.
A single series in the 0-100 range (the Ultimate Oscillator value); the first `slow` bars are None.
Note
Buying pressure BP = close - min(low, prev close); true range TR = max(high, prev close) - min(low, prev close). For each period the average = Σ(BP)/Σ(TR); UO = 100*(4*fast + 2*mid + slow)/7. Standard Williams math is applied.
plot(uo(7, 14, 28))
Plots the Ultimate Oscillator in a separate pane; combining three windows gives fewer false signals than single-window oscillators.
valueWhen(condition, source, occurrence=0)
Value of source at the bar where the condition was true for the nth time.
A series carrying, from that bar onward, the source value at the bar where the condition was last true (going n occurrences back).
Note
When the condition is true the source value is captured and held on later bars; n=0 gives the most recent occurrence, n=1 the previous one. If the condition has never occurred yet the result is empty (na).
When to use
To remember, on later bars, the price/value at the moment an event occurred (e.g. the last crossover price, the last peak, the indicator value at the last signal).
Limits
It returns na until the condition first occurs. If there are not enough past occurrences for n it also returns na.
Not for
It is not for COUNTING the condition; it returns the VALUE at the moment of the event.
vw = valueWhen(crossover(close, sma(close,20)), close) plot(vw, "Last crossover price")
Plots a line holding the close at the bar where price last crossed above SMA20.
hi = valueWhen(high == cumMax(high), high) plot(hi, "Last peak price")
Remembers and plots the high at the bar where the most recent new peak was made.
Rolling population variance (mean of squared deviations from the moving average over length bars; equals stdev squared).
A population variance series of the source over the last length bars.
Note
Variance is the average of the squared deviations from the mean (moving average); it equals the square of the standard deviation (stdev) and measures the dispersion of the series.
plot(variance(close, 20))
Plots the 20-bar variance of the close in a separate pane; it is the square of standard deviation, so it grows quickly as volatility rises.
Vertical Horizontal Filter (VHF) — measures trend strength as the ratio of the high-low close range over a window to the sum of absolute bar-to-bar close changes.
A VHF value for each bar (trend strength; high = trending, low = ranging).
Note
The first length-1 bars are None; if the window's sum of absolute changes is zero, that bar is None.
v = vhf(28) plot(v)
Plots the vertical horizontal filter in a separate pane; a rise means the market is trending, a fall means it is going sideways.
vidya(source?, length=14, cmoLen=9)
Chande's Variable Index Dynamic Average; smoothing factor scaled by absolute CMO so it reacts fast in strong trends and slow in flat markets.
A VIDYA value series for each bar; the first cmoLen bars are None.
Note
The smoothing coefficient k = (2/(length+1)) * |CMO|; CMO approaches 0 in a ranging market and locks onto the average source.
v = vidya(close, 14, 9) plot(v)
Draws the VIDYA average over price; it speeds up when momentum rises and slows down in quiet periods.
Volume Oscillator — percentage difference between a fast and slow EMA of volume.
The volume oscillator series (percentage); the first (slow-1) bars are None.
Note
The source volume is the chart's volume; it does not take a separate source. Positive = volume is above the slow average.
v=vo(5, 10) plot(v)
Plots the volume oscillator in a separate pane; above zero recent volume has moved above its longer-run average.
Vortex Indicator (VI+ / VI-): measures trend direction strength by comparing upward and downward vortex movements to the true range.
A two-field record:.plus (VI+, upward strength) and.minus (VI-, downward strength).
Note
Crossovers of VI+ and VI- are read as trend-reversal signals; both typically oscillate around 1.0.
v = vortex(14) plot(v.plus)
Plots the up arm of the vortex indicator in a separate pane; rising above 1 shows upward pressure is increasing.
vwap(anchor?, stdevMult?, source?)
Volume weighted average price. Without `anchor` (the default) it is cumulative from the start of the chart. `anchor="session"/"week"/"month"` resets at the exchange-local start of the day/week/month (or a CONDITION series can be given directly — it resets on bars where that is true). With `stdevMult` it returns a {value,upper,lower} record together with a volume weighted standard deviation band. `source` picks the price the calculation is based on (default: the bar's typical price, (high+low+close)/3); give it BY NAME — writing `vwap(hlc3)` makes hlc3 be read as `anchor` and the VWAP then resets on every bar.
If neither anchor nor stdevMult is given: a volume-weighted average price series (plain series, cumulative). If stdevMult is given: a {value, upper, lower} record.
Note
A reference level commonly used in intraday trading; whether price is above or below the VWAP gives a directional cue. By default it does not reset on a new session; pass `anchor="session"` if you want it to reset every session. Price crossing above the VWAP reads as intraday strength, below it as weakness.
When to use
To use the volume-weighted average price as a reference level in intraday trading; price being above/below the VWAP gives a directional cue. Use `anchor=` when a level that resets every day/week/month is wanted; add `stdevMult=` for a volatility band around the VWAP.
Limits
If `anchor` is a session-period string (it needs the exchange-local day/week/month boundary), the symbol's timezone must be resolvable — if it is not (e.g. a US stock without bridge metadata/classification) it raises a clear error. It is meaningless without volume.
Not for
It is not designed as a long-term (weekly/monthly) trend average; its real use is intraday.
Tip
Price crossing above the VWAP reads as intraday strength, below it as weakness.
A reference level commonly used in intraday trading; whether price is above or below the VWAP gives a directional cue.
Price crossing above the VWAP reads as intraday strength, below it as weakness.
plot(vwap(), "VWAP")
Plots the volume-weighted average price as a reference line.
plotshape(crossover(close, vwap()), "Above VWAP")
Marks bars where the close crosses above the VWAP.
Volume-weighted moving average — more weight on high-volume bars.
A volume-weighted average series.
Note
Weight = bar volume; low-volume bars affect the average less.
plot(vwma(close, 20))
Draws the 20-bar volume-weighted average of the close over price; high-volume bars pull the line more.
vzo(source?, volume?, length=14)
Volume Zone Oscillator
The Volume Zone Oscillator series (approximately between -100 and +100); a positive value indicates that directional volume is buyer-dominant, a negative value indicates it is seller-dominant.
Note
The first length-1 bars return None due to warmup. If the EMA volume is zero, that bar is None (division-by-zero protection).
v = vzo(close, volume, 14) plot(v)
Plots the volume zone oscillator in a separate pane; above +40 is a strong buying zone, below −40 a strong selling zone.
Williams Accumulation/Distribution — cumulative accumulation/distribution line from H/L/C.
The cumulative Williams A/D line (a single series).
Note
Does not use volume; it computes cumulative accumulation/distribution using only H/L/C. The first bar starts at 0 as the cumulative base.
plot(wad())
Plots the Williams accumulation/distribution line in a separate pane; if price makes a new high and the line does not, that is a divergence.
WaveTrend (LazyBear) momentum oscillator computed on hlc3; wt1 is the main line and wt2 its 4-period SMA
Record:.wt1 (the main WaveTrend line) and.wt2 (the 4-period simple moving average of wt1)
Note
Crossovers of wt1 and wt2 are used as signals; the extreme zones indicate overbought/oversold
wt = wavetrend(10, 21) plot(wt.wt1) plot(wt.wt2)
Plots the two WaveTrend lines in a separate pane; the main line crossing the signal in extreme zones is read as a reversal signal.
Williams Vix Fix — measures fear/volatility spikes via (highest(close,length)-low)/highest(close,length)*100.
A single series: a Williams Vix Fix value for each bar (percentage).
Note
Uses the chart's H/L/C data; the first (length-1) bars return None due to insufficient data.
v=williamsvixfix(22) plot(v)
Plots the Williams Vix Fix in a separate pane; sharp spikes mark panic selling, that is, a possible bottom area.
Williams %R (−100..0): >−20 overbought, <−80 oversold.
A Williams %R series that oscillates between −100 and 0.
Note
Above −20 is interpreted as overbought and below −80 as oversold.
plot(willr(14))
Plots Williams %R in a separate pane; above −20 is overbought and below −80 oversold, on a scale from zero to −100.
Weighted Moving Average — highest weight on the latest bar (1..length).
A weighted moving average series.
Note
The most recent bar is given the highest weight; weights increase from 1 up to length.
plot(wma(close, 20))
Draws the 20-bar weighted average of the close over price; the newest bar carries the largest weight.
Williams %R — close relative to the last N-bar high/low (-100..0).
A Williams %R series that oscillates between −100 and 0.
Note
It uses high/low/close. The scale is inverted: values near 0 mark the top (overbought) and values near −100 the bottom (oversold); above −20 is overbought and below −80 oversold.
When to use
To look for overbought/oversold by measuring, inversely, where price sits in the last N-bar range; very similar to stochastic, just with a different scale.
Limits
It can stay at the extremes for a long time in a trend. The fixed ceiling is 0 and the floor is −100.
Not for
It is not for trend direction/strength. Do not expect a positive scale — the values are negative.
plot(wpr(14), "Williams %R")
Plots the 14-bar Williams %R in the −100…0 range.
w = wpr(14) plotshape(crossover(w, -80), "Bounce off low")
Marks bars where the indicator crosses above −80 (a possible bottom recovery).
Williams Variable Accumulation/Distribution - per-bar value: (close-open)/(high-low) * volume. Empty when high==low.
Note
Computed from the chart OHLCV; takes no arguments. accdist is CUMULATIVE (a line) while iii/wvad are per-bar values - do not confuse them.
When to use
To combine volume with price action and gauge accumulation/distribution pressure.
plot(wvad())
Plots the Williams variable accumulation/distribution in a separate pane; it is computed per bar, not cumulatively.
Zero-Lag EMA: an EMA applied to lag-compensated source data (src + (src - src[lag])), reducing the lag inherent in a standard EMA.
A series of Zero-Lag EMA values; the first (lag + length - 1) bars are None.
Note
lag = floor((length-1)/2). A lag-compensation term is added to the source (src + (src - src[lag])), then the EMA is applied.
plot(zlema(close, 20))
Draws the 20-bar zero-lag exponential average of the close over price; lag compensation keeps it closer to price than a plain exponential average.
Rolling z-score: how many standard deviations the source is from its window mean, (src - sma) / stdev.
A z-score series for each bar; the first length-1 bars are None.
Note
The standard deviation is population (biased) based. If the standard deviation in the window is zero, the value returns 0.0.
plot(zscore(close, 20))
Plots the 20-bar z-score of the close in a separate pane; around +2 and −2 price is statistically in extreme territory.
nirengi(sensitivity=3, length=10, shortThreshold=0)
Nirengi — trend baseline (©LeventAlgo). A smoothed middle line, a band that widens when the market is calm and narrows when the move strengthens, and a rule that waits for price to clear the line decisively before turning. `kisaEsik`: how strong a move must be before turning to SELL (0 = free, the default) → record: .line, .direction, .guc.
Record: `.line` trend baseline (price scale), `.direction` +1 up / −1 down, `.guc` 0-100 trend strength.
Note
©LeventAlgo. The middle line smooths out price noise; the band widens when the market is calm and narrows as the move strengthens; the line waits for price to clear it decisively before turning. Use `.guc` to filter out signals when trend strength is low.
n = nirengi(3, 10) plot(n.line, "Pivot") plot(n.guc, "Strength")
Plots the Nirengi trend line and its strength value separately; the line marks the base of the trend and the strength shows how much it can be relied on.