Author: Federico Costalonga
Miscellaneous
Implements a curve of type %1
0 Views
0 Downloads
0 Favorites
JBands_v1
//+------------------------------------------------------------------+
//|                                                       JBands.mq4 |
//|                                              Federico Costalonga |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Federico Costalonga"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Orange
#property indicator_color2 Red
#property indicator_color3 Lime
//---- input parameters
extern int       Length = 14;
extern int       Phase  = 0;
extern double    Deviations=2.4;
//---- buffers
double JMAValueBuffer[],JMAUpperValueBuffer[],JMALowerValueBuffer[];
double fC0Buffer[];
double fA8Buffer[];
double fC8Buffer[];
double UpperBuffer[];
double LowerBuffer[];
double MovingBuffer[];
//---- 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_LINE);
   SetIndexBuffer(0,JMAValueBuffer);
   SetIndexStyle(1,DRAW_LINE);
   SetIndexBuffer(1,JMAUpperValueBuffer);
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,JMALowerValueBuffer);
   SetIndexDrawBegin(0,Length);
   SetIndexDrawBegin(1,Length);
   SetIndexDrawBegin(2,Length);
//---- additional indicators buffers mapping
   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("JBandsValue("+Length+","+Phase+","+Deviations+")");
   SetIndexLabel(0,"JBandsValue");
//---- 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()
  {

   int    q,k;
   double deviation;
   double sum,oldval,newres;

   int counted_bars=IndicatorCounted();
   if(counted_bars < 0)  return(-1);
   if(counted_bars>0) counted_bars--;
   int limit=Bars-counted_bars;
   if(counted_bars==0) limit-=1+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;

        }

      //---- End of main cycle

     }
//----
   ArrayResize(MovingBuffer,ArraySize(JMAValueBuffer));
   for(q=0; q<limit; q++)
      MovingBuffer[q]=JMAValueBuffer[q];

//q=Bars-Length+1;
//if(counted_bars>Length-1) q=Bars-counted_bars-1;
   q=limit-Length+1;
   while(q>=0)
     {
      sum=0.0;
      k=q+Length-1;
      oldval=JMAValueBuffer[q];
      while(k>=q)
        {
         newres=Close[k]-oldval;
         sum+=newres*newres;
         k--;
        }
      deviation=Deviations*MathSqrt(sum/Length);
      JMAUpperValueBuffer[q]=oldval+deviation;
      JMALowerValueBuffer[q]=oldval-deviation;
      q--;
     }

   return;

  }
//+------------------------------------------------------------------+
int IntPortion(double param)
  {
   if(param > 0) return (MathFloor (param));
   if(param < 0) return (MathCeil (param));
   return (0.0);
  }
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---