(M) Moving Averages

Author: Copyright � 2004, MetaQuotes Software Corp.
(M) Moving Averages

This script is designed for the MetaTrader platform to provide visual price analysis by calculating and displaying various types of Moving Averages on a trading chart. Its primary purpose is to help traders identify trends by smoothing out volatile price fluctuations, allowing them to see the "big picture" of market movement more clearly.

Core Functionality

The script acts as a dynamic calculator that monitors the closing prices of an asset over a specific period of time. Depending on your preferences, it can calculate four different styles of averages, each reacting to price changes in a unique way:

  • Simple Moving Average (SMA): This is the standard average. It treats every price point in the selected timeframe with equal importance, providing a steady, balanced view of the trend.
  • Exponential Moving Average (EMA): This version gives more weight to the most recent price data. Because it reacts more quickly to new information, it is often preferred by traders who want to spot sudden shifts in momentum faster than a standard average would allow.
  • Smoothed Moving Average (SMMA): This calculation creates a much "softer" line by incorporating all previous data points into the current average. It is designed to filter out "noise" or minor price spikes, making it ideal for identifying long-term trends.
  • Linear Weighted Moving Average (LWMA): Similar to the exponential model, this gives more importance to recent prices, but it does so using a linear progression. It provides a distinct balance between responsiveness and smoothness.

How the Logic Works

The script operates through three main stages:

  1. Configuration: When you load the script, it establishes your rules—specifically, how many past candles to look at (the Period), how far to offset the visual line on the chart (the Shift), and which of the four math models (SMA, EMA, SMMA, or LWMA) you want to use.
  2. Data Processing: The script continuously scans the historical "Close" prices of the market. It organizes these prices into a mathematical sequence based on your chosen method. For example, if you choose a Simple Moving Average, it adds up all prices in your period and divides by the total number of bars to find the mean.
  3. Visual Rendering: Once the calculation is complete, the script draws a continuous line on your chart. This line represents the "average" price path. By watching where the current price sits in relation to this line, traders can visually determine if the market is currently trending upward, downward, or moving sideways.

User Experience

For the end-user, the logic is automated entirely. You do not need to perform any manual math; the script handles the heavy lifting of calculating complex averages in real-time as new price data arrives, updating the visual line on your chart instantly so you can make informed trading decisions based on current trends.

Miscellaneous
Implements a curve of type %1
15 Views
0 Downloads
0 Favorites
(M) Moving Averages
//+------------------------------------------------------------------+
//|                                        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=1;
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_LINE);
   SetIndexShift(0,MA_Shift);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   if(MA_Period<2) MA_Period=1;
   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