Ultimate_MA

Author: Copyright 2020, MetaQuotes Software Corp.
Indicators Used
Indicator of the average true range
0 Views
0 Downloads
0 Favorites
Ultimate_MA
//+------------------------------------------------------------------+
//|                                                  Ultimate_MA.mq5 |
//|                        Copyright 2020, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2020, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"

//------------------------------------------------------------------
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   2
#property indicator_label1  "Ultimate MA"
#property indicator_color1 clrMediumVioletRed
#property indicator_type1   DRAW_LINE
#property indicator_width1  1


//------------------------------------------------------------------

//---- input parameters
input ENUM_MA_METHOD MA_Method = MODE_SMA;  // Method
input int fastperiod=5;                     // Fast Period
input int middleperiod=34;                  // Middle Period
input int slowperiod=55;                    // Slow Period
input double fastK=4.0;                          // Fast Multiplier
input double middleK=2.0;                        // Middle Multiplier
input double slowK=1.0;                          // Slow Multiplier
//---- buffers
double UOBuffer[];
double BPBuffer[];
double divider;

int atrFastH;
int atrMiddleH;
int atrSlowH;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   string name;
   name="UMA("+fastperiod+", "+middleperiod+", "+slowperiod+")";
   
   SetIndexBuffer(0, UOBuffer, INDICATOR_DATA);
   SetIndexBuffer(1, BPBuffer, INDICATOR_CALCULATIONS);
   
   
   IndicatorSetString(INDICATOR_SHORTNAME, name);
   IndicatorSetInteger(INDICATOR_DIGITS, 5);
   divider=fastK+middleK+slowK;
   
   atrFastH = iATR(_Symbol, PERIOD_CURRENT, fastperiod);
   atrMiddleH = iATR(_Symbol, PERIOD_CURRENT, middleperiod);
   atrSlowH = iATR(_Symbol, PERIOD_CURRENT, slowperiod);
   
   if(atrFastH==INVALID_HANDLE)Print(" Failed to get handle of the iATR fast indicator");
   if(atrMiddleH==INVALID_HANDLE)Print(" Failed to get handle of the iATR mid indicator");
   if(atrSlowH==INVALID_HANDLE)Print(" Failed to get handle of the iATR slow indicator");
   
   ArraySetAsSeries(UOBuffer,true);
   ArraySetAsSeries(BPBuffer,true);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 i,limit,limit2;
   double RawUO;
   
   double ATRFast[];
   double ATRMiddle[];
   double ATRSlow[];
   
   
   if (prev_calculated>0)
   {
      limit = rates_total + 1 - prev_calculated;
      limit2 = limit;
   }
   else
   {
      limit = rates_total - 2;
      limit2 = rates_total - slowperiod;
   }
   
   CopyBuffer(atrFastH, 0, 0, limit2, ATRFast);
   CopyBuffer(atrMiddleH, 0, 0, limit2, ATRMiddle);
   CopyBuffer(atrSlowH, 0, 0, limit2, ATRSlow);
   
   for (i=0; i<limit; i++)
   {
      BPBuffer[i] = (2.0*((open[rates_total-1-i]+close[rates_total-1-i])/2.0)+((high[rates_total-1-i]+low[rates_total-1-i])/2.0))/3.0;
   }
   
   for (i=limit2-1; i>=0; i--)
   {
    
      RawUO = (fastK+3.0*ATRFast[limit2-1-i])*MAOnArray(BPBuffer, 0, fastperiod, 0, MA_Method, i)
              +(middleK+3.0*ATRMiddle[limit2-1-i])*MAOnArray(BPBuffer, 0, middleperiod, 0, MA_Method, i)
              +(slowK+3.0*ATRSlow[limit2-1-i])*MAOnArray(BPBuffer, 0, slowperiod, 0, MA_Method, i);
              
              
      divider = (fastK+3.0*ATRFast[limit2-1-i])+(middleK+3.0*ATRMiddle[limit2-1-i])+(slowK+3.0*ATRSlow[limit2-1-i]);

      
      UOBuffer[i] = RawUO/divider;
   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| iMAOnArray() https://www.mql5.com/ru/articles/81                 |
//+------------------------------------------------------------------+
double MAOnArray(double &array[],int total,int period,int ma_shift,int ma_method,int shift)
  {
   double buf[],arr[];
   if(total==0) total=ArraySize(array);
   if(total>0 && total<=period) return(0);
   if(shift>total-period-ma_shift) return(0);
//---
   switch(ma_method)
     {
      case MODE_SMA :
        {
         total=ArrayCopy(arr,array,0,shift+ma_shift,period);
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,pos=total-1;
         for(i=1;i<period;i++,pos--)
            sum+=arr[pos];
         while(pos>=0)
           {
            sum+=arr[pos];
            buf[pos]=sum/period;
            sum-=arr[pos+period-1];
            pos--;
           }
         return(buf[0]);
        }
      case MODE_EMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double pr=2.0/(period+1);
         int    pos=total-2;
         while(pos>=0)
           {
            if(pos==total-2) buf[pos+1]=array[pos+1];
            buf[pos]=array[pos]*pr+buf[pos+1]*(1-pr);
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_SMMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0;
         int    i,k,pos;
         pos=total-period;
         while(pos>=0)
           {
            if(pos==total-period)
              {
               for(i=0,k=pos;i<period;i++,k++)
                 {
                  sum+=array[k];
                  buf[k]=0;
                 }
              }
            else sum=buf[pos+1]*(period-1)+array[pos];
            buf[pos]=sum/period;
            pos--;
           }
         return(buf[shift+ma_shift]);
        }
      case MODE_LWMA :
        {
         if(ArrayResize(buf,total)<0) return(0);
         double sum=0.0,lsum=0.0;
         double price;
         int    i,weight=0,pos=total-1;
         for(i=1;i<=period;i++,pos--)
           {
            price=array[pos];
            sum+=price*i;
            lsum+=price;
            weight+=i;
           }
         pos++;
         i=pos+period;
         while(pos>=0)
           {
            buf[pos]=sum/weight;
            if(pos==0) break;
            pos--;
            i--;
            price=array[pos];
            sum=sum-lsum+price*period;
            lsum-=array[i];
            lsum+=price;
           }
         return(buf[shift+ma_shift]);
        }
      default: return(0);
     }
   return(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 ---