Indicators: ATR adaptive SMA

 

ATR adaptive SMA:

ATR adaptive SMA (Simple Moving Average)

ATR adaptive SMA

Author: Mladen Rakic

 
@Mladen Rakic I am having troubles converting this to an include file, specificly what do i do with rates_total and prev? I would rather you suggest readings, than do the job for me. Thanks.
 
Revo Trades:
@Mladen Rakic I am having troubles converting this to an include file, specificly what do i do with rates_total and prev? I would rather you suggest readings, than do the job for me. Thanks.

Since it is not using any extraordinary methods that would make it more complicated to convert it, you can convert it to include file as any other indicator that you have already converted to include file

 
Mladen Rakic:

Since it is not using any extraordinary methods that would make it more complicated to convert it, you can convert it to include file as any other indicator that you have already converted to include file

see Include file attached. I dont know how to deal with the 2 variables rates_total and limit, saying "Undeclared identifier". I do not want you to fix it for me. Please refer me to a document or reading.

Files:
 
Revo Trades:

see Include file attached. I dont know how to deal with the 2 variables rates_total and limit, saying "Undeclared identifier". I do not want you to fix it for me. Please refer me to a document or reading.

Use iBars() for rates_total  and prev_calculated(initially zero) is same as rates_total unless there is a new bar.
 
Navdeep Singh:
Use iBars() for rates_total  and prev_calculated(initially zero) is same as rates_total unless there is a new bar.

but wont that mean that the function will only update 1 time per bar?

 
Revo Trades:

but wont that mean that the function will only update 1 time per bar?

1) FYI for those trying to create include files: I found out I can import an indicator without creating an include file or a new function. Instead I used a mql command "resource". And I was able to import my external indicator into the ea, just as I would with an include or library file.

But, question for @Mladen Rakic : I have used "resource" in add in 2 indicators, both have OnCalculate; my question: Is there any issue with having these 2 files with same Oncalculate? or do i need to only use 1 function Oncalculate?

 
Revo Trades:
@Mladen Rakic I am having troubles converting this to an include file, specificly what do i do with rates_total and prev? I would rather you suggest readings, than do the job for me. Thanks.


Rates_total and prev cannot be put on the include file. They are part of the OnCalculate() function.


Get the content inside the OnCalculate, create a new function, put the contents inside it.

Erase the contents from the OnCalculate function.

Call your newly created function inside the OnCalculate.

Move your new function to the include .mqh file.

#include <the_mqlfile.mqh> on your main app

It is done. 

SImple.


PS: Create the respective parameters to pass to your new function. It depends on each indicator you will want to do this, as each one has its particular variables.

Pass them as function parameters. 

 
it is nt as easy as that for this indicator.
 
Revo Trades:
it is nt as easy as that for this indicator.

Yes it is as simple as that, I just give a look at the source code of it. It can be done under 15 minutes. 

What is being your main problem right now? Still the rates_total and Prev_rates ?

 

@Mladen Rakic @rrocchi

I am trying to add std deviation bands to this. See my attempt below and how it appears on the chart. I appreciate any advice on finding what i have done or have not done, and I prefer to find the solution myself if possible; but thanks to Mladen for creating the top 1 of 5 of my most used indicators.

//------------------------------------------------------------------
#property copyright   "© mladen, 2020"
#property link        "mladenfx@gmail.com"
#property version     "1.00"
#property description "ATR adaptive"
//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 6
#property indicator_label1  "SMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrWhite
#property indicator_label2  "ATR adaptive"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrBlue
#property indicator_width2  2
#property indicator_label3  "ATR adaptive"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrRed
#property indicator_width3  2
#property indicator_label4  "ATR adaptive"
#property indicator_type4   DRAW_LINE
#property indicator_color4  clrYellow
#property indicator_width4  2
#property indicator_label5  "ATR Upper Band"
#property indicator_type5   DRAW_LINE
#property indicator_color5  clrOrange
#property indicator_label6  "ATR Lower Band"
#property indicator_type6   DRAW_LINE
#property indicator_color6  clrOrange
#property strict

//
//
//

input int                inpMaPeriod = 25;          // SMA period
input ENUM_APPLIED_PRICE inpPrice    = PRICE_CLOSE; // Price
enum enColorMode
  {
   col_onSlope, // Change color on slope change
   col_onCross, // Change color on two sma cross
  };
input enColorMode        inpColorMode = col_onCross; // Color change mode
input double InpBandsDeviations = 1.0;
double val[],valda[],valdb[],valc[],sma[],atr[],ExtStdDevBuffer[],ExtUpperBuffer[],ExtLowerBuffer[];

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   IndicatorBuffers(9);
   IndicatorDigits(Digits+1);
   SetIndexBuffer(0,sma,INDICATOR_DATA);
   SetIndexBuffer(1,val,INDICATOR_DATA);
   SetIndexBuffer(2,valda,INDICATOR_DATA);
   SetIndexBuffer(3,valdb,INDICATOR_DATA);
   SetIndexBuffer(4,ExtUpperBuffer,INDICATOR_DATA);
   SetIndexBuffer(5,ExtLowerBuffer,INDICATOR_DATA);
   SetIndexBuffer(6,valc,INDICATOR_COLOR_INDEX);
   SetIndexBuffer(7,atr,INDICATOR_CALCULATIONS);
   SetIndexBuffer(8,ExtStdDevBuffer,INDICATOR_CALCULATIONS);

   IndicatorSetString(INDICATOR_SHORTNAME,"ATR adaptive SMA ("+(string)inpMaPeriod+")");
   return (INIT_SUCCEEDED);
  }
void OnDeinit(const int reason) { }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
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 pos,r,i,limit = rates_total-prev_calculated;
   if(limit>=rates_total-1)
      limit = rates_total-1;

   if(prev_calculated>1)
      pos=prev_calculated-1;
   else
      pos=0;

   if(prev_calculated<1)
     {
      for(int j=0; j<inpMaPeriod; j++)
        {
         //         ExtMovingBuffer[i]=EMPTY_VALUE;
         //         ExtStdDevBuffer[j]=EMPTY_VALUE;
         ExtUpperBuffer[j]=EMPTY_VALUE;
         ExtLowerBuffer[j]=EMPTY_VALUE;
        }
     }

   struct sWorkStruct
     {
      double         price;
      double         tr;
      double         sumtr;
      double         min;
      double         max;
      double         sum;
      double         sumSma;
      int            period;
      int            prevBar;
                     sWorkStruct() : prevBar(-1), period(INT_MIN) {};
     };
   static sWorkStruct m_work[];
   static int         m_workSize = -1;
   if(m_workSize<=rates_total)
      m_workSize = ArrayResize(m_work,rates_total+100,400);

   if(valc[limit]==1)
      CleanPoint(limit,valda,valdb);
   for(i=limit, r=rates_total-i-1; i>=0 && !_StopFlag; i--,r++)
     {
      m_work[r].price = iMA(_Symbol,_Period,1,0,MODE_SMA,inpPrice,i);;
      m_work[r].tr    = (r>0) ? (high[i]>close[i+1] ? high[i] : close[i+1]) -(low[i]<close[i+1] ? low[i] : close[i+1]) : high[i]-low[i];
      if(r>inpMaPeriod)
        {
         m_work[r].sumSma = m_work[r-1].sumSma + m_work[r].price - m_work[r-inpMaPeriod].price;
         m_work[r].sumtr  = m_work[r-1].sumtr  + m_work[r].tr    - m_work[r-inpMaPeriod].tr;
        }
      else
        {
         m_work[r].sumSma = m_work[r].price;
         for(int k=1; k<inpMaPeriod && r>=k; k++)
            m_work[r].sumSma += m_work[r-k].price;
         m_work[r].sumtr  = m_work[r].tr;
         for(int k=1; k<inpMaPeriod && r>=k; k++)
            m_work[r].sumtr  += m_work[r-k].tr;
        }
      atr[i] = m_work[r].sumtr/(double)inpMaPeriod;
      sma[i] = NormalizeDouble(m_work[r].sumSma/(double)inpMaPeriod,_Digits);

      if(m_work[r  ].prevBar !=r ||
         m_work[r+1].prevBar > r)
        {
         if(inpMaPeriod>1)
           {
            m_work[r].max = atr[ArrayMaximum(atr,inpMaPeriod-1,i)];
            m_work[r].min = atr[ArrayMinimum(atr,inpMaPeriod-1,i)];
           }
         else
           {
            m_work[r].max = -DBL_MAX;
            m_work[r].min = DBL_MAX;
           }
        }

      double _max   = m_work[r].max > atr[i] ? m_work[r].max : atr[i];
      double _min   = m_work[r].min < atr[i] ? m_work[r].min : atr[i];
      double _coeff = (_min!=_max) ? 1-(atr[i]-_min)/(_max-_min) : 0.5;

      int _period = int(inpMaPeriod*(_coeff+1.0)/2.0);
      if(m_work[r  ].prevBar !=r ||
         m_work[r+1].prevBar > r ||
         m_work[r+1].period != _period)
        {
         m_work[r  ].prevBar = r;
         m_work[r+1].prevBar = -1;
         m_work[r+1].period  = _period;
         m_work[r].sum       = 0;
         for(int k=1; k<_period && r>=k; k++)
            m_work[r].sum += m_work[r-k].price;
        }

      val[i]  = (_period>0) ? NormalizeDouble((m_work[r].sum+m_work[r].price)/(double)_period,Digits+1) : m_work[r].price;

      if(inpColorMode==col_onSlope)
         valc[i] = (r>0) ? (val[i]>val[i+1]) ? 2 : (val[i]<val[i+1]) ? 1 : valc[i+1]: 0;
      else
         valc[i] = (val[i]>sma[i]) ? 2 :(val[i]<sma[i]) ? 1 : (r>0) ? valc[i+1]: 0;
      if(valc[i]==1)
         PlotPoint(i,valda,valdb,val);
      else
         valda[i] = valdb[i] = EMPTY_VALUE;

     }

   for(int j=pos; j<rates_total && !IsStopped(); j++)
     {
      //--- calculate and write down StdDev
      ExtStdDevBuffer[j]=StdDev_Func(j,close,val,inpMaPeriod);
      //--- upper line
      ExtUpperBuffer[j]=val[j]+InpBandsDeviations*ExtStdDevBuffer[j];
      //--- lower line
      ExtLowerBuffer[j]=val[j]-InpBandsDeviations*ExtStdDevBuffer[j];
     }
     
   return(rates_total);
  }

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
void CleanPoint(int i,double& first[],double& second[])
  {
   if(i>=Bars-3)
      return;
   if((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))
      second[i+1] = EMPTY_VALUE;
   else
      if((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))
         first[i+1] = EMPTY_VALUE;
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PlotPoint(int i,double& first[],double& second[],double& from[])
  {
   if(i>=Bars-2)
      return;
   if(first[i+1] == EMPTY_VALUE)
      if(first[i+2] == EMPTY_VALUE)
        { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }
      else
        {
         second[i] = from[i];
         second[i+1] = from[i+1];
         first[i]  = EMPTY_VALUE;
        }
   else
     {
      first[i]  = from[i];
      second[i] = EMPTY_VALUE;
     }
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double StdDev_Func(int position,const double &price[],const double &MAprice[],int period)
  {
//--- variables
   double StdDev_dTmp=0.0;
//--- check for position
   if(position>=period)
     {
      //--- calcualte StdDev
      for(int i=0; i<period; i++)
         StdDev_dTmp+=MathPow(price[position-i]-MAprice[position],2);
      StdDev_dTmp=MathSqrt(StdDev_dTmp/period);
     }
//--- return calculated value
   return(StdDev_dTmp);
  }
//+------------------------------------------------------------------+

AtrSmaBands_strike1

Reason: