Moving Averages Advance

Download script
Author: Copyright � 2004, MetaQuotes Software Corp. 2007, MQL Service
Moving Averages Advance

This script is a specialized technical analysis tool designed for use on trading charts to visualize price trends. Its primary function is to calculate and display various types of "Moving Averages," which are used by traders to smooth out price fluctuations and identify the underlying direction of the market.

Core Functionality

The script provides four distinct methods for calculating moving averages, allowing users to choose the mathematical model that best fits their trading strategy:

  • Simple Moving Average (SMA): Calculates the basic average of price data over a specific number of periods.
  • Exponential Moving Average (EMA): Gives more weight to recent price data, making it more responsive to new market information.
  • Smoothed Moving Average (SMMA): A variation that smooths out price action even further by incorporating a weighted calculation based on previous averages.
  • Linear Weighted Moving Average (LWMA): Assigns a linear weight to each data point, where the most recent data carries the highest influence on the current average.

Key Technical Features

The logic within this script includes several unique behaviors that distinguish it from standard moving average indicators:

1. Advanced Offset Positioning Unlike standard indicators that sit directly on the current price, this script features a "Move Advance" capability. This allows the indicator line to be shifted forward or backward on the chart relative to the current market price. This is useful for visual spacing or aligning the indicator with specific historical data points.

2. Dynamic Calculation Engines The script is programmed to automatically switch its internal logic based on your selection. Depending on which method you choose (SMA, EMA, SMMA, or LWMA), the script changes how it processes the "Close" prices of the candles to generate the final visual line.

3. Initialization and Optimization The script includes logic to ensure the chart remains clean and accurate:

  • It validates that there is enough historical data available before attempting to draw a line (preventing errors on new charts).
  • It automatically adjusts the starting point of the drawing to ensure the line appears smoothly from its first valid calculation.
  • It handles "zero-filling" for the initial bars, ensuring that no phantom data points appear before the indicator has enough information to calculate a valid average.

Summary for the User

In simple terms, this tool acts as a customizable "trend smoother." It takes raw market prices and converts them into a readable line on your chart. By offering four different types of averages and an "advance" feature to move that line forward or backward, it gives you greater flexibility in how you visualize market momentum and historical price flow.

Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
Moving Averages Advance
//+------------------------------------------------------------------+
//|                                      Moving Averages Advance.mq4 |
//|    Copyright © 2004, MetaQuotes Software Corp. 2007, MQL Service |
//|                                       http://www.mqlservice.com/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp. 2007, MQL Service"
#property link      "http://www.mqlservice.com/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int MA_Period=13;
extern int MA_Shift=0;
extern int MA_Method=0;
extern int MA_Advance=30; // Added by MQL Serivce
//---- indicator buffers
double ExtMapBuffer[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int    draw_begin;
   string short_name;
//---- drawing settings
   SetIndexStyle(0,DRAW_LINE);
   SetIndexShift(0,MA_Shift+MA_Advance);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   if(MA_Period<2) MA_Period=13;
   draw_begin=MA_Period-1;
//---- indicator short name
   switch(MA_Method)
     {
      case 1 : short_name="EMA(";  draw_begin=0; break;
      case 2 : short_name="SMMA("; break;
      case 3 : short_name="LWMA("; break;
      default :
         MA_Method=0;
         short_name="SMA(";
     }
   IndicatorShortName(short_name+MA_Period+")");
   SetIndexDrawBegin(0,draw_begin);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   if(Bars<=MA_Period) return(0);
   ExtCountedBars=IndicatorCounted();
//---- check for possible errors
   if (ExtCountedBars<0) return(-1);
//---- last counted bar will be recounted
   if (ExtCountedBars>0) ExtCountedBars--;
//----
   switch(MA_Method)
     {
      case 0 : sma();  break;
      case 1 : ema();  break;
      case 2 : smma(); break;
      case 3 : lwma();
     }
//---- done
   return(0);
  }
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
void sma()
  {
   double sum=0;
   int    i,pos=Bars-ExtCountedBars-1;
//---- initial accumulation
   if(pos<MA_Period) pos=MA_Period;
   for(i=1;i<MA_Period;i++,pos--)
      sum+=Close[pos];
//---- main calculation loop
   while(pos>=-MA_Advance)
     {
      int j = MathRound(MathMax(pos, 0));
      sum+=Close[j];
      ExtMapBuffer[pos+MA_Advance]=sum/MA_Period;
      j = MathRound(MathMax(pos+MA_Period-1, 0));
	   sum-=Close[j];
 	   pos--;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+
//| Exponential Moving Average                                       |
//+------------------------------------------------------------------+
void ema()
  {
   double pr=2.0/(MA_Period+1);
   int    pos=Bars-2-MA_Advance;
   if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1-MA_Advance;
//---- main calculation loop
   while(pos>=-MA_Advance)
     {
      int j=MathRound(MathMax(pos, 0));
      int k=pos+MA_Advance;
      
      if(k==Bars-2) ExtMapBuffer[k+1]=Close[k+1];
      ExtMapBuffer[k]=Close[j]*pr+ExtMapBuffer[k+1]*(1-pr);
 	   pos--;
     }
  }
//+------------------------------------------------------------------+
//| Smoothed Moving Average                                          |
//+------------------------------------------------------------------+
void smma()
  {
   double sum=0;
   int    i,k,pos=Bars-ExtCountedBars+1-MA_Advance;
//---- main calculation loop
   pos=Bars-MA_Period-MA_Advance;
   if(pos>Bars-ExtCountedBars-MA_Advance) pos=Bars-ExtCountedBars-MA_Advance;
   while(pos>=-MA_Advance)
     {
      if(pos==Bars-MA_Period-MA_Advance)
        {
         //---- initial accumulation
         for(i=0,k=pos+MA_Advance;i<MA_Period;i++,k++)
           {
            sum+=Close[k-MA_Advance];
            //---- zero initial bars
            ExtMapBuffer[k]=0;
           }
        }
      else {
        int p = MathMax(pos, 0);
        sum=ExtMapBuffer[pos+1+MA_Advance]*(MA_Period-1)+Close[p];
      }
      ExtMapBuffer[pos+MA_Advance]=sum/MA_Period;
 	   pos--;
     }
  }
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
void lwma()
  {
   double sum=0.0,lsum=0.0;
   double price;
   int    i,weight=0,pos=Bars-ExtCountedBars-1-MA_Advance;
//---- initial accumulation
   if(pos<MA_Period) pos=MA_Period;
   for(i=1;i<=MA_Period;i++,pos--)
     {
      price=Close[pos];
      sum+=price*i;
      lsum+=price;
      weight+=i;
     }
//---- main calculation loop
   pos++;
   i=pos+MA_Period;
   while(pos>=-MA_Advance)
     {
      ExtMapBuffer[pos+MA_Advance]=sum/weight;
      if(pos==-MA_Advance) break;
      pos--;
      if(i>0) i--;
      int p=MathMax(pos, 0);
      price=Close[p];
      sum=sum-lsum+price*MA_Period;
      lsum-=Close[i];
      lsum+=price;
     }
//---- zero initial bars
   if(ExtCountedBars<1)
      for(i=1;i<MA_Period;i++) ExtMapBuffer[Bars-i]=0;
  }
//+------------------------------------------------------------------+

Comments