Moving Averages Lower Window
Download scriptThis script is a versatile technical analysis tool designed for the MetaTrader 4 platform. Its primary purpose is to calculate and display different types of "Moving Averages," which are essential tools used by traders to smooth out price fluctuations and identify the underlying trend of a financial market.
Instead of providing just one type of average, this script allows users to choose between four distinct mathematical methodologies, depending on how much weight they want to give to recent versus historical price data.
Key Functional Features:
1. Customizable Trend Smoothing The logic supports four different calculation methods, which can be toggled by the user:
- Simple Moving Average (SMA): The standard average where every price point in a specific timeframe carries equal weight. It is best for identifying general trends without over-reacting to minor price spikes.
- Exponential Moving Average (EMA): This method places a greater emphasis on the most recent price data. It reacts more quickly to sudden market changes compared to a simple average.
- Smoothed Moving Average (SMMA): A variation that reduces "noise" even further by calculating a moving average of previous moving averages, providing a much curvier and steadier trend line.
- Linear Weighted Moving Average (LWMA): This assigns weights to prices in a linear fashion, where the most recent price has the highest impact on the current value.
2. Dynamic Configuration The script is designed with user-friendly inputs that allow for quick adjustments without needing to modify any underlying code:
- Period Adjustment: Users can define the "lookback" period (how many past candles the average should consider). For example, a shorter period makes the indicator more sensitive to current moves, while a longer period tracks broader movements.
- Visual Shifting: The tool includes a "Shift" feature, which allows traders to move the resulting line forward or backward on the chart for visual alignment with other technical indicators.
3. Intelligent Calculation Logic The script handles complex data processing automatically behind the scenes:
- Data Integrity: It contains logic to ensure the calculation only begins once enough historical data is available (based on the selected period).
- Real-time Processing: The code is optimized to update dynamically as new price candles form, ensuring that the moving average line moves in sync with live market activity.
- Automated Labeling: It automatically updates its display name on the chart based on which mathematical method you have selected, making it easy for traders to keep track of multiple different averages simultaneously.
//+------------------------------------------------------------------+
//| 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_separate_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;
//---- 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=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