JMASlope_002





//+------------------------------------------------------------------+
//|                                                     JMASlope.mq4 |
//|                           Copyright © 2005, TrendLaboratory Ltd. |
//|            http://finance.groups.yahoo.com/group/TrendLaboratory |
//|            Thanks to Weld, Jurik Research http://weld.torguem.net|
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, TrendLaboratory Ltd."
#property link      "http://finance.groups.yahoo.com/group/TrendLaboratory"
//----
#property indicator_separate_window
#property indicator_buffers 2
#property indicator_color1 Green
#property indicator_color2 Red
//---- input parameters
extern int       Length=14;
extern int       Phase =0;
//---- buffers
double UpBuffer [];
double DnBuffer [];
double JMAValueBuffer [];
double fC0Buffer [];
double fA8Buffer [];
double fC8Buffer [];
//---- temporary buffers
double list[128], ring1[128], ring2[11], buffer[62];
//---- bool flag
bool   initFlag;
//---- integer vars
int    limitValue, startValue, loopParam, loopCriteria;
int    cycleLimit, highLimit, counterA, counterB;
//---- double vars
double cycleDelta, lowDValue, highDValue, absValue, paramA, paramB;
double phaseParam, logParam, JMAValue, series, sValue, sqrtParam, lengthDivider;
//---- temporary int variables
int   s58, s60, s40, s38, s68;
//+------------------------------------------------------------------+
//| JMA initFlagization function                                     |
//+------------------------------------------------------------------+
int init()
  {
   double   lengthParam;
//---- 3 additional buffers are used for counting.
   IndicatorBuffers(6);
//---- drawing settings
   SetIndexStyle  (0, DRAW_HISTOGRAM);
   SetIndexStyle  (1, DRAW_HISTOGRAM);
   SetIndexDrawBegin(0, 30);
   SetIndexDrawBegin(1, 30);
//---- 4 indicator buffers mapping
   SetIndexBuffer (0, UpBuffer);
   SetIndexBuffer (1, DnBuffer);
   SetIndexBuffer (2, JMAValueBuffer);
   SetIndexBuffer (3, fC0Buffer);
   SetIndexBuffer (4, fA8Buffer);
   SetIndexBuffer (5, fC8Buffer);
//---- initialize one buffer (neccessary)   
   ArrayInitialize (ring2, 0);
   ArrayInitialize (ring1, 0);
   ArrayInitialize (buffer, 0);
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName ("JMASlope(" + Length + "," + Phase + ")");
   SetIndexLabel (0, "UpSlope");
   SetIndexLabel (1, "DownSlope");
//---- initial part
   limitValue=63;
   startValue=64;
//----   
   for(int i=0; i<=limitValue; i++) list [i]=-1000000;
   for(i=startValue; i<=127; i++)   list [i]=1000000;
//----
   initFlag =true;
   if (Length < 1.0000000002) lengthParam=0.0000000001;
   else lengthParam=(Length - 1)/2.0;
//----   
   if (Phase < -100) phaseParam=0.5;
   else if (Phase > 100) phaseParam=2.5;
      else phaseParam=Phase/100.0 + 1.5;
//----   
   logParam=MathLog (MathSqrt (lengthParam))/MathLog (2.0);
//----
   if (logParam + 2.0 < 0) logParam=0;
   else logParam=logParam + 2.0;
//----
   sqrtParam    =MathSqrt(lengthParam) * logParam;
   lengthParam  =lengthParam * 0.9;
   lengthDivider=lengthParam/(lengthParam + 2.0);
//----  
   return;
  }
//+------------------------------------------------------------------+
//| JMA iteration function                                           |
//+------------------------------------------------------------------+
int start()
  {
//---- get already counted bars    
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if (counted_bars < 0) return(-1);
   int limit=Bars - counted_bars - 1;
//---- main cycle
     for(int shift=limit; shift>=0; shift--) 
     {
      series=Close [shift];
//----
        if (loopParam < 61) 
        {
         loopParam++;
         buffer [loopParam]=series;
        }
        if (loopParam > 30) 
        {
           if (initFlag) 
           {
            initFlag=false;
//----
            int diffFlag=0;
              for(int i=1; i<=29; i++) 
              {
               if (buffer [i + 1]!=buffer [i]) diffFlag=1;
              }
            highLimit=diffFlag * 30;
//----
            if (highLimit==0) paramB=series;
            else paramB=buffer[1];

            paramA=paramB;
            if (highLimit > 29) highLimit=29;
           } 
           else
            highLimit=0;
         //---- big cycle
           for(i=highLimit; i>=0; i--) 
           {
            if (i==0) sValue=series; else sValue=buffer [31 - i];
            if (MathAbs (sValue - paramA) > MathAbs (sValue - paramB)) absValue=MathAbs(sValue - paramA); else absValue=MathAbs(sValue - paramB);
            double dValue=absValue + 0.0000000001; //1.0e-10; 
//----
            if (counterA<=1) counterA=127; else counterA--;
            if (counterB<=1) counterB=10;  else counterB--;
            if (cycleLimit < 128) cycleLimit++;
            cycleDelta+=(dValue - ring2 [counterB]);
            ring2 [counterB]=dValue;
            if (cycleLimit > 10) highDValue=cycleDelta/10.0; else highDValue=cycleDelta/cycleLimit;
              if (cycleLimit > 127) 
              {
               dValue=ring1 [counterA];
               ring1 [counterA]=highDValue;
               s68=64; s58=s68;
                 while(s68 > 1) 
                 {
                    if (list [s58] < dValue) 
                    {
                     s68=s68/2.0;
                     s58+=s68;
                    }
                     else
                       if (list [s58]<=dValue) 
                       {
                        s68=1;
                        }
                         else 
                        {
                     s68=s68/2.0;
                     s58-=s68;
                    }
                 }
               }
                else 
               {
               ring1 [counterA]=highDValue;
                 if ((limitValue + startValue) > 127) 
                 {
                  startValue--;
                  s58=startValue;
                  }
                   else 
                  {
                  limitValue++;
                  s58=limitValue;
                 }
               if (limitValue > 96) s38=96; else s38=limitValue;
               if (startValue < 32) s40=32; else s40=startValue;
              }
            //----		      
            s68=64;
            s60=s68;
              while(s68 > 1) 
              {
                 if (list [s60]>=highDValue) 
                 {
                    if (list [s60 - 1]<=highDValue) 
                    {
                     s68=1;
                    }
                    else 
                    {
                     s68=s68/2.0;
                     s60-=s68;
                    }
                 }
                 else 
                 {
                  s68=s68/2.0;
                  s60+=s68;
                 }
               if ((s60==127) && (highDValue > list[127])) s60=128;
              }
              if (cycleLimit > 127) 
              {
                 if (s58>=s60) 
                 {
                  if (((s38 + 1) > s60) && ((s40 - 1) < s60))
                     lowDValue+=highDValue;
                  else if ((s40 > s60) && ((s40 - 1) < s58))
                        lowDValue+=list [s40 - 1];
                 }
                 else if (s40>=s60) 
                 {
                     if (((s38 + 1) < s60) && ((s38 + 1) > s58))
                        lowDValue+=list[s38 + 1];
                    }
                  else if ((s38 + 2) > s60)
                        lowDValue+=highDValue;
                     else if (((s38 + 1) < s60) && ((s38 + 1) > s58))
                           lowDValue+=list[s38 + 1];
                 if (s58 > s60) 
                 {
                  if (((s40 - 1) < s58) && ((s38 + 1) > s58))
                     lowDValue-=list [s58];
                  else if ((s38 < s58) && ((s38 + 1) > s60))
                        lowDValue-=list [s38];
                 }
                 else 
                 {
                  if (((s38 + 1) > s58) && ((s40 - 1) < s58))
                     lowDValue-=list [s58];
                  else if ((s40 > s58) && (s40 < s60))
                        lowDValue-=list [s40];
                 }
              }
              if (s58<=s60) 
              {
                 if (s58>=s60) list[s60]=highDValue; else 
                 {
                    for(int j=s58 + 1; j<=(s60 - 1); j++) 
                    {
                     list [j - 1]=list[j];
                    }
                  list [s60 - 1]=highDValue;
                 }
               }
                else 
               {
                 for(j=s58 - 1; j>=s60; j--) 
                 {
                  list [j + 1]=list [j];
                 }
               list [s60]=highDValue;
              }
              if (cycleLimit<=127) 
              {
               lowDValue=0;
                 for(j=s40; j<=s38; j++) 
                 {
                  lowDValue+=list[j];
                 }
              }
            //----			    
            if ((loopCriteria + 1) > 31) loopCriteria=31; else loopCriteria++;
            double JMATempValue, sqrtDivider=sqrtParam/(sqrtParam + 1.0);
//----
              if (loopCriteria<=30) 
              {
               if (sValue - paramA > 0) paramA=sValue; else paramA=sValue - (sValue - paramA) * sqrtDivider;
               if (sValue - paramB < 0) paramB=sValue; else paramB=sValue - (sValue - paramB) * sqrtDivider;
               JMATempValue=series;
                 if (loopCriteria==30) 
                 {
                  fC0Buffer [shift]=series;
                  int intPart;
//----
                  if (MathCeil(sqrtParam)>=1) intPart=MathCeil(sqrtParam); else intPart=1;
                  int leftInt=IntPortion (intPart);
                  if (MathFloor(sqrtParam)>=1) intPart=MathFloor(sqrtParam); else intPart=1;
                  int rightPart=IntPortion (intPart);
//----
                  if (leftInt==rightPart) dValue=1.0;
                  else
                     dValue=(sqrtParam - rightPart)/(leftInt - rightPart);
                  if (rightPart<=29) int upShift=rightPart; else upShift=29;
                  if (leftInt<=29) int dnShift=leftInt; else dnShift=29;
                  fA8Buffer [shift]=(series - buffer [loopParam - upShift]) * (1 - dValue)/rightPart + (series - buffer[loopParam - dnShift]) * dValue/leftInt;
                 }
               }
                else 
               {
               double powerValue, squareValue;
//----
               dValue=lowDValue/(s38 - s40 + 1);
               if (0.5<=logParam - 2.0) powerValue=logParam - 2.0;
               else powerValue=0.5;
               if (logParam>=MathPow(absValue/dValue, powerValue)) dValue=MathPow (absValue/dValue, powerValue); else dValue=logParam;
               if (dValue < 1) dValue=1;
//----
               powerValue=MathPow (sqrtDivider, MathSqrt (dValue));
               if (sValue - paramA > 0) paramA=sValue; else paramA=sValue - (sValue - paramA) * powerValue;
               if (sValue - paramB < 0) paramB=sValue; else paramB=sValue - (sValue - paramB) * powerValue;
              }
           }
         // ---- end of big cycle                  			   
           if (loopCriteria > 30) 
           {
            JMATempValue=JMAValueBuffer [shift + 1];
            powerValue  =MathPow (lengthDivider, dValue);
            squareValue =MathPow (powerValue, 2);
//----
            fC0Buffer [shift]=(1 - powerValue) * series + powerValue * fC0Buffer [shift + 1];
            fC8Buffer [shift]=(series - fC0Buffer [shift]) * (1 - lengthDivider) + lengthDivider * fC8Buffer [shift + 1];
            fA8Buffer [shift]=(phaseParam * fC8Buffer [shift] + fC0Buffer [shift] - JMATempValue) *
            (powerValue * (-2.0) + squareValue + 1) + squareValue * fA8Buffer [shift + 1];
            JMATempValue+=fA8Buffer [shift];
           }
         JMAValue=JMATempValue;
        }
      if (loopParam<=30) JMAValue=0;
      JMAValueBuffer [shift]=JMAValue;
      double rel=JMAValueBuffer [shift]-JMAValueBuffer [shift+1];
      if(rel>=0)
        {
         UpBuffer[shift]=rel;
         DnBuffer[shift]=0;
        }
      else
        {
         DnBuffer[shift]=rel;
         UpBuffer[shift]=0;
        }
      //---- End of main cycle
     }
   return;
  }
//+------------------------------------------------------------------+
  int IntPortion (double param) 
  {
   if (param > 0) return(MathFloor (param));
   if (param < 0) return(MathCeil (param));
   return(0.0);
  }
//+------------------------------------------------------------------+



Sample





Analysis



Market Information Used:



Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:

Other Features: