Advertisement IC Markets

⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Optimize MetaTrader 4, MetaTrader 5, cTrader, and TradingView for speed. Discuss Level II Market Depth (DOM), custom hotkeys, and volume indicators.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

Hi scalpers,

If you’ve been scalping the lower timeframes for a while, you already know the daily struggle: standard moving averages either lag too much (making you late to the breakout) or they react too fast (faking you out during minor pullbacks).

While the Hull Moving Average (HMA) is fantastic, many advanced scalpers eventually graduate to the Jurik Moving Average (JMA). Let's break down why this tool is a favorite for fast-paced trading.

What is the Jurik Moving Average (JMA)?

Developed by Mark Jurik for institutional traders, the JMA was engineered to do two things perfectly: eliminate lag and aggressively smooth out market noise.

A quick dose of honesty: The true, original JMA formula is a heavily guarded, proprietary commercial product. Because of this, the versions used by retail traders on MT4 and MT5 are community-built mathematical approximations. However, these open-source versions are incredibly accurate and still outperform standard moving averages in responsiveness!

Why Scalpers Prefer the JMA

1.) Zero Overshoot: Fast moving averages often "overshoot" or distort during sudden price spikes. The JMA tightly hugs the price action without swinging wildly out of proportion.

2.) Supreme Smoothness: It filters out the tiny, irrelevant 1-pip jitters (market noise) that trigger false entries on the M1 and M5 charts.

3.) Volatility Adaptive: The math behind the JMA adjusts dynamically. When the market moves fast, the line catches up instantly; when the market ranges, it flattens out smoothly.

How to Trade It

As a newbie, do not overcomplicate your charts. Use the JMA as a high-tier directional filter:

1.) Trend Confirmation: Only take long scalps when the price is clearly closing above an upward-sloping JMA. Take shorts when the price is below a downward-sloping JMA.

2.) The JMA Crossover: Plot a "Fast" JMA (e.g., 7-period) and a "Slow" JMA (e.g., 21-period). When the fast crosses the slow, it signals a highly filtered shift in short-term momentum.

3.) Flat Lines = Ranging: When the JMA flattens, it means the market is consolidating. Stay out and wait for a clear angle!

MT4 (MQL4) Version:
Save this as a new Custom Indicator in your MetaEditor (F4).

Code: Select all

//+------------------------------------------------------------------+
//|                                                  JMA_Proxy.mq4   |
//|                        Open-Source Jurik Approximation for MT4   |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrMagenta
#property indicator_width1 2

input int Length = 14; // Smoothing Period
input int Phase = 50;  // Phase (-100 to +100)

double JMABuffer[];
double e1[], e2[], e3[], e4[], e5[], e6[];

int OnInit() {
   SetIndexBuffer(0, JMABuffer);
   SetIndexStyle(0, DRAW_LINE);
   
   // Hidden buffers for math
   ArrayResize(e1, Bars); ArrayResize(e2, Bars);
   ArrayResize(e3, Bars); ArrayResize(e4, Bars);
   ArrayResize(e5, Bars); ArrayResize(e6, Bars);
   return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[],
                const double &open[], const double &high[], const double &low[],
                const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
                
   int limit = rates_total - prev_calculated;
   if(prev_calculated == 0) limit = rates_total - 1;
   
   double pr = Phase;
   if(pr < -100) pr = -100;
   if(pr > 100) pr = 100;
   double phaseRatio = (pr / 100.0) + 1.5;
   double beta = 0.45 * (rates_total - 1) / (0.9999999 * rates_total + 2.0);
   double alpha = MathPow(beta, phaseRatio);
   
   for(int i = limit; i >= 0; i--) {
      double price = close[i];
      if(i == rates_total - 1) {
         e1[i] = price; e2[i] = price; e3[i] = price;
         e4[i] = price; e5[i] = price; e6[i] = price;
         JMABuffer[i] = price;
         continue;
      }
      
      // JMA proxy smoothing logic
      e1[i] = (1 - alpha) * price + alpha * e1[i+1];
      e2[i] = (price - e1[i]) * (1 - beta) + beta * e2[i+1];
      e3[i] = e1[i] + e2[i];
      e4[i] = (1 - alpha) * e3[i] + alpha * e4[i+1];
      e5[i] = (e3[i] - e4[i]) * (1 - beta) + beta * e5[i+1];
      e6[i] = e4[i] + e5[i];
      
      JMABuffer[i] = e6[i];
   }
   return(rates_total);
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Recommended broker for automated trading & scalping IC Markets
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

And for MT5 traders, here is updated version:

MT5 (MQL5) Version:
MT5 handles arrays differently (from left to right by default). Here is the MQL5 equivalent.

Code: Select all

//+------------------------------------------------------------------+
//|                                                  JMA_Proxy.mq5   |
//|                        Open-Source Jurik Approximation for MT5   |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 7
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrMagenta
#property indicator_width1  2

input int Length = 14; // Smoothing Period
input int Phase = 50;  // Phase (-100 to +100)

double JMABuffer[];
double e1[], e2[], e3[], e4[], e5[], e6[];

int OnInit() {
   SetIndexBuffer(0, JMABuffer, INDICATOR_DATA);
   SetIndexBuffer(1, e1, INDICATOR_CALCULATIONS);
   SetIndexBuffer(2, e2, INDICATOR_CALCULATIONS);
   SetIndexBuffer(3, e3, INDICATOR_CALCULATIONS);
   SetIndexBuffer(4, e4, INDICATOR_CALCULATIONS);
   SetIndexBuffer(5, e5, INDICATOR_CALCULATIONS);
   SetIndexBuffer(6, e6, INDICATOR_CALCULATIONS);
   return(INIT_SUCCEEDED);
}

int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[],
                const double &open[], const double &high[], const double &low[],
                const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) {
                
   if(rates_total < Length) return 0;
   
   int start = (prev_calculated > 0) ? prev_calculated - 1 : 0;
   
   double pr = Phase;
   if(pr < -100) pr = -100;
   if(pr > 100) pr = 100;
   double phaseRatio = (pr / 100.0) + 1.5;
   double beta = 0.45 * Length / (0.9999999 * Length + 2.0);
   double alpha = MathPow(beta, phaseRatio);

   for(int i = start; i < rates_total; i++) {
      double price = close[i];
      if(i == 0) {
         e1[i] = price; e2[i] = price; e3[i] = price;
         e4[i] = price; e5[i] = price; e6[i] = price;
         JMABuffer[i] = price;
         continue;
      }
      
      e1[i] = (1 - alpha) * price + alpha * e1[i-1];
      e2[i] = (price - e1[i]) * (1 - beta) + beta * e2[i-1];
      e3[i] = e1[i] + e2[i];
      e4[i] = (1 - alpha) * e3[i] + alpha * e4[i-1];
      e5[i] = (e3[i] - e4[i]) * (1 - beta) + beta * e5[i-1];
      e6[i] = e4[i] + e5[i];
      
      JMABuffer[i] = e6[i];
   }
   return(rates_total);
}
For those of you who strictly scalp the 1-minute (M1) or 5-minute (M5) charts, what specific settings (Length and Phase) do you plan on testing first?

Please let me know, how do you like it, plus if you have any idea how to extend it or make it even better.
Take a care.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
LondonScalper
Posts: 965
Joined: Sat Sep 05, 2026 7:54 am

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by LondonScalper »

PTScalper wrote:standard moving averages either lag too much ... or they react too fast ... many advanced scalpers eventually graduate to the Jurik Moving Average (JMA).
JMA sits in that same family of “smoother, less lag” ambitions — with the added footnote that retail builds are usually approximations of a proprietary filter. Fine for charting; be careful treating them as sacred.

My desk bias hasn’t changed across HMA/JMA/Kalman/etc.: the line is a lens. If your edge needs a perfect low-lag MA, it may be fragile to the next vol regime. I still glance at a fast smooth average for trend hygiene on occasion; I don’t let it veto structure and session context.

If you use JMA-style tools:
  • Validate the specific indicator build you installed (clones differ)
  • Test in the sessions you actually trade, with real spreads
  • Ask whether it changes decisions or only changes aesthetics
“Ultimate scalper’s tool” is marketing language; a useful optional overlay is plenty.

Curious what decision JMA changed for you last week that a plain EMA would have missed — entry timing, or stand-down?
PropScalpDesk
Posts: 521
Joined: Sat Sep 19, 2026 7:50 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PropScalpDesk »

JMA is a filter, not a personality

Smooth averages help on noisy M1/M5, but from this desk they never replace invalidation, cost, and session. Jurik-style responsiveness is useful when I want less whip than a plain EMA without waiting for a glacier SMA. It is still lag dressed in better clothes.

How I would actually use it if I put it on EURUSD for the European morning:
  • Bias/filter only — slope or side of price, not “cross means market order”
  • Pair with a hard structure stop, not a trailing MA fantasy
  • Disable around red folders; adaptive averages do not know CPI is in twelve minutes
Code snippets are fine for learning. Live size is earned after you measure expectancy after spread and commission, not on a clean visual backtest.

I stay mostly price-action with a thin toolkit. Indicators earn a slot when they remove decisions, not when they add charts to babysit.

I also compare any MA-based idea against a pure price-action baseline on the same sample. If JMA does not improve expectancy after costs, it does not earn screen space.

If you run JMA on M1, what is the one rule that stops you from chasing every micro-turn it paints?
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

PropScalpDesk wrote: Sun Sep 20, 2026 1:12 pm JMA is a filter, not a personality

Smooth averages help on noisy M1/M5, but from this desk they never replace invalidation, cost, and session. Jurik-style responsiveness is useful when I want less whip than a plain EMA without waiting for a glacier SMA. It is still lag dressed in better clothes.

How I would actually use it if I put it on EURUSD for the European morning:
  • Bias/filter only — slope or side of price, not “cross means market order”
  • Pair with a hard structure stop, not a trailing MA fantasy
  • Disable around red folders; adaptive averages do not know CPI is in twelve minutes
Code snippets are fine for learning. Live size is earned after you measure expectancy after spread and commission, not on a clean visual backtest.

I stay mostly price-action with a thin toolkit. Indicators earn a slot when they remove decisions, not when they add charts to babysit.

I also compare any MA-based idea against a pure price-action baseline on the same sample. If JMA does not improve expectancy after costs, it does not earn screen space.

If you run JMA on M1, what is the one rule that stops you from chasing every micro-turn it paints?
Hi PropScalpDesk,

The one rule to stop chasing M1 JMA micro-turns is making a higher-timeframe liquidity sweep a mandatory prerequisite.

If the M1 JMA flips slope or price crosses it, but the market hasn't just swept a clear structural level—like an M15 fractal, a prior session high/low, or a daily extreme—that JMA turn is treated as mid-range noise and completely ignored.

Because JMA is still fundamentally a lagging calculation, letting raw price action dictate the location of the trade forces the indicator to remain a subordinate filter. You let market structure trigger the idea, and you only consult the JMA to confirm the short-term momentum reaction.

If the JMA paints a beautiful turn but the structural context is absent, the signal is dead on arrival. This strict structural prerequisite strips away the temptation to trade localized momentum shifts, keeps you out of chop, and ensures the indicator is actually removing decisions rather than just giving you more lines to babysit.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

The cleanest way to handle this without building a spaghetti of nested if statements is to structure the bot as a finite state machine (FSM). Because you are crossing timeframes (M15 structural data into an M1 execution loop), the primary technical challenge is data synchronization and signal expiration.

Here is the architectural approach to building this in C# for cAlgo (or porting to MQL5).

1. The State Machine
The market is always in one of three states relative to your strategy. You only evaluate JMA slope or crosses when the state is primed by the M15 timeframe.

Code: Select all

public enum SetupState 
{ 
    Neutral, 
    LiquiditySweptHigh, 
    LiquiditySweptLow 
}

private SetupState _currentState = SetupState.Neutral;
private int _barsSinceSweep = 0;
private int _maxSweepValidity = 5; // Discard setup if JMA doesn't fire within 5 M1 bars
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

2. Multi-Timeframe Synchronization (The M15 Context)

You must isolate strictly closed M15 data to prevent repainting. In cAlgo, you retrieve the M15 series and look at index Last(1). The "liquidity pool" can be the previous M15 candle's extreme, or a broader M15 fractal structure.

Code: Select all

// Inside OnBar() - running on the M1 timeframe
var m15Bars = MarketData.GetBars(TimeFrame.Minute15);

// Example: Using the previous closed M15 candle as the structural liquidity level
double m15PrevHigh = m15Bars.HighPrices.Last(1);
double m15PrevLow = m15Bars.LowPrices.Last(1);

double m1High = Bars.HighPrices.Last(1);
double m1Low = Bars.LowPrices.Last(1);
double m1Close = Bars.ClosePrices.Last(1);
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

3. Detecting the Sweep (Pierce + Rejection)

A sweep is not just touching the M15 level; it requires price to push through it and then fail. On an M1 chart, this looks like an M1 candle closing back inside the range after piercing the M15 extreme.

Code: Select all

if (_currentState == SetupState.Neutral)
{
    // Swept the M15 high, but the M1 candle closed back below it (Rejection)
    if (m1High > m15PrevHigh && m1Close < m15PrevHigh)
    {
        _currentState = SetupState.LiquiditySweptHigh;
        _barsSinceSweep = 0;
    }
    // Swept the M15 low, M1 closed back above it
    else if (m1Low < m15PrevLow && m1Close > m15PrevLow)
    {
        _currentState = SetupState.LiquiditySweptLow;
        _barsSinceSweep = 0;
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

4. The JMA Trigger and Expiration

Once the state is primed, you hand control over to the JMA. However, you must implement a "timeout" counter. If the JMA is too slow to react and doesn't confirm the turn within a few M1 bars, the momentum of the sweep is dead and the state must reset to Neutral.

Code: Select all

if (_currentState == SetupState.LiquiditySweptHigh)
{
    _barsSinceSweep++;

    // JMA filter: Is the JMA sloping downward now?
    bool jmaRollingOver = JmaIndicator.Result.Last(1) < JmaIndicator.Result.Last(2);

    if (jmaRollingOver)
    {
        // Execute the trade
        ExecuteMarketOrder(TradeType.Sell, SymbolName, Volume, "M15_Sweep_JMA", HardStopPips, TargetPips);
        
        // Reset state after execution
        _currentState = SetupState.Neutral;
    }
    else if (_barsSinceSweep > _maxSweepValidity)
    {
        // The JMA took too long to confirm. The sweep is invalid.
        _currentState = SetupState.Neutral;
    }
}
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
PTScalper
Site Admin
Posts: 7643
Joined: Mon Jul 20, 2026 1:28 pm

Re: ⚡ The Ultimate Scalper's Tool: Jurik Moving Average (JMA) Explained + MT4/MT5 Code!

Post by PTScalper »

Key Considerations for Live Execution

Index Alignment: In MQL5, CopyRates or iHigh/iLow will require exact time-matching to ensure you are referencing the correct M15 bar relative to the current M1 tick. cAlgo's GetBars handles this under the hood, but always verify you are pulling Last(1) (closed bar) and not Last(0) (forming bar).

Spread Validation: Because you are executing on M1 immediately after a sweep, spread expansion is common (especially if the sweep coincided with minor news or sudden order book absorption). Wrap the ExecuteMarketOrder call in a strict spread check: if (Symbol.Spread > MaxAllowedSpread) return;.

Stop Placement: The hard structure stop should dynamically reference the highest high of the sweep (m1High), plus your standard spread/buffer allowance, rather than a fixed pip amount.
Preserve your own money. Scale with the market's money. Exponential growth is the ultimate key.
Post Reply