TradingView indicator calculations

T3 Moving Average for TradingView: Factor, Lag and Overshoot

The T3 moving average applies Tim Tillson's generalized DEMA three times. It combines six EMA stages using a volume factor, usually written v. That factor controls the amount of lag compensation; it does not read traded volume. T3 differs from TEMA, can overshoot price, and needs matching source, length, factor and initialization before TradingView values can be compared.

See the decision guide

How three generalized DEMA stages become six EMAs

Define E1 = EMA(price), E2 = EMA(E1), and continue through E6, all with the same length. Generalized DEMA is GD(x) = (1 + v) × EMA(x) − v × EMA(EMA(x)). T3 = GD(GD(GD(price))). Expanding those three stages gives the coefficient formula below. The equivalence assumes consistent EMA coefficients and initialization.

  • The T3 coefficients sum to 1. A constant input with all stages initialized to that constant stays unchanged.
  • Negative coefficients help offset smoothing delay but allow the result to leave the range of recent prices. This is why a smooth line can still overshoot.
  • With fixed length and factor, these equations form a fixed-coefficient filter. They do not automatically adapt the factor to volatility or volume.
OutputFormula using the same EMA chain
EMAE1
TEMA3 × E1 − 3 × E2 + E3
T3(1 + v)³ × E3 − 3v(1 + v)² × E4 + 3v²(1 + v) × E5 − v³ × E6
T3 with v = 0.74.913 × E3 − 6.069 × E4 + 2.499 × E5 − 0.343 × E6

What volume factor changes, and what it does not

Volume factor is the historical parameter name for the blend between EMA and DEMA in each GD stage. DEMA = 2 × EMA − EMA(EMA), so GD = (1 − v) × EMA + v × DEMA. There is no volume series in this equation. A T3 calculated from close can therefore be computed without a volume feed.

  • Factor 0.7 is a documented common setting, not a proven optimum for every instrument or timeframe.
  • A length of 20 means 20 chart observations for the EMA coefficient. It does not mean T3 forgets everything older than 20 bars or has a fixed 20-bar delay.
ParameterBoundary or interpretation
v = 0Each GD becomes EMA; the full T3 becomes E3, with three smoothing stages.
v = 1Each GD becomes DEMA; the full T3 is DEMA applied three times, not TEMA.
0 < v < 1Intermediate lag compensation. A higher factor can increase overshoot around changes in direction.
v outside [0, 1]The polynomial is calculable, but this is extrapolation beyond the conventional blend. The example script rejects it.
Length = 1α = 1, every EMA equals the source, and EMA, TEMA and T3 coincide.
Length ≤ 0 or non-integerOutside the length contract used here; choose a positive integer.

Same-data comparison: a rise, plateau and reversal

This synthetic sequence starts at 100 on bar 0, stays at 110 on bars 1 through 6, then returns to 100 from bar 7. Set length = 3, so α = 0.5. Initialize all six EMA stages to 100 on bar 0. On each later bar, update E1 from price, then E2 from the new E1, continuing through E6. Values are rounded to four decimals after calculation; these are arithmetic checks, not market observations or returns.

  • Bar 1 has E1…E6 = 105, 102.5, 101.25, 100.625, 100.3125, 100.15625. Thus TEMA = 315 − 307.5 + 101.25 = 108.75. The T3 coefficient formula gives 103.07546875.
  • TEMA first exceeds the 110 plateau on bar 2; T3 first exceeds it on bar 4. After the reversal, TEMA first falls below 100 on bar 8, while T3 does so on bar 11. The EMA remains between its prior value and the new price.
  • The first rising-bar T3 response is smaller than the EMA response here. Claims that T3 always leads EMA are inconsistent with this example. Response timing depends on the input and parameters.
  • A price crossing caused partly by filter overshoot does not establish a new price trend. Choppy input can also produce repeated crosses without a useful trade after costs.
BarPriceEMA(3)TEMA(3)T3(3, 0.7)
0100100.0000100.0000100.0000
1110105.0000108.7500103.0755
2110107.5000110.6250106.4927
3110108.7500110.6250108.8689
4110109.3750110.3125110.1041
5110109.6875110.0781110.5586
6110109.8438109.9609110.6037
7100104.9219101.1719107.4121
8100102.460999.2969103.8478
9100101.230599.3115101.3469
10100100.615299.6411100.0226
11100100.307699.890199.5107

Factor sensitivity on that same sequence

Changing only the factor leaves the six EMA states unchanged. The rows below therefore isolate the coefficient effect. They demonstrate overshoot at both ends of the move without changing the price source or length.

  • At bar 4, factor 1 overshoots the plateau by 1.7578 price units, versus 0.1041 for factor 0.7. Factor 0 still trails below the plateau.
  • Choose a factor using a stated measurement, such as response after a step and maximum overshoot, then test separate market data. This four-row comparison does not identify a profitable setting.
Bar / priceT3, v = 0T3, v = 0.7T3, v = 1
1 / 110101.2500103.0755104.2188
4 / 110106.5625110.1041111.7578
9 / 100104.6729101.346999.3585
11 / 100102.153399.510798.3412

A Pine v6 comparison with an explicit seed

The script implements the published formula and plots EMA, TEMA and T3 on the chart timeframe. Each EMA state starts at its first non-missing input and holds its prior state across missing inputs. Test sequence replaces the chart source with the synthetic series above; use length 3 and factor 0.7, then inspect bars 0 through 11 in the Data Window. Test bars are counted from the first loaded chart bar. The test disables alerts.

Public-formula implementation with a synthetic check mode. Syntax validation does not establish equivalence to every community T3 script or a trading edge.pine
//@version=6
indicator("T3, EMA and TEMA comparison", overlay=true)
length = input.int(3, "Length", minval=1)
v = input.float(0.7, "Volume factor", minval=0, maxval=1, step=0.05)
source = input.source(close, "Source")
isTest = input.bool(false, "Test sequence")

emaSeeded(float x, int n) =>
    float alpha = 2.0 / (n + 1.0)
    float value = na
    value := na(x) ? value[1] : na(value[1]) ? x : alpha * x + (1.0 - alpha) * value[1]
    value

float sample = bar_index == 0 ? 100.0 : bar_index <= 6 ? 110.0 : 100.0
float x = isTest ? sample : source
e1 = emaSeeded(x, length)
e2 = emaSeeded(e1, length)
e3 = emaSeeded(e2, length)
e4 = emaSeeded(e3, length)
e5 = emaSeeded(e4, length)
e6 = emaSeeded(e5, length)
t3 = math.pow(1 + v, 3) * e3 - 3 * v * math.pow(1 + v, 2) * e4 + 3 * v * v * (1 + v) * e5 - v * v * v * e6
tema = 3 * e1 - 3 * e2 + e3
plot(t3, "T3", color=color.blue, linewidth=2)
plot(e1, "EMA", color=color.orange)
plot(tema, "TEMA", color=color.purple)
plot(isTest ? bar_index : na, "Test bar", display=display.data_window)
plot(isTest ? x : na, "Test input", display=display.data_window)
crossUp = ta.crossover(x, t3)
alertcondition(not isTest and barstate.isconfirmed and crossUp, "Source crosses above T3", "Source crossed above T3 on a closed chart bar.")

Verify initialization and closed-bar timing in TradingView

A community script called T3 may use a different source, seed, coefficient convention or extra filter. Identify its author and inspect available source before comparing. Start with a standard candlestick chart, the same symbol and session, the same chart timeframe and zero plot offset. Record values on completed bars in the Data Window.

  • Match length, factor and source first. An SMA-seeded EMA and the first-value seed shown here can disagree near the start. Six recursive stages can retain startup effects; six times the length is not a universal convergence guarantee.
  • Load more history and compare the same timestamps again. Treat remaining differences as evidence to investigate. Missing data can make implementations differ because their hold, skip or reset policies may not match.
  • The example alert requires current source > current T3 and prior source ≤ prior T3, evaluated at chart-bar close. Equality now is not an upward cross. The state source > T3 is a separate condition.
  • Create the alert with Once Per Bar Close and recreate it after changing code or inputs. The displayed line can still move while the current bar is open. No higher-timeframe request is used in this example.
  • A confirmed cross defines an observation, not execution. Specify order timing, exits, position size and costs separately before evaluating a strategy.

Carry the verified specification into Pineify

Use Pine Script AI Coding Agent to draft or revise this public-formula indicator. Supply the six-stage formula, first-value initialization, missing-input policy, length and factor bounds, and closed-chart-bar alert condition. Include the synthetic table as the expected output instead of asking it to copy an unnamed proprietary indicator.

  • Ask for syntax diagnostics, review the source, and compare the generated values and event times with TradingView before enabling alerts.
  • Keep formula changes separate from trading rules. Passing a syntax check does not prove chart-value parity, correct execution assumptions or profitable results.
Where Pineify fits

Pine Script AI Coding Agent

Describe the T3 formula, seed and close-confirmed alert rule, then inspect the generated Pine Script and check its values in TradingView.

Build a T3 comparison script

Frequently asked questions

Educational indicator calculations, not investment advice. Synthetic values are formula examples, not backtest results. Smoothing and confirmed alerts do not guarantee profitable trades.

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.