MA_Channal3
Download scriptThis script functions as a technical analysis tool designed to create a visual "channel" or corridor on a price chart. Its primary purpose is to help traders identify the general trend of a financial instrument by calculating a central average price and then projecting a specific boundary around that average.
Core Logic and Functionality
1. Central Average Calculation (The Baseline) The script begins by determining a central path for the price action. It offers four different mathematical methods to calculate this moving average, allowing users to choose how "smooth" or "reactive" they want the baseline to be:
- Simple Moving Average (SMA): A basic average where every price point in the lookback period carries equal weight.
- Exponential Moving Average (EMA): A weighted average that gives more importance to recent price changes, making it more responsive to new data.
- Smoothed Moving Average (SMMA): A calculation designed to reduce "noise" and provide a more stable, fluid trend line.
- Linear Weighted Moving Average (LWMA): A method that applies a linear weight to price points, prioritizing the most recent data significantly more than older data.
2. Channel Construction (The Envelope) Once the central moving average is established, the script creates a "channel" or "envelope" around it. Instead of just showing one line, it calculates two additional lines:
- Upper Boundary: A price line positioned above the central average based on a user-defined width.
- Lower Boundary: A price line positioned below the central average based on that same width.
How It Works Together
Think of the script as creating a "road" for the price to travel along. The moving average acts as the center lane, while the upper and lower boundaries act as the guardrails.
By looking at where the current price sits in relation to these three lines, a user can visually assess whether the market is currently trading in the middle of its normal range, breaking out toward the "ceiling" (upper boundary), or dropping toward the "floor" (lower boundary).
User Customization Options
The logic allows for several adjustable parameters to tailor the visual experience:
- Channel Width: Determines how wide the distance between the top and bottom boundaries will be.
- MA Period: Sets how many previous price bars are used to calculate the averages (longer periods result in smoother lines, shorter periods are more reactive).
- MA Method: Allows the user to toggle between the four different mathematical styles mentioned above.
- Shift: Adjusts the visual placement of the lines forward or backward on the chart for alignment purposes.
//+------------------------------------------------------------------+
//| MA_Channal3.mq4 |
//| Moving Average: Copyright © 2004, MetaQuotes Software Corp. |
//| http://www.metaquotes.net/ |
//| MA_Channal: Copyright © 2005, Nikolay Kositsin |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2004, MetaQuotes Software Corp."
#property link "http://www.metaquotes.net/"
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Lime
#property indicator_color2 Blue
#property indicator_color3 Red
//---- indicator parameters
extern double Channal_width=40;
extern int MA_Period=60;
extern int MA_Shift =0;
extern int MA_Method =0;
//---- indicator buffers
//---- buffers
double UperBuffer [];
double ExtMapBuffer[];
double DownBuffer [];
//----
int ExtCountedBars=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
int draw_begin;
string short_name;
//---- drawing settings
SetIndexStyle(0,DRAW_LINE);
SetIndexStyle(1,DRAW_LINE);
SetIndexStyle(2,DRAW_LINE);
//---- IndexShift
SetIndexShift(0,MA_Shift);
SetIndexShift(1,MA_Shift);
SetIndexShift(2,MA_Shift);
//----
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
//----
SetIndexLabel (0, "Channal+");
SetIndexLabel (2, "Channal-");
if(MA_Period<2) MA_Period=13;
draw_begin=MA_Period-1;
//---- indicator short name
switch(MA_Method)
{
case 1 : short_name="EMAChannal("; draw_begin=0; break;
case 2 : short_name="SMMAChannal("; break;
case 3 : short_name="LWMAChannal("; break;
default :
MA_Method=0;
short_name="SMAChannal(";
}
IndicatorShortName(short_name+MA_Period+")");
//---- SetIndexDrawBegin
SetIndexDrawBegin(0,draw_begin);
SetIndexDrawBegin(2,draw_begin);
//---- indicator buffers
IndicatorBuffers(3);
//---- indicator buffers mapping
SetIndexBuffer (0, UperBuffer);
SetIndexBuffer (1, ExtMapBuffer);
SetIndexBuffer (2, DownBuffer);
//---- initializaton done
return(0);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int start()
{
if(Bars<=MA_Period) return(0);
ExtCountedBars=IndicatorCounted();
//---- check for possible errors
if (ExtCountedBars<0) return(-1);
//---- last couExtCountedBarnted 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();
}
//+------------------------------------------------------------------+
//|++++++++++++++++++++++++Envelope code++++++++++++++++++++++++++++++
// Input indicator buffer: ExtMapBufferBuffer. |
//| Output indicator buffers: UperBuffer, DownBuffer. |
//+------------------------------------------------------------------+ |
int r; r=Bars-ExtCountedBars-1;
while(r>=0)
{
UperBuffer[r] = ExtMapBuffer[r] + Channal_width*Point/2;
DownBuffer[r] = ExtMapBuffer[r] - Channal_width*Point/2;
r--;
}
//+------------------------------------------------------------------+
// ++++++++++++++++++Envelope Indicator code done+++++++++++++++++++++
//+------------------------------------------------------------------+
return(0);
}
//+------------------------------------------------------------------+
//| Simple Moving Average |
//+------------------------------------------------------------------+
void sma()
{
SetIndexLabel (1, "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()
{
SetIndexLabel (1, "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()
{
SetIndexLabel (1, "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()
{
SetIndexLabel (1, "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