TradingView indicator calculations

Trend Trigger Factor for TradingView: window comparisons

Trend Trigger Factor (TTF), introduced by M.H. Pee, compares highs and lows across two adjacent windows of equal length. Buy power is the recent high minus the older low; sell power is the older high minus the recent low. Their difference is divided by their average and multiplied by 100. The familiar +100 and -100 levels are thresholds, not bounds on the result.

See the decision guide

Compare adjacent windows without clipping either power

For the current bar t, the recent window covers t through t−N+1. The older window covers t−N through t−2N+1. Pee illustrates N = 15 on daily data; on an intraday chart N counts chart bars, not calendar days. The following is the unsmoothed calculation.

  • Buying and selling power are names for price differences. The calculation does not use volume, executed buy orders or order-book data.
  • Either power can be negative when the windows are separated by a price gap. Clamping negative power to zero changes the formula.
  • Do not add smoothing or a signal line when comparing this example with the public formula. TradingView community variants may include extra filters, including discontinued signal lines.
QuantityDefinition
Hr, LrHighest high and lowest low in the recent N bars
Ho, LoHighest high and lowest low in the preceding N bars
Buying power BHr − Lo
Selling power SHo − Lr
Denominator D(B + S) / 2 = ((Hr − Lr) + (Ho − Lo)) / 2
TTF100 × (B − S) / D, where D > 0

Recalculate a four-bar example

These are hypothetical high-low observations with N = 2, ordered from oldest to newest. The first complete result appears on bar 4. Only extrema matter; the closing price within each bar does not enter the TTF formula.

  • Ho = 108, Lo = 100, Hr = 114 and Lr = 104. B = 14, S = 4 and D = (14 + 4) / 2 = 9. TTF = 100 × 10 / 9 = 111.1111.
  • The independent range check gives D = ((114 − 104) + (108 − 100)) / 2 = 9. Disagreement here usually means an offset or sign error.
  • If the recent high were 112 with all other extrema unchanged, B = 12, S = 4 and TTF = 100 exactly. Our strict greater-than rule would not switch direction at that value.
  • Swapping the two complete windows negates the reading: −111.1111. It preserves the denominator and exchanges buying with selling power.
BarWindowHighLow
1Older108100
2Older106102
3Recent112106
4Recent114104

Handle undefined and unusually large readings

TTF is not confined to ±100 or even ±200. A gap between narrow windows can make a power negative and the ratio large. The denominator measures the ranges inside the two windows; it does not include the gap between them.

  • A very small positive D can produce a very large finite value. Any minimum-range filter would be a separate policy to disclose and test.
  • Rolling extrema can change when an old high or low leaves a window, even without a large current-bar move. A threshold event does not identify its economic cause.
Hypothetical extremaCalculationRequired handling
Recent 110/105; older 104/99B = 11; S = −1; D = 5; TTF = 240Keep the negative sell power and the 240 result.
Both windows 100/100B = 0; S = 0; D = 0Return na; no new state or alert.
Recent 110/110; older 100/100B = 10; S = −10; D = 0Still undefined, despite the gap between windows.
Fewer than 2N valid barsAt least one window is incompleteWait for complete windows.

Separate the displayed value from the direction state

This page defines a persistent state machine, not a complete trading strategy. Start at 0 (uninitialized), set +1 after a confirmed TTF > 100, and set −1 after a confirmed TTF < −100. Keep the previous state for values between the thresholds, including equality, and for missing values. An alert fires only when the state changes into +1 or −1.

  • A neutral-zone classifier would instead assign 0 whenever TTF is between −100 and +100. That is a different state rule; do not mix its colors with persistent-state alerts.
  • Another crossing of +100 while state is already +1 creates no new switch alert. Initializing from 0 to +1 does create an event in this example.
  • The retained direction on missing data is stale state, not a valid current reading. The state also depends on available earlier history until the first threshold exceedance.
Observation in sequenceConfirmed stateEvent
Start, then closed TTF = 800None
Closed TTF = 1000None: equality is not greater than
Closed TTF = 111.1111+1Switch up
Closed TTF = 130, then 40+1None: direction persists
Open-bar TTF = −120+1None: bar is not confirmed
That bar closes at −90+1None
Next bar closes at −110−1Switch down
Next closed value is undefined−1None: retain state, show no TTF value

Inspect the windows and confirmed transitions in Pine v6

This chart-timeframe indicator exposes both powers, the denominator and confirmed state in the Data Window. The TTF line develops during the open bar; only the state, markers and alert conditions wait for confirmation. There are no strategy orders or higher-timeframe requests.

  • Match symbol, feed, chart interval, session and candle type before comparing values. Use ordinary candles when verifying traded high-low prices.
  • On a completed bar, inspect the recent N bars and the preceding N bars separately. Recalculate B, S and D before checking TTF; this finds the first disagreement.
  • Choose a confirmed-switch condition when creating an alert and use Once Per Bar Close. Historical markers are not historical alert deliveries.
  • A strategy needs separate order timing, exits, sizing and costs. Retaining a direction state does not authorize holding an unlimited-risk position.
Educational implementation of the stated window and state rules. Syntax checking does not prove numerical agreement with other scripts or profitable trades.pine
//@version=6
indicator("Trend Trigger Factor window audit", overlay=false, precision=4)
length = input.int(15, "Bars per window", minval=1, maxval=500)
threshold = input.float(100.0, "Symmetric threshold", minval=0.1)
recentHigh = ta.highest(high, length)
recentLow = ta.lowest(low, length)
olderHigh = recentHigh[length]
olderLow = recentLow[length]
validBar = not na(high) and not na(low) and high >= low
validFraction = ta.sma(validBar ? 1.0 : 0.0, 2 * length)
fullWindow = bar_index >= 2 * length - 1 and validFraction == 1.0
buyPower = recentHigh - olderLow
sellPower = olderHigh - recentLow
denominator = 0.5 * (buyPower + sellPower)
ttf = fullWindow and denominator > 0.0 ? 100.0 * (buyPower - sellPower) / denominator : na
var int direction = 0
bool switchedUp = false
bool switchedDown = false
if barstate.isconfirmed and not na(ttf)
    nextDirection = ttf > threshold ? 1 : ttf < -threshold ? -1 : direction
    switchedUp := nextDirection == 1 and direction != 1
    switchedDown := nextDirection == -1 and direction != -1
    direction := nextDirection
plot(ttf, "TTF (developing until close)", color=color.blue, style=plot.style_linebr)
hline(threshold, "Upper threshold", color=color.gray)
hline(-threshold, "Lower threshold", color=color.gray)
hline(0, "Zero", color=color.gray, linestyle=hline.style_dotted)
plot(buyPower, "Buy power", display=display.data_window)
plot(sellPower, "Sell power", display=display.data_window)
plot(denominator, "Average window range", display=display.data_window)
plot(direction, "Confirmed direction: -1, 0, 1", display=display.data_window)
plotshape(switchedUp, title="Switch to up", style=shape.triangleup, location=location.bottom, color=color.green, size=size.tiny)
plotshape(switchedDown, title="Switch to down", style=shape.triangledown, location=location.top, color=color.red, size=size.tiny)
alertcondition(switchedUp, "Confirmed TTF switch up", "TTF direction switched up on a closed chart bar.")
alertcondition(switchedDown, "Confirmed TTF switch down", "TTF direction switched down on a closed chart bar.")

Keep TTF separate from TSI and Trend Intensity Index

True Strength Index (TSI) uses double-smoothed price changes and absolute price changes. Trend Intensity Index (TII) uses price deviations relative to a moving average. Neither is the adjacent-window high-low calculation above. Similar names or a common trend-analysis purpose do not make their values or threshold settings interchangeable.

  • TTF has no moving-average stage in this version. A script with smoothing should document its type, length and position in the calculation.
  • A threshold breach can occur in a choppy market and can reverse on later closes. Confirmation removes developing-bar events from this rule; it does not remove false signals.

Give Pineify the formula and the state contract

Ask the Pine Script AI Coding Agent to draft or explain this public TTF calculation with two N-bar windows, no smoothing, a complete-history requirement and na for zero denominators. Specify strict ±100 thresholds, initial state 0, persistence between thresholds, and bar-close switch alerts. Include the four-bar fixture as an arithmetic check.

  • Request intermediate Data Window outputs and review them against TradingView before using alerts. Ask explicitly for syntax validation after any code change.
  • This workflow specifies a reproducible public algorithm. It does not promise to copy the inaccessible source or extra filters of a proprietary indicator.
Where Pineify fits

Pine Script AI Coding Agent

Draft and review a TTF indicator with explicit window offsets, undefined-value handling and confirmed state transitions.

Draft a TTF indicator

Frequently asked questions

Educational information, not investment advice. Numerical examples are hypothetical. Indicator states, syntax validation and alerts do not establish future returns or provide a complete trading strategy.

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.