◆ New — Strategy Validator, Code Fixer & Prop Compliance Checker are live. Try one free →
Home / Indicators / HalfTrend
Trend indicator

HalfTrend

A stateful trend-following overlay that ratchets a support/resistance line and flips between up and down states.

Illustrative diagram — not live market data.

What it is

HalfTrend is a trend-state overlay that originated as a free MetaTrader 4 indicator and later went viral on TradingView through community ports (the best known by the user everget). Its provenance is murky — there is no canonical paper or verified original author documenting the algorithm — so in practice 'HalfTrend' refers to a family of closely related implementations rather than one authoritative formula. The indicator draws a single stepped line on the price chart that switches between an up state (line below price, typically drawn in a bullish color) and a down state (line above price), usually accompanied by an ATR-scaled channel and arrows at each flip. Because one name covers several ports, values can differ across platforms and even between TradingView scripts, which matters if you are comparing signals or validating a Pine port against the MQL original. Like every indicator, HalfTrend is descriptive, not predictive: it summarizes what recent highs, lows, and closes have already done and says nothing about what price will do next. This page is educational only, not financial advice, and trading involves risk of loss.

How it works

The algorithm keeps a persistent trend state and two tracked extremes. Over a lookback window called the amplitude (default 2), it computes the simple moving averages of the highs and of the lows, plus the highest high and lowest low of that window. While the state is up, the indicator ratchets a 'max low' value: each bar it takes the greater of the window's lowest low and the previous tracked value, so the plotted line rises or stays flat but never falls within the state. The state flips down only when the SMA of highs drops below that tracked level and the bar closes below the prior bar's low; the logic then mirrors, ratcheting a 'min high' downward until the conditions for an upward flip are met. The plotted line is simply the tracked extreme for whichever state is active, and popular ports wrap it in a channel of ATR-scaled bands. On the repaint question: the calculation uses only completed bar values, so historical bars do not repaint — but during a live bar the flip condition can appear and disappear as price moves, so a real-time arrow is provisional until the bar closes. Any alert built on a flip should be gated on bar confirmation.

How traders read it

Common settings

Amplitude 2 and channel deviation 2 are the defaults inherited from the MT4 original. Larger amplitude values widen the window used for the SMAs and extremes, producing fewer and later flips; smaller values flip more often and track price more tightly. Because different ports handle the opening bars and the ratchet slightly differently, the state can differ between platforms on identical data — worth verifying before comparing signals. It can be applied to any market and timeframe.

Strengths

Pitfalls to watch

Pine v6 example

//@version=6
indicator("HalfTrend Example", overlay = true)

amplitude = input.int(2, "Amplitude", minval = 1)

var int trend = 0
var float maxLowPrice = low
var float minHighPrice = high

highMa = ta.sma(high, amplitude)
lowMa = ta.sma(low, amplitude)
hh = ta.highest(high, amplitude)
ll = ta.lowest(low, amplitude)

if trend == 0
    maxLowPrice := math.max(ll, maxLowPrice)
    if highMa < maxLowPrice and close < nz(low[1], low)
        trend := 1
        minHighPrice := hh
else
    minHighPrice := math.min(hh, minHighPrice)
    if lowMa > minHighPrice and close > nz(high[1], high)
        trend := 0
        maxLowPrice := ll

htLine = trend == 0 ? maxLowPrice : minHighPrice
plot(htLine, "HalfTrend", color = trend == 0 ? color.teal : color.red, linewidth = 2)

flipUp = trend == 0 and trend[1] == 1 and barstate.isconfirmed
flipDn = trend == 1 and trend[1] == 0 and barstate.isconfirmed
plotshape(flipUp, "Flip Up", style = shape.triangleup, location = location.belowbar, color = color.teal)
plotshape(flipDn, "Flip Down", style = shape.triangledown, location = location.abovebar, color = color.red)

Pro tip: Before trusting any HalfTrend port, run it side by side with a second implementation on identical data and check that the flips match — the name does not guarantee the formula. Gate every alert on bar confirmation so live signals match what a study of closed bars would show, and treat the line as a label for the trend that already happened rather than a call on the next one. Educational information only, not financial advice; no indicator removes the risk of loss.

Built an indicator from this? Run it through the Validator to catch look-ahead bias and repainting, or convert a strategy to Pine Script.

Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.

Catch the bug that compiles.Run auditGet Pro