Moving Averages Advance
Download scriptThis 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.
//+------------------------------------------------------------------+
//| 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