TradingView indicator calculations

Gann HiLo Activator: high-low averages and state changes

The Gann HiLo Activator selects a high-side or low-side moving-average reference according to price. A close above the prior high average selects the low side; a close below the prior low average selects the high side. The exact behavior between those thresholds depends on the implementation. This guide implements the publicly documented Sierra Chart recurrence, with explicit neutral startup and decisions made only at the chart bar close.

See the decision guide

A public recurrence with explicit startup

Sierra Chart attributes its HiLo study to Robert Krausz's New Gann Swing Chartist article. For length n, define U[t] as the mean of high[t-1] through high[t-n], and D[t] as the mean of low[t-1] through low[t-n]. Its recurrence selects D[t] when close[t] > U[t], selects U[t] when close[t] < D[t], and otherwise retains the preceding activator value. Its color also persists between thresholds. Equality belongs to the hold case.

  • The example uses n = 3 and standard chart OHLC. Its startup policy is our explicit choice: direction = 0 and activator = unavailable until the first qualifying confirmed close. No bullish default is assumed.
  • At least n preceding bars are required. With bars numbered from 1, the earliest decision is bar n + 1. Flat data can stay neutral indefinitely. Require non-missing OHLC and low <= open, close <= high on the current bar and every bar in the preceding window; never fill missing prices with zero.
  • For equal lengths and valid bars with high >= low, U >= D. Therefore the two strict conditions cannot both be true. If U = D and close equals that value, hold the preceding state.

Recalculate every decision on ten synthetic bars

All numbers below are hypothetical price units, not market data or performance results. Use n = 3 and assume open equals close on every row. Each U / D pair averages exactly the previous three rows; the current row supplies the tested close. A dash means unavailable. Values are rounded for display only. The direction is a stored indicator state, not an account position.

  • At bar 4, U = (11 + 12 + 13) / 3 = 12 and D = (9 + 10 + 11) / 3 = 10. Close 13 selects 10. Including bar 4 would instead give U = 13; the strict comparison would fail.
  • At bar 5, close 11 equals D. The activator stays at 10, even though the new low average is 11. Holding a number and holding a direction are different operations.
  • At bar 10, the line changes from 10 to 11.3333 without a direction change. Alerts based on every line movement would not match reversal alerts.
BarHigh / Low / ClosePrior U / DState after closeActivator
111 / 9 / 10-Neutral-
212 / 10 / 11-Neutral-
313 / 11 / 12-Neutral-
414 / 12 / 1312 / 10Up: first state10
513 / 10 / 1113 / 11Up: lower tie, hold10
612 / 9 / 9.513.3333 / 11Down: reversal13.3333
715 / 13 / 1413 / 10.3333Up: reversal10.3333
811 / 8 / 913.3333 / 10.6667Down: reversal13.3333
915 / 13 / 1412.6667 / 10Up: reversal10
1015 / 14 / 14.513.6667 / 11.3333Up: same state11.3333

A fully confirmed whipsaw still loses direction repeatedly

Bars 7, 8, and 9 alternate Up, Down, Up at closes 14, 9, and 14. Each reversal passes the confirmed-close rule. If an illustrative trader could reverse one unit exactly at those closes, the long leg from 14 to 9 would lose 5 units and the short leg from 9 to 14 would lose another 5, before costs. Those assumed fills are arithmetic examples, not achievable execution claims or a backtest.

  • Waiting for the close removes a temporary intrabar crossing from this decision rule. It does not prevent the next completed bar from crossing the opposite threshold.
  • A longer average changes the thresholds and may delay a reversal. It cannot be assumed to reduce total losses. Compare several nearby lengths with fixed entry, exit, costs, and fill rules on a reserved later sample.
  • The selected line is not a ratcheting stop: an Up reference can decrease as low observations change. A line or alert also places no broker order and guarantees no fill price across a gap.

Why two HiLo scripts can disagree

A shared name does not establish identical formulas. The author of Modified Gann HiLo Activator on TradingView describes alternative input construction, a median method, and a multiplier. Those additions define another calculation. This page does not copy that script or claim to reproduce every public version.

  • The carried activator is not always today's lower or upper threshold. Do not replace the two-average test with a crossover of the carried line without treating that as a new rule.
  • Use the same symbol feed, session, standard chart type, timeframe, length, and history when comparing output. A period counts chart bars, not automatically days.
  • Gann Fan geometry and Square of 9 price constructions are separate topics. This HiLo calculation uses averages and a recurrence; it provides no angle-based or numerological price forecast.
Choice to inspectThis exampleAlternative and consequence
Comparison referencePrior high and low SMAsCurrent averages include the tested bar and can change a boundary decision.
Inside-band behaviorHold the numeric activator and directionRetain direction but plot its newly calculated average; bar 5 would show prior low SMA 11 instead of 10.
Average and lengthOne length, SMA on high and lowEMA, median, separate lengths, or transformed inputs produce different values.
StartupNeutral until a strict qualifying closeAn initial Up or Down seed produces a line before our first state.
Decision timeConfirmed chart barAn open-bar test can flip temporarily as the last price moves.

Pine Script v6 with a neutral seed and reversal alerts

This independently written indicator implements the recurrence above on the chart timeframe. It keeps the displayed value unchanged while the current bar is open. The first Up or Down state has no reversal marker; later changes between +1 and -1 do. The Data Window exposes both preceding averages and the stored state for comparison with the table.

  • The SMA function can skip missing prices. The separate 0/1 validity average prevents using an older observation to replace a missing bar within the exact preceding window. If current OHLC is invalid or any prior window bar is invalid, retain the old state and activator, suppress reversal signals, and show readiness 0. The retained line is stale, not a fresh decision; prior averages are hidden when their window is invalid.
  • After a bad bar, wait until it has left the preceding n-bar window and the current bar is valid. A missing open or close also invalidates a window bar even if its high and low exist. For n = 3, a bad bar 5 blocks decisions on bars 5 through 8; bar 9 can resume if bars 6 through 9 are valid.
  • For an intrabar check, take prior U = 13 and D = 11 with stored Up state and activator 10. A temporary last price of 10.5 does nothing while the bar is open. A final close of 11.5 retains Up and 10; a final close of 10.5 selects Down and 13.
  • Create an alert from the chosen reversal condition and use Once Per Bar Close. Recreate alerts after changing the script or inputs so the saved alert configuration matches the intended test.
  • This script has no request.security call. A chart bar closing does not by itself confirm an independently requested higher-timeframe bar. Do not extend the confirmation claim to a different script.
  • Syntax acceptance cannot establish formula equivalence or profitability. Check intermediate numbers and the tie, flat-data, warm-up, and whipsaw cases separately.
The missing else branch intentionally retains both stored variables. This is an indicator with alert conditions, not order placement or a trading strategy.pine
//@version=6
indicator("HiLo: prior SMA, confirmed hold", overlay = true)
int length = input.int(3, "SMA length", minval = 1)
bool validBar = not na(open) and not na(high) and not na(low) and not na(close) and high >= low and high >= math.max(open, close) and low <= math.min(open, close)
float priorValidFraction = ta.sma(validBar ? 1.0 : 0.0, length)[1]
bool validWindow = bar_index >= length and not na(priorValidFraction) and priorValidFraction == 1.0
float upperCandidate = ta.sma(high, length)[1]
float lowerCandidate = ta.sma(low, length)[1]
float upper = validWindow ? upperCandidate : na
float lower = validWindow ? lowerCandidate : na
bool ready = validBar and validWindow and not na(upper) and not na(lower)
var int direction = 0
var float activator = na
int previousDirection = nz(direction[1], 0)
if barstate.isconfirmed and ready
    if close > upper
        direction := 1
        activator := lower
    else if close < lower
        direction := -1
        activator := upper
bool upReversal = barstate.isconfirmed and ready and direction == 1 and previousDirection == -1
bool downReversal = barstate.isconfirmed and ready and direction == -1 and previousDirection == 1
plot(activator, "Confirmed activator", color = direction == 1 ? color.teal : color.orange, linewidth = 2, style = plot.style_stepline)
plot(upper, "Prior high SMA", display = display.data_window)
plot(lower, "Prior low SMA", display = display.data_window)
plot(direction, "State: +1 up, -1 down, 0 neutral", display = display.data_window)
plot(ready ? 1 : 0, "Valid current bar and prior window", display = display.data_window)
plotshape(upReversal, "Up reversal", shape.triangleup, location.belowbar, color.teal, text = "UP", size = size.tiny)
plotshape(downReversal, "Down reversal", shape.triangledown, location.abovebar, color.orange, text = "DN", size = size.tiny)
alertcondition(upReversal, "HiLo Up reversal", "Confirmed HiLo reversal from Down to Up")
alertcondition(downReversal, "HiLo Down reversal", "Confirmed HiLo reversal from Up to Down")

Give Pineify a reproducible specification

Use the Pine Script AI Coding Agent to draft changes from the public formula and your own acceptance cases. Specify prior-bar SMAs, numeric hold behavior, neutral initialization, strict comparisons, and confirmed reversal alerts. Request the two average values in the Data Window before adding strategy orders.

  • Keep the ten-bar fixture unchanged while comparing generated versions. A different result must be explained by an intentional rule change or corrected as an implementation error.
  • For a strategy, separately define whether Down exits a long or opens a short, when the order can fill, position size, fees, and slippage. Reserve later data before selecting a length.
Where Pineify fits

Pine Script AI Coding Agent

Draft a HiLo indicator from explicit formulas and state rules, request syntax checking, and compare the output with your numerical acceptance cases.

Draft a HiLo indicator

Frequently asked questions

Educational calculation examples, not investment advice. All numerical price paths are synthetic. Indicator states and syntax checks do not establish profitable trades or guaranteed execution prices.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.