Author: Copyright � 2004, MetaQuotes Software Corp.
MA_dots

This script is designed as a versatile technical analysis tool for the MetaTrader platform. Its primary purpose is to calculate and display various types of Moving Averages, which are used by traders to smooth out price fluctuations and identify the underlying trend of a financial asset.

Instead of providing just one type of calculation, this tool allows users to choose between four distinct mathematical methods to interpret price data. Here is a breakdown of how the logic functions:

Core Configuration

The script begins by establishing three main settings that dictate how the data is processed:

  • Period: Determines the "window" of time or data points used for the calculation (e.g., looking at the last 200 candles).
  • Shift: Allows the user to move the resulting line forward or backward on the chart.
  • Method: This is the core selector that tells the script which specific mathematical formula to apply to the price history.

The Four Calculation Methods

Depending on the selected method, the script switches between these distinct logical paths:

  1. Simple Moving Average (SMA): This is the standard approach. It takes the closing prices of all candles within the chosen period, adds them together, and divides by the total number of candles. Every candle in the window carries equal weight.
  2. Exponential Moving Average (EMA): This method gives more importance to recent price action. By applying a weighting factor, it reacts more quickly to sudden price changes than a simple average, making it popular for identifying fast-moving trends.
  3. Smoothed Moving Average (SMMA): This logic focuses on eliminating "noise." It creates a smoother line by incorporating the previous average into the current calculation, which helps in identifying long-term trends while ignoring minor price spikes.
  4. Linear Weighted Moving Average (LWMA): This method assigns a linear weight to each data point. The most recent price is given the highest weight, and the weights decrease progressively for older candles. This creates a balance between reactivity and smoothing.

Operational Workflow

When the script runs on a chart, it follows these automated steps:

  • Data Validation: It first checks if there are enough historical bars available to perform the requested calculation based on your chosen period. If the data is insufficient, it will not display anything to avoid inaccurate readings.
  • Dynamic Labeling: The script automatically updates its own name on the chart (e.g., "EMA(200)" or "LWMA(200)") so you can easily identify which calculation is currently active.
  • Real-Time Processing: The script continuously scans the price history and populates a visual buffer. This translates the complex math into a visible red line on your chart, providing a clear visual representation of market momentum.
Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
MA_dots
//+------------------------------------------------------------------+
//|                                        Custom Moving Average.mq4 |
//|                      Copyright © 2004, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int MA_Period=200;
extern int MA_Shift=0;
extern int MA_Method=0;
//---- indicator buffers
double ExtMapBuffer[];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   int    draw_begin;
   string short_name;
//---- drawing settings
      SetIndexStyle(0,DRAW_ARROW,EMPTY);
      SetIndexArrow(0,115);
   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>=0)
     {
      sum+=Close[pos];
      ExtMapBuffer[pos]=sum/MA_Period;
	   sum-=Close[pos+MA_Period-1];
 	   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;
   if(ExtCountedBars>2) pos=Bars-ExtCountedBars-1;
//---- main calculation loop
   while(pos>=0)
     {
      if(pos==Bars-2) ExtMapBuffer[pos+1]=Close[pos+1];
      ExtMapBuffer[pos]=Close[pos]*pr+ExtMapBuffer[pos+1]*(1-pr);
 	   pos--;
     }
  }
//+------------------------------------------------------------------+
//| Smoothed Moving Average                                          |
//+------------------------------------------------------------------+
void smma()
  {
   double sum=0;
   int    i,k,pos=Bars-ExtCountedBars+1;
//---- main calculation loop
   pos=Bars-MA_Period;
   if(pos>Bars-ExtCountedBars) pos=Bars-ExtCountedBars;
   while(pos>=0)
     {
      if(pos==Bars-MA_Period)
        {
         //---- initial accumulation
         for(i=0,k=pos;i<MA_Period;i++,k++)
           {
            sum+=Close[k];
            //---- zero initial bars
            ExtMapBuffer[k]=0;
           }
        }
      else sum=ExtMapBuffer[pos+1]*(MA_Period-1)+Close[pos];
      ExtMapBuffer[pos]=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;
//---- 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>=0)
     {
      ExtMapBuffer[pos]=sum/weight;
      if(pos==0) break;
      pos--;
      i--;
      price=Close[pos];
      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