Author: Dm_35
JMA_WPR

This script functions as a sophisticated technical analysis tool designed to visualize price momentum on a trading chart. It combines two distinct mathematical concepts: the Weighted Price Range (WPR) and the Jurik Moving Average (JMA).

Core Logic Overview

The primary purpose of this script is to smooth out "noisy" market data. Instead of looking at raw, jagged price movements, it calculates a momentum value and then processes that value through a high-end smoothing algorithm. This allows traders to see the underlying trend of market momentum more clearly without the lag typically associated with standard moving averages.

Step-by-Step Processing

To achieve this smooth visualization, the script follows these logical stages:

1. Momentum Extraction (WPR) The script first looks at a specific period of historical price data to determine the Weighted Price Range. This tells the script where the current price sits relative to its recent high and low points (essentially identifying if the market is currently "overbought," "oversold," or in a state of transition).

2. Data Buffering and Filtering Rather than reacting instantly to every tiny fluctuation, the script stores these momentum values into an internal "buffer." It performs a series of checks to identify significant changes in price direction. If the price is stable, the script remains steady; if a move occurs, it calculates the magnitude of that move to determine how much weight to give it.

3. The Jurik Smoothing Engine This is the most complex part of the logic. The script applies a proprietary smoothing technique known as the Jurik Moving Average. It uses several advanced mathematical operations:

  • Dynamic Weighting: It adjusts how much importance to give to new data versus old data based on the speed of the market.
  • Phase Adjustment: It allows for a "phase" shift, which helps in aligning the indicator with the specific visual requirements of the user.
  • Non-Linear Filtering: The logic uses powers and square roots to create a curve that hugs the price trend closely while filtering out minor "wiggles" or outliers that could trigger false signals.

4. Final Output The end result is a single, continuous line (plotted in a separate window below your main chart). Because of the Jurik logic, this line responds quickly to real trends but remains smooth and fluid, making it easier for a human observer to identify when momentum is shifting from one direction to another.

Summary for the User

Think of this script as a "Smart Momentum Tracker." It takes the raw intensity of price movements (WPR), strips away the insignificant "noise," and paints a smooth path showing you exactly where the market's underlying energy is headed.

Indicators Used
Larry William percent range indicator
Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
JMA_WPR
//+------------------------------------------------------------------+
//|                                                      JMA_WPR.mq4 |
//|                                                     JMA - Spiggy |
//|                                                       Dm_35 2008 |
//|                                    http://www.fxexpert.ru/forum/ |
//+------------------------------------------------------------------+
#property copyright "Dm_35"
#property link      "dm34@mail.ru"
//----
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- input parameters
extern int       WPRPeriod =  14;
extern int       Len=8;
extern int       phase=0;
extern int       BarCount=200;

//---- buffers
double ExtMapBuffer1[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,ExtMapBuffer1);
//----
   string short_name="JMA WPR(" + WPRPeriod + " , "+ Len+ ")";
   IndicatorShortName(short_name);
   SetIndexLabel(0, short_name);

   return(0);
  }
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   int    counted_bars=IndicatorCounted();
//---- 
   // variable definitions
   int jj=0;
   int ii=0;
   int shift=0;
   double series=0;
//----
   double vv=0;
   double v1=0;
   double v2=0;
   double v3=0;
   double v4=0;
   double s8=0;
   double s10=0;
   double s18=0;
   double s20=0;
   int v5=0;
   int v6=0;
   double s28=0;
   double s30=0;
   int s38=0;
   int s40=0;
   int s48=0;
   int s50=0;
   int s58=0;
   int s60=0;
   double s68=0;
   double s70=0;
   double f8=0;
   double f10=0;
   double f18=0;
   double f20=0;
   double f28=0;
   double f30=0;
   double f38=0;
   double f40=0;
   double f48=0;
   double f50=0;
   double f58=0;
   double f60=0;
   double f68=0;
   double f70=0;
   double f78=0;
   double f80=0;
   double f88=0;
   double f90=0;
   double f98=0;
   double fA0=0;
   double fA8=0;
   double fB0=0;
   double fB8=0;
   double fC0=0;
   double fC8=0;
   double fD0=0;
   double f0=0;
   double fD8=0;
   double fE0=0;
   double fE8=0;
   int fF0=0;
   double fF8=0;
   int value2=0;
   double JMA=0;

//----
   double list[127];
   double ring1[127];
   double ring2[10];
   double buffer[61];
//----
   ArrayInitialize(list,0);
   ArrayInitialize(ring1,0);
   ArrayInitialize(ring2,0);
   ArrayInitialize(buffer,0);
//----

      s28=63;
      s30=64;
      for( ii=1;ii<=s28;ii++)
        {
         list[ii]=-1000000;
        }
      for( ii=s30;ii<=127 ;ii++ )
        {
         list[ii]=1000000;
        }
      f0=1;
//----
   for( shift=BarCount;shift>=0;shift-- )
     {
      series=iWPR(NULL,0,WPRPeriod,shift);
      if (fF0 < 61)
        {
         fF0= fF0 + 1;
         buffer[fF0]=series;
        } //{ main cycle } 
      if (fF0 > 30)
        {
         if (Len < 1.0000000002)
           {
            f80=0.0000000001; //{1.0e-10} 
           }
         else
           {
            f80=(Len - 1)/2.0;
           }
         if (phase < -100)
           {
            f10=0.5;
           }
         else
           {
            if (phase > 100)
              {
               f10=2.5;
              }
            else
              {
               f10=phase/100 + 1.5;
              }
           }
         v1=MathLog(MathSqrt(f80));
         v2=v1;
         if (v1/MathLog(2.0) + 2.0 < 0.0)
           {
            v3=0;
           }
         else
           {
            v3=v2/MathLog(2.0) + 2.0;
           }
         f98=v3;
//----
         if (0.5<=f98 - 2.0)
           {
            f88=f98 - 2.0;
           }
         else
           {
            f88=0.5;
           }
         f78=MathSqrt(f80) * f98;
         f90=f78/(f78 + 1.0);
         f80=f80 * 0.9;
         f50=f80/(f80 + 2.0);
//----
         if (f0!=0)
           {
            f0=0;
            v5=0;
            for( ii=1;ii <=29;ii++)
              {
               if (buffer[ii+1]!=buffer[ii])
                 {
                  v5=1.0;
                 }
              }
            fD8=v5*30.0;
            if (fD8==0)
              {
               f38=series;
              }
            else
              {
               f38=buffer[1];
              }
            f18=f38;
            if (fD8 > 29)
               fD8=29;
           }
         else
            fD8=0;
//----
         for( ii=fD8;ii>=0;ii-- )
           { //{ another bigcycle...} 
            value2=31-ii;
            if (ii==0)
              {
               f8=series;
              }
            else
              {
               f8=buffer[value2];
              }
            f28=f8 - f18;
            f48=f8 - f38;
            if (MathAbs(f28) > MathAbs(f48))
              {
               v2=MathAbs(f28);
              }
            else
              {
               v2=MathAbs(f48);
              }
            fA0=v2;
            vv=fA0 + 0.0000000001; //{1.0e-10;} 
//----
            if (s48<=1)
              {
               s48=127;
              }
            else
              {
               s48=s48 - 1;
              }
            if (s50<=1)
              {
               s50=10;
              }
            else
              {
               s50=s50 - 1;
              }
            if (s70 < 128)
               s70=s70 + 1;
            s8=s8 + vv - ring2[s50];
            ring2[s50]=vv;
            if (s70 > 10)
              {
               s20=s8/10;
              }
            else
               s20=s8/s70;
//----
            if (s70 > 127)
              {
               s10=ring1[s48];
               ring1[s48]=s20;
               s68=64;
               s58=s68;
               while(s68 > 1)
                 {
                  if (list[s58] < s10)
                    {
                     s68=s68 *0.5;
                     s58=s58 + s68;
                    }
                  else
                     if (list[s58]<=s10)
                       {
                        s68=1;
                       }
                     else
                       {
                        s68=s68 *0.5;
                        s58=s58 - s68;
                       }
                 }
              }
            else
              {
               ring1[s48]=s20;
               if (s28 + s30 > 127)
                 {
                  s30=s30 - 1;
                  s58=s30;
                 }
               else
                 {
                  s28=s28 + 1;
                  s58=s28;
                 }
               if (s28 > 96)
                 {
                  s38=96;
                 }
               else
                  s38=s28;
               if (s30 < 32)
                 {
                  s40=32;
                 }
               else
                  s40=s30;
              }
//----
            s68=64;
            s60=s68;
            while(s68 > 1)
              {
               if (list[s60]>=s20)
                 {
                  if (list[s60 - 1]<=s20)
                    {
                     s68=1;
                    }
                  else
                    {
                     s68=s68 *0.5;
                     s60=s60 - s68;
                    }
                 }
               else
                 {
                  s68=s68 *0.5;
                  s60=s60 + s68;
                 }
               if ((s60==127) && (s20 > list[127]))
                  s60=128;
              }

            if (s70 > 127)
              {
               if (s58>=s60)
                 {
                  if ((s38 + 1 > s60) && (s40 - 1 < s60))
                    {
                     s18=s18 + s20;
                    }
                  else
                     if ((s40 > s60) && (s40 - 1 < s58))
                        s18=s18 + list[s40 - 1];
                 }
               else
                  if (s40>=s60)
                    {
                     if ((s38 + 1 < s60) && (s38 + 1 > s58))
                        s18=s18 + list[s38 + 1];
                    }
                  else
                     if (s38 + 2 > s60)
                       {
                        s18=s18 + s20;
                       }
                     else
                        if ((s38 + 1 < s60) && (s38 + 1 > s58))
                           s18=s18 + list[s38 + 1];

               if (s58 > s60)
                 {
                  if ((s40 - 1 < s58) && (s38 + 1 > s58))
                    {
                     s18=s18 - list[s58];
                    }
                  else
                     if ((s38 < s58) && (s38 + 1 > s60))
                        s18=s18 - list[s38];
                 }
               else
                 {
                  if ((s38 + 1 > s58) && (s40 - 1 < s58))
                    {
                     s18=s18 - list[s58];
                    }
                  else
                     if ((s40 > s58) && (s40 < s60))
                        s18=s18 - list[s40];
                 }
              }
            if (s58<=s60)
              {
               if (s58>=s60)
                 {
                  list[s60]=s20;
                 }
               else
                 {
                  for( jj=s58 + 1;jj<=s60 - 1;jj++)
                    {
                     list[jj - 1]=list[jj];
                    }
                  list[s60 - 1]=s20;
                 }
              }
            else
              {
               for( jj=s58 - 1;jj>=s60;jj-- )
                 {
                  list[jj + 1]=list[jj];
                 }
               list[s60]=s20;
              }
            if (s70<=127)
              {
               s18=0;
               for(jj=s40;jj<=s38;jj++)
                 {
                  s18=s18 + list[jj];
                 }
              }
            f60=s18/(s38 - s40 + 1);
            if (fF8 + 1 > 31)
              {
               fF8=31;
              }
            else
               fF8=fF8 + 1;
//----
            if (fF8<=30)
              {
               if (f28 > 0)
                 {
                  f18=f8;
                 }
               else
                  f18=f8 - f28 * f90;
               if (f48 < 0)
                 {
                  f38=f8;
                 }
               else
                  f38=f8 - f48 * f90;
               fB8=series;
//{EasyLanguage does not have "continue" statement} 
               if (fF8!=30)
                 {
                  continue;
                 }
               if (fF8==30)
                 {
                  fC0=series;
                  if (MathCeil(f78)>=1)
                    {
                     v4=MathCeil(f78);
                    }
                  else
                     v4=1;
                  fE8=MathCeil(v4);
                  if (MathFloor(f78)>=1)
                    {
                     v2=MathFloor(f78);
                    }
                  else
                     v2=1;
                  fE0=MathCeil(v2);
                  if (fE8==fE0)
                    {
                     f68=1;
                    }
                  else
                    {
                     v4=fE8 - fE0;
                     f68=(f78 - fE0)/v4;
                    }
                  if (fE0<=29)
                    {
                     v5=fE0;
                    }
                  else
                     v5=29;
                  if (fE8<=29)
                    {
                     v6=fE8;
                    }
                  else
                     v6=29;
                  fA8=(series - buffer[fF0 - v5]) * (1 - f68)/fE0 + (series - buffer[fF0 - v6]) * f68/fE8;
                 }
              }
            else
              {
               if (f98>=MathPow(fA0/f60, f88))
                 {
                  v1=MathPow(fA0/f60, f88);
                 }
               else
                  v1=f98;
               if (v1 < 1)
                 {
                  v2=1;
                 }
               else
                 {
                  if (f98>=MathPow(fA0/f60, f88))
                    {
                     v3=MathPow(fA0/f60, f88);
                    }
                  else
                     v3=f98;
                  v2=v3;
                 }
               f58=v2;
               f70=MathPow(f90, MathSqrt(f58));
               if (f28 > 0)
                 {
                  f18=f8;
                 }
               else
                 {
                  f18=f8 - f28 * f70;
                 }
               if (f48 < 0)
                 {
                  f38=f8;
                 }
               else
                 {
                  f38=f8 - f48 * f70;
                 }
              }
           }
         if (fF8 > 30)
           {
            f30=MathPow(f50, f58);
            fC0=(1 - f30) * series + f30 * fC0;
            fC8=(series - fC0) * (1 - f50) + f50 * fC8;
            fD0=f10 * fC8 + fC0;
            f20=-f30 * 2;
            f40=f30 * f30;
            fB0=f20 + f40 + 1;
            fA8=(fD0 - fB8) * fB0 + f40 * fA8;
            fB8=fB8 + fA8;
           }
         JMA= fB8;
        }
      if (fF0<=30)
        {
         JMA=0;
        }
//Print ("JMA is " + JMA + " shift is " + shift); 
      ExtMapBuffer1[shift]=JMA;
     }
//----
   return(0);
  }
//+------------------------------------------------------------------+

Comments