TradingView indicators

Jurik Moving Average on TradingView: Public Implementations Explained

A TradingView script named Jurik Moving Average may be a public approximation rather than the proprietary JMA. This guide tests one identified, licensed implementation. Its length, phase, power and starting values determine its output; the JMA label does not make different scripts interchangeable.

The worked example below uses hypothetical prices, not a market backtest. It measures filter response, not returns or signal accuracy.

Compare the same price sequence

Which implementation are you using?

Jurik Research distributed licensed software. The historical AmiBroker integration manual requires licensed Jurik DLLs and documents a JMA interface with speed and phase. It does not publish the internal calculation. That manual is historical documentation, not evidence of current purchasing availability.

The example here adapts everget's public source at a fixed revision, whose header permits distribution under GPL-3.0. We preserve its notices and license, expose its settings, and add a first-price seed and a reproducible test mode. These are disclosed changes to the public implementation, not access to Jurik's original source.

For fixed inputs, beta and alpha below stay constant. There is no volatility estimate that updates alpha, so calling this particular recurrence volatility-adaptive would be inaccurate. Other public scripts can use different calculations.

Parameter mechanics in this example

  • Length sets beta = 0.45 × (length − 1) / [0.45 × (length − 1) + 2]. Larger lengths increase beta toward 1.
  • Power sets alpha = beta^power. For length above 1, increasing positive power lowers alpha and increases the immediate input weight.
  • Phase sets the correction multiplier to phase / 100 + 1.5. The bounded range from -100 to 100 produces multipliers from 0.5 to 2.5.
  • Initialization sets the previous E0 and output. This example seeds both with the first valid price and seeds E1 and E2 with zero.

Length 1 is a special case of this public formula: beta and alpha are zero and the output equals the input. Power must be positive; phase is bounded by the inputs. These are example constraints, not the proprietary product's complete parameter contract.

Same prices, different lag and overshoot

Start with 100 at bar 0, then use 110 for bars 1 through 20. Seed E0 and the output at 100, with E1 = E2 = 0. All rows use exactly this sequence. Values are rounded only for display.

Hypothetical step response; overshoot is in price units above 110
Length / phase / powerBar 1Bar 3Bar 5First bar ≥ 105Max overshoot, bars 1 to 20
7 / -100 / 2103.3226108.4394109.848820.0418
7 / 0 / 2103.9530109.4179110.414020.4140
7 / 100 / 2104.5834110.3963110.979221.0028
7 / 0 / 1101.4345105.8155108.874830.4151
14 / 0 / 2101.2987105.5010108.714930.6668

The first three rows isolate phase: raising it increases the peak beyond the input level. The power-1 row reaches 105 one bar later than power 2. Length 14 also takes an extra bar to reach that threshold. This threshold delay is one test measure; it is not a universal lag figure for live prices.

For length 7, phase 0 and power 2, beta = 27/47 and alpha = (27/47)² ≈ 0.330014. At bar 1, E0 ≈ 106.699864, E1 ≈ 1.404313 and E2 ≈ 3.953003, giving 103.953003. The positive correction can push the line above 110 even though the input never exceeds 110.

Why the starting state matters

With the same 7 / 0 / 2 settings, replacing missing previous states with zero produces 39.5300 on the first price of 100. The first-price seed produces 100.0000. That difference is a startup artifact, not a price move. Changing available chart history can change recursive values near the start; there is no universal warm-up bar count proved by this example.

Pine Script v6: inspect and reproduce the calculation

Copy into TradingView's Pine Editor and add it to a chart. Enable the synthetic step and use the first loaded bars to reproduce the table in the Data Window. Keep first-price seeding enabled. Disable the synthetic input before examining market data or creating an alert.

//@version=6
// Public approximation, not the proprietary Jurik algorithm.
// Copyright (c) 2007-present Jurik Research and Consulting. All rights reserved.
// Copyright (c) 2018-present, Alex Orekhov (everget).
// Adapted by Pineify, 2026-10-17: v6, first-price seed, reset on na,
// bounded inputs, synthetic test series and confirmed-close alerts.
// This adaptation is distributed under GPL-3.0:
// https://www.gnu.org/licenses/gpl-3.0.html
// Source: github.com/everget/tradingview-pinescript-indicators
// movings/jurik_moving_average.pine, commit 187e031f04069b1bed0db2d0ebe85f0fa4e0251b
indicator("Public JMA approximation: parameter test", overlay=true)
length = input.int(7, "Length", minval=1)
phase = input.int(0, "Phase", minval=-100, maxval=100)
power = input.float(2.0, "Power", minval=0.1)
src = input.source(close, "Source")
seedFirst = input.bool(true, "Seed with first price")
demo = input.bool(false, "Synthetic step: 100, then 110")

publicJma(float x, int n, int ph, float pw, bool seed) =>
    beta = 0.45 * (n - 1) / (0.45 * (n - 1) + 2)
    alpha = math.pow(beta, pw)
    ratio = ph / 100.0 + 1.5
    var float e0 = na
    var float e1 = na
    var float e2 = na
    var float value = na
    if na(x)
        e0 := na
        e1 := na
        e2 := na
        value := na
    else
        priorE0 = nz(e0[1], seed ? x : 0.0)
        priorValue = nz(value[1], seed ? x : 0.0)
        e0 := (1 - alpha) * x + alpha * priorE0
        e1 := (x - e0) * (1 - beta) + beta * nz(e1[1])
        e2 := (e0 + ratio * e1 - priorValue) * math.pow(1 - alpha, 2) + math.pow(alpha, 2) * nz(e2[1])
        value := priorValue + e2
    value

price = demo ? (bar_index == 0 ? 100.0 : 110.0) : src
value = publicJma(price, length, phase, power, seedFirst)
plot(value, "Public approximation", color=color.blue, linewidth=2)
plot(demo ? price : na, "Synthetic input", color=color.gray)
crossUp = ta.crossover(price, value)
crossDown = ta.crossunder(price, value)
alertcondition(not demo and barstate.isconfirmed and crossUp, "Close crossed above", "Source closed above the public approximation")
alertcondition(not demo and barstate.isconfirmed and crossDown, "Close crossed below", "Source closed below the public approximation")

Source: everget public implementation. The displayed adaptation is licensed under GPL-3.0. A missing source value resets the state; the next valid value starts a new sequence. That differs from blindly replacing a missing price with zero.

Validate values before adding trading rules

  1. Record the script revision, symbol, exchange, chart timeframe, session, source, all three parameters and seed setting.
  2. Run the synthetic test first. Then compare market-data values against this exact implementation with matching history, rather than a different script carrying the JMA name.
  3. Inspect both a steady region and a sudden jump. Compare absolute output errors and overshoot before interpreting a crossover.
  4. Create alerts only after the comparison. The example evaluates crossings every bar and requires the chart bar to close before alerting.

TradingView documents barstate.isconfirmed and repainting behavior. Close confirmation addresses the open chart bar; it does not make a supplied external indicator source or higher-timeframe data safe automatically. Oscillating prices can repeatedly cross the filter, and overshoot can cause a cross without a new price trend. A syntax pass does not prove signal quality.

Continue with the Pine Script AI Coding Agent

Pineify's agent can create and edit Pine Script code documents and provides a syntax-check tool when requested. Supply the public source, license, parameter bounds, initialization policy and closed-bar conditions. Ask it to preserve the synthetic test so you can compare outputs in TradingView before adding alerts. It cannot establish equivalence to an undisclosed algorithm.

Educational information, not investment advice. Filter response is not evidence of profitability. No trading result is promised.

JMA questions

No. This is an adaptation of the publicly licensed everget implementation. It is not verified against the proprietary Jurik software and does not claim to reproduce its undisclosed algorithm. A script name alone does not establish numerical equivalence.

They may use different recurrences, adaptive coefficients, seeds, source prices or parameter defaults. Match the exact source revision, settings, chart data and history start before comparing. Power is a control in this public implementation, not proof of compatibility with every JMA product.

There is no setting established here as best for trading. The step experiment isolates each parameter: higher phase increases overshoot, while power and length change the response speed. A shorter response time does not establish a better trading result.

The current value changes while the source changes on an open bar. The included alerts require barstate.isconfirmed on the chart timeframe. That condition does not validate higher-timeframe requests, a future-looking external source or historical data revisions.

Sources and public implementation checked October 17, 2026.