Pine Script indicator guide

Stochastic Momentum Index: formula, signals and Pine Script

The Stochastic Momentum Index (SMI) compares the close with the midpoint of a rolling high-low range. It smooths the distance and the range separately, then forms a centered oscillator. Use the calculation below to inspect the 10-3-3 example and distinguish range position from a trade signal.

SMI = 200 × doubleEMA(Close − Midpoint) / doubleEMA(High − Low)

Educational material, not investment advice. The example is an indicator, not a tested trading system or a forecast.

Calculate SMI from the midpoint outward

TradingView calculates the highest high and lowest low over K bars. Subtract their midpoint from the close, apply two EMAs of length D to that distance and to the range, and divide the results. A separate EMA of SMI supplies the signal line. See the official SMI formula.

The table is a constructed arithmetic example. Set D=3 and signal length=3, so each EMA uses weight 0.5 for its new input. Assume the rolling high stays 110 and low stays 90. Before row A, both distance EMAs and the signal equal 0; both range EMAs equal 20. For each pass, new EMA = 0.5 × input + 0.5 × previous EMA.

Fixed midpoint 100, double-smoothed range 20
BarCloseDistanceEMA 1EMA 2SMISignal
A102210.552.5
B10442.51.5158.75
C10664.252.87528.7518.75
D98-21.12522019.375

Row C gives 200 × 2.875 / 20 = 28.75. In row D, the close is below the midpoint, yet SMI remains positive at 20 because earlier values remain in both EMA stages. Its sign describes smoothed distance, not the position of the latest close alone.

If the smoothed range is zero, there is no defined ratio. The code returns na rather than treating missing information as neutral momentum. A single zero raw range can still leave a positive smoothed denominator. Early values also depend on EMA initialization and available chart history.

Pine Script v6 with confirmed crossover signals

The inputs are K=10, D=3, and signal EMA=3. Both smoothing passes use the same D length. The script runs on the chart timeframe and plots live lines, while its markers and alert conditions wait for the bar to close. It contains no order entries, exits, or position sizing.

Pine Script v6
//@version=6
indicator("Stochastic Momentum Index: confirmed crosses", overlay = false)

kLength = input.int(10, "%K length", minval = 1)
dLength = input.int(3, "%D length", minval = 1)
signalLength = input.int(3, "Signal EMA length", minval = 1)

emaTwice(source, length) =>
    ta.ema(ta.ema(source, length), length)

highestHigh = ta.highest(high, kLength)
lowestLow = ta.lowest(low, kLength)
priceRange = highestHigh - lowestLow
midpointDistance = close - (highestHigh + lowestLow) / 2
smoothedDistance = emaTwice(midpointDistance, dLength)
smoothedRange = emaTwice(priceRange, dLength)

// A zero smoothed range has no defined normalized position.
smi = smoothedRange > 0 ? 200 * smoothedDistance / smoothedRange : na
signal = ta.ema(smi, signalLength)

plot(smi, "SMI", color = color.blue, linewidth = 2)
plot(signal, "Signal EMA", color = color.orange)
hline(40, "Upper reference", color = color.gray)
hline(0, "Zero", color = color.new(color.gray, 50))
hline(-40, "Lower reference", color = color.gray)

// Evaluate crosses every bar, then require chart-bar confirmation.
crossUp = ta.crossover(smi, signal)
crossDown = ta.crossunder(smi, signal)
confirmedUp = crossUp and barstate.isconfirmed
confirmedDown = crossDown and barstate.isconfirmed
plotshape(confirmedUp, "Confirmed up cross", shape.triangleup, location.bottom, color.blue, size = size.tiny)
plotshape(confirmedDown, "Confirmed down cross", shape.triangledown, location.top, color.orange, size = size.tiny)
alertcondition(confirmedUp, "SMI above signal", "SMI crossed above its signal EMA on a closed chart bar.")
alertcondition(confirmedDown, "SMI below signal", "SMI crossed below its signal EMA on a closed chart bar.")

Add the script through TradingView's Pine Editor. To receive notifications, create an alert and select one of its SMI conditions; use Once Per Bar Close. An alertcondition() declaration does not itself create a running alert. Recreate the alert after changing script settings because existing alerts retain their saved configuration. See TradingView's alert documentation.

Compare the output with TradingView's built-in SMI

  1. Add TradingView's Stochastic Momentum Index and this script to the same standard candlestick chart. Do not choose SMI Ergodic Indicator or SMI Ergodic Oscillator.
  2. Set both to K=10, D=3, and EMA=3. Keep the built-in calculation timeframe equal to the chart timeframe.
  3. In the Data Window, compare both SMI and signal EMA on the same closed bars, away from the left edge where initialization can dominate. Record the symbol, exchange, timeframe, session, and timestamps.
  4. Check several positive, negative, and near-zero readings. A persistent mismatch calls for checking the input lengths, price data, timeframe, and whether each EMA stage uses the same length.
  5. Inspect flat-price periods separately. Our explicit zero-denominator branch returns na; check the built-in's actual display instead of assuming its missing-value handling.

These are comparison steps, not a claim of measured chart parity. The formula follows TradingView's published definition; actual chart values require the same data and settings. This example does not reproduce the built-in higher-timeframe selector.

A crossover can be confirmed and still fail

Consider a hypothetical sideways sequence in which SMI minus its signal reads -2, +1, then -0.5 on three consecutive closed bars. The second bar gives an upward cross; the third gives a downward cross. Both are valid confirmed events. Neither establishes a price trend, and trading both can incur two sets of costs without a useful move. Double smoothing does not eliminate this whipsaw.

  • A zero cross tests the sign of smoothed midpoint distance. A signal cross tests SMI against its own EMA. They answer different questions.
  • The +40 and -40 lines are reference levels. Remaining above +40 does not require a short trade; a trend can keep SMI above +40.
  • Longer smoothing retains more history and delays changes. Shorter lengths can react to small price moves. Test that tradeoff on fixed rules, fees, slippage, and an untouched evaluation period.

barstate.isconfirmed is true on historical bars and the closing update of a realtime bar. Here it suppresses provisional crossover markers. It does not freeze the live lines, prevent data revisions, or confirm a separate higher-timeframe request.

SMI, stochastic, and SMI Ergodic use different inputs

IndicatorQuantity being normalizedReference
SMISmoothed close-to-midpoint distance / smoothed high-low rangeCentered range position
Stochastic %KClose minus range low / high-low rangePosition from the bottom of the range
SMI Ergodic / TSI familySmoothed signed price change / smoothed absolute price changeDirection of price changes

TradingView's SMI Ergodic documentation describes the price-change ratio with an EMA signal. Its similar name does not make it interchangeable with range-based SMI. Use the True Strength Index guide for that calculation and scaling, or the Stochastic Oscillator guide for the standard range-low calculation.

Specify the SMI behavior before changing the code

Pineify's Pine Script AI Coding Agent can help create and edit a script from your requirements. Supply the formula and state which length or signal rule should change. Review the generated code and repeat the TradingView comparison before evaluating a strategy.

Keep the range-midpoint SMI formula and K=10. Change both D smoothing passes to length 5. Keep the signal EMA at 3 and mark crossovers only after the chart bar closes. Return na when the smoothed range is zero.

Syntax checking can catch code errors; it does not verify profitable rules, data parity, or future returns. Account access and model usage depend on the current product plan.

Customize SMI with the Pine Script AI Coding Agent

Stochastic Momentum Index questions

SMI measures the double-smoothed distance of the close from a rolling high-low midpoint, normalized by the double-smoothed range. A positive reading describes positive smoothed distance; it does not require the current close to be above the current midpoint.

No. This SMI uses the highest high, lowest low, and close. SMI Ergodic uses smoothed price changes divided by smoothed absolute price changes, like the True Strength Index, with a signal line. Select the full Stochastic Momentum Index name when comparing TradingView indicators.

There is no universal best setting. This example uses K=10, D=3, and a signal EMA length of 3. K selects the range window; D controls both EMA passes; the signal length smooths the resulting SMI. Compare settings with fixed trading rules and costs, then evaluate an untouched period.

The ratio is undefined when the double-smoothed high-low range is zero. The example returns na instead of a fabricated zero reading. A zero raw range on one bar does not necessarily mean the smoothed denominator is zero because EMA calculations retain earlier values.

Its current value can change as the open bar updates. The example confirms crossover markers and alert conditions at chart-bar close, while keeping the lines live. This does not remove losing signals or establish confirmation for a separate higher-timeframe data request.

No. The level is a reference for positive smoothed range position, not proof of a reversal. SMI can remain above +40 while price keeps rising. A trading system needs separate entry, exit, sizing, and cost assumptions before its results can be evaluated.

Sources and verification scope

Official documentation checked October 17, 2026. The numerical table and whipsaw sequence are constructed examples, not market results. No live TradingView output comparison or trading performance test is claimed here.

Browse more TradingView indicator guides.