Candle_MA
Download scriptThis script is designed as a versatile technical analysis tool for the MetaTrader 4 platform. Its primary purpose is to analyze specific components of price candles—such as their bodies, wicks (shadows), or relative proportions—and then smooth that data into a readable trend line.
Core Functionality
The logic operates in three distinct stages:
1. Data Selection (The Input) Instead of just looking at the closing price, this tool allows you to choose exactly what part of the "candle" you want to analyze. You can select from various options, including:
- Absolute Values: Raw measurements like the distance between the High and Low, the size of the candle body, or the length of the upper and lower wicks.
- Relative Proportions: Percentages that show how much of a candle is made up by the body versus the wicks (e.g., "What percentage of this candle's total range was actually traded in the body?").
- Standard Prices: Traditional values like the Open, Close, High, Low, or weighted averages (Median, Typical, etc.).
2. Modification and Scaling Once a data type is selected, the script applies several modifiers to customize the visual output:
- Volume Integration: You can choose to multiply the price data by the trading volume, which helps identify where significant "weight" is moving in the market.
- Manual Scaling: There are dedicated settings to scale the vertical height of both the raw candle data and the resulting averages, allowing you to fit the indicator perfectly onto your chart's proportions.
3. Smoothing and Level Analysis (The Output) After the specific price data is gathered, the script applies a Moving Average (MA). This transforms "choppy" individual candle data into a smooth line that reveals the underlying trend.
- Smoothing Methods: Users can choose between different standard smoothing types (Simple, Exponential, Smoothed, or Linear Weighted).
- Dynamic Levels: The script automatically generates six additional "Levels" based on the main average. These levels act as multipliers, creating a band or zone around the main moving average. This is often used to identify overextended price movements or potential zones of support and resistance.
Summary for the User
In simple terms, this tool takes any specific part of a price candle (like just the "wicks" or a "percentage of the body"), calculates a smoothed average of that data over a set period, and plots it along with several auxiliary levels. This allows traders to see the trend of specific market behaviors—rather than just the general price—with much greater clarity.
//+-----------------------------------------------------------------------------+
//| Candle_MA.mq4 |
//| Gregory A. Kakhiani |
//| gkakhiani@gmail.com |
//+-----------------------------------------------------------------------------+
//Candle Moving Average |
//Ïðîñòîé èíäèêàòîð äëÿ àíàëèçà ñðåäíèõ çíà÷åíèé ðàçëè÷íûõ ïàðàìåòðîâ ñâå÷åé. |
//+-----------------------------------------------------------------------------+
// ----= Îïèñàíèå ïàðàìåòðîâ =----- |
// |
//CandleType - Òèï îòîáðàæàåìûõ äàííûõ |
//---------------+--------------------------------------------------------------+
// Êîä | Îïðåäåëåíèå |
//---------------+--------------------------------------------------------------+
// Àáñîëþòíûå äàííûå
//---------------+--------------------------------------------------------------+
// 1 | High-Open |
// 2 | High-Close |
// 3 | Open-Low |
// 4 | Close-Low |
// 5 | |Open-Close| |
// 6 | High-Low |
// 7 | Top Shade - Âåðõíÿÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è |
// 8 | Open-Close - ñ ó÷¸òîì öâåòà ñâå÷è |
// 9 | Bottom Shade - Íèæíÿÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è |
// 10 | Îòíîøåíèå âñåé äëèíû ñâå÷è ê å¸ òåëó |
// 11 | Top Shade+Bottom Shade - Îáùàÿ äëèíà òåíåé áåç ó÷¸òà çíàêà |
// 12 | Top Shade-Bottom Shade - Îáùàÿ äëèíà òåíåé ñ ó÷¸òîì çíàêà |
//---------------+--------------------------------------------------------------+
// Îòíîñèòåëüíûå äàííûå |
//---------------+--------------------------------------------------------------+
// 13 | 100*(High-Open)/(High-Low) |
// 14 | 100*(High-Close)/(High-Low) |
// 15 | 100*(Open-Low)/(High-Low) |
// 16 | 100*(Close-Low)/(High-Low) |
// 17 | 100*(Open-Close)/(High-Low) |
// 18 | 100*(|Open-Close|)/(High-Low) |
// 19 | 100*(Top Shade)/(High-Low) |
// 20 | 100*(Bottom Shade)/(High-Low) |
// 21 | 100*(Top Shade+Bottom Shade)/(High-Low) |
// 22 | 100*(Top Shade-Bottom Shade)/(High-Low) |
//---------------+--------------------------------------------------------------+
// |
//MaPeriod - Ïåðèîä ñãëàæèâàíèÿ |
// |
// MaType - Ìåòîä ñãëàæèâàíèÿ - Èñïîëüçóþòñÿ ñòàíäàðòíûå êîíñòàíòû |
// |
// VolMult - Îïðåäåëÿåò ìàñøòàáèðîâàíèå ïî îáúåìàì |
// 0 - èãíîðèðîâàòü îáúåìû |
// 1 - óìíîæèòü íà îáúåì |
// |
// scale - Ìíîæèòåëü äëÿ ìàñøòàáèðîâàíèÿ ïî âåðòèêàëè äëÿ áàðîâ |
//avgscale - Ìíîæèòåëü äëÿ ìàñøòàáèðîâàíèÿ ïî âåðòèêàëè äëÿ ñðåäíåé |
// |
// k1...k6 - Êîýôôèöèåíòû äëÿ ðàñ÷¸òà óðîâíåé ñðåäíåé âåëè÷èíû |
//+-----------------------------------------------------------------------------+
#property copyright "Gregory A. Kakhiani"
#property link "gkakhiani@gmail.com"
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 Silver
#property indicator_color4 Silver
#property indicator_color5 Silver
#property indicator_color6 Silver
#property indicator_color7 Silver
//---- input parameters
extern int CandleType=6;
extern int MaPeriod=360;
extern int MaType=0;
extern int VolMult=0;
extern double scale=1.0;
extern double avgscale=1.0;
//Êîåôôèöèåíòû äëÿ ðàñ÷¸òà óðîâíåé ñêîëüçÿùåé ñðåäíåé
extern double k1=0.3333333333;
extern double k2=0.6666666666;
extern double k3=1.3333333333;
extern double k4=1.6666666666;
extern double k5=2.0000000000;
extern double k6=2.3333333333;
//---- buffers
double CandleBuffer[];
double MABuffer[];
//
double MABuffer1[];
double MABuffer2[];
double MABuffer3[];
double MABuffer4[];
double MABuffer5[];
double MABuffer6[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
IndicatorDigits(0); //Îêðóãëÿåì
//Óñòàíàâëèâàåì ñòèëè îòîáðàæåíèÿ
SetIndexStyle(0,DRAW_HISTOGRAM,0,7);
SetIndexBuffer(0,CandleBuffer);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,MABuffer);
SetIndexStyle(2,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(2,MABuffer1);
SetIndexStyle(3,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(3,MABuffer2);
SetIndexStyle(4,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(4,MABuffer3);
SetIndexStyle(5,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(5,MABuffer4);
SetIndexStyle(6,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(6,MABuffer5);
SetIndexStyle(7,DRAW_LINE,STYLE_DASHDOTDOT);
SetIndexBuffer(7,MABuffer6);
//Íàçâàíèÿ ãðàôèêîâ
SetIndexLabel(0,"Candle:") ;
SetIndexLabel(1,"Candle Average:") ;
SetIndexLabel(2,"Level K1:") ;
SetIndexLabel(3,"Level K2:") ;
SetIndexLabel(4,"Level K3:") ;
SetIndexLabel(5,"Level K4:") ;
SetIndexLabel(6,"Level K5:") ;
SetIndexLabel(7,"Level K6:") ;
//
if (CandleType>29)
CandleType=1;
//îôîðìëÿåì èíäèêàòîð
string Candletext="";
switch(CandleType)
{
case 1: {//High-Open
Candletext="High-Open";
}break;
case 2: {//High-Close
Candletext="High-Close";
}break;
case 3: {//Open-Low
Candletext="Open-Low";
}break;
case 4: {//Close-Low
Candletext="Close-Low";
}break;
case 5: {// |Open-Close|
Candletext="|Open-Close|";
}break;
case 6: {//High-Low
Candletext="High-Low";
}break;
case 7: {//Âåðõíàÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è
Candletext="Top Shade";
}break;
case 8: {//Open-Close - ñ ó÷¸òîì öâåòà ñâå÷è
Candletext="Open-Close";
}break;
case 9: {//Íèæíàÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è
Candletext="Bottom Shade";
}break;
case 10: {//Îòíîøåíèå âñåé äëèíû ñâå÷è ê å¸ òåëó
Candletext="Candle/Candle Body";
}break;
case 11: {//Top Shade+Bottom Shade - Îáùàÿ äëèíà òåíåé áåç ó÷¸òà çíàêà
Candletext="Top Shade+Bottom Shade";
}break;
case 12: {//Top Shade-Bottom Shade - Îáùàÿ äëèíà òåíåé ñ ó÷¸òîì çíàêà
Candletext="Top Shade-Bottom Shade";
}break;
case 13: {//100*(High-Open)/(High-Low)
Candletext="%(High-Open)";
}break;
case 14: {//100*(High-Close)/(High-Low)
Candletext="%(High-Close)";
}break;
case 15: {//100*(Open-Low)/(High-Low)
Candletext="%(Open-Low)";
}break;
case 16: {//100*(Close-Low)/(High-Low)
Candletext="%(Close-Low)";
}break;
case 17: {//100*(Open-Close)/(High-Low)
Candletext="%(Open-Close)";
}break;
case 18: {//100*(|Open-Close|)/(High-Low)
Candletext="%(|Open-Close|)";
}break;
case 19: {//100*(Top Shade)/(High-Low)
Candletext="%(Top Shade)";
}break;
case 20: {//100*(Bottom Shade)/(High-Low)
Candletext="%(Bottom Shade)";
}break;
case 21: {//100*(Top Shade+Bottom Shade)/(High-Low)
Candletext="%(Top Shade+Bottom Shade)";
}break;
case 22: {//100*(Top Shade-Bottom Shade)
Candletext="%(Top Shade-Bottom Shade)";
}break;
case 23: {//Close - Öåíà çàêðûòèÿ
Candletext="Close";
}break;
case 24: {//Öåíà îòêðûòèÿ
Candletext="Open";
}break;
case 25: {//Ìàêñèìàëüíàÿ öåíà
Candletext="High";
}break;
case 26: {//Ìèíèìàëüíàÿ öåíà
Candletext="Low";
}break;
case 27: {//Ñðåäíÿÿ öåíà
Candletext="Median";
}break;
case 28: {//Òèïè÷íàÿ öåíà
Candletext="Typical";
}break;
case 29: {//Âçâåøåííàÿ öåíà çàêðûòèÿ
Candletext="Weighted";
}break;
}
string MaTypeText="";
switch(MaType)
{
case 0:{
MaTypeText="MODE_SMA";
}break;
case 1:{
MaTypeText="MODE_EMA";
}break;
case 2:{
MaTypeText="MODE_SMMA";
}break;
case 3:{
MaTypeText="MODE_LWMA";
}break;
}
string VolMultText="";
if(VolMult!=0)
VolMultText="*Value";
else VolMultText="NONE";
IndicatorShortName("Candle MA("+Candletext+","+MaPeriod+","+MaTypeText+","+VolMultText+")");
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
int i;
int j;
int MaxBars=100000;
double K=scale/Point;
//----
for(i=0;i<=MaxBars;i++)
{
if(VolMult!=0)
CandleBuffer[i]=GetPrice(K, CandleType, i)*Volume[i];
else CandleBuffer[i]=GetPrice(K, CandleType, i);
}
for(i=0;i<=MaxBars;i++)
{
//Óñðåäíåíèå è ñãëàæèâàíèå
MABuffer[i]=iMAOnArray(CandleBuffer,0,MaPeriod,0,MaType,i)*avgscale;
//Çàïîëíåíèå âñïîìîãàòåëüíûõ áóôåðîâ
MABuffer1[i]=k1*MABuffer[i];
MABuffer2[i]=k2*MABuffer[i];
MABuffer3[i]=k3*MABuffer[i];
MABuffer4[i]=k4*MABuffer[i];
MABuffer5[i]=k5*MABuffer[i];
MABuffer6[i]=k6*MABuffer[i];
}
//----
return(0);
}
//+----------------------------------------------------------------------+
//|Ôóíêöèÿ â çàâèñèìîñòè îò PriceType-âîçâðàùàåò ëèáî ïàðàìåòðû ñâå÷è
//| PriceType 1 - 22
//|ëèáî îäíó èç âåëè÷èí èç ñïèñêà öåíîâûõ êîíñòàíò
//| PriceType 23 - 29
//+----------------------------------------------------------------------+
//|K - ìíîæèòåëü
//|PriceType - ïàðàìåòð îïðåäåëÿþùèé ñïîñîá ðàñ÷¸òà âîçâðàùàåìîé âåëè÷èíû
//|Index - èíäåêñ òåêóùåãî áàðà
//+----------------------------------------------------------------------+
double GetPrice(double K, int PriceType, int Index)
{
double Tmp=0.0;
double Tmp1=0.0;
double Tmp2=0.0;
switch(PriceType)
{
case 1: {//High-Open
Tmp=K*(High[Index]-Open[Index]);
}break;
case 2: {//High-Close
Tmp=K*(High[Index]-Close[Index]);
}break;
case 3: {//Open-Low
Tmp=K*(Open[Index]-Low[Index]);
}break;
case 4: {//Close-Low
Tmp=K*(Close[Index]-Low[Index]);
}break;
case 5: {// |Open-Close|
Tmp=K*MathAbs(Open[Index]-Close[Index]);
}break;
case 6: {//High-Low
Tmp=K*(High[Index]-Low[Index]);
}break;
case 7: {//Âåðõíàÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è
if(Open[Index]>Close[Index])
Tmp=K*(High[Index]-Open[Index]);
else Tmp=K*(High[Index]-Close[Index]);
}break;
case 8: {//Open-Close - ñ ó÷¸òîì öâåòà ñâå÷è
Tmp=K*MathAbs(Open[Index]-Close[Index]);
if((Open[Index]>Close[Index]))
Tmp=(-1)*Tmp;
}break;
case 9: {//Íèæíàÿ òåíü ñ ó÷¸òîì öâåòà ñâå÷è
if(Open[Index]<Close[Index])
Tmp=(-1)*K*(Open[Index]-Low[Index]);
else Tmp=(-1)*K*(Close[Index]-Low[Index]);
}break;
case 10: {//Îòíîøåíèå âñåé äëèíû ñâå÷è ê å¸ òåëó
Tmp1=MathAbs(Open[Index]-Close[Index]);
if(Tmp1!=0)
Tmp=(High[Index]-Low[Index])/Tmp1;
else Tmp=0;
}break;
case 11: {//|Top Shade+Bottom Shade| - Îáùàÿ äëèíà òåíåé áåç ó÷¸òà çíàêà
if(Open[Index]>Close[Index])
Tmp=K*(High[Index]-Open[Index]);
else Tmp=K*(High[Index]-Close[Index]);
if(Open[Index]<Close[Index])
Tmp1=K*(Open[Index]-Low[Index]);
else Tmp1=K*(Close[Index]-Low[Index]);
Tmp=Tmp+Tmp1;
}break;
case 12: {//Top Shade-Bottom Shade - Îáùàÿ äëèíà òåíåé ñ ó÷¸òîì çíàêà
if(Open[Index]>Close[Index])
Tmp=K*(High[Index]-Open[Index]);
else Tmp=K*(High[Index]-Close[Index]);
if(Open[Index]<Close[Index])
Tmp1=(-1)*K*(Open[Index]-Low[Index]);
else Tmp1=(-1)*K*(Close[Index]-Low[Index]);
Tmp=Tmp+Tmp1;
}break;
case 13: {//100*(High-Open)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else Tmp=100*(High[Index]-Open[Index])/Tmp1;
}break;
case 14: {//100*(High-Close)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else Tmp=100*(High[Index]-Close[Index])/Tmp1;
}break;
case 15: {//100*(Open-Low)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else Tmp=100*(Open[Index]-Low[Index])/Tmp1;
}break;
case 16: {//100*(Close-Low)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else Tmp=100*(Close[Index]-Low[Index])/Tmp1;
}break;
case 17: {//100*(Open-Close)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else {
Tmp=100*MathAbs(Open[Index]-Close[Index])/Tmp1;
if((Open[Index]>Close[Index]))
Tmp=(-1)*Tmp;
}
}break;
case 18: {//100*(|Open-Close|)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Tmp1==0)
Tmp=100;
else Tmp=100*MathAbs(Open[Index]-Close[Index])/Tmp1;
}break;
case 19: {//100*(Top Shade)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Open[Index]>Close[Index])
Tmp=100*(High[Index]-Open[Index]);
else Tmp=100*(High[Index]-Close[Index]);
if(Tmp1==0)
Tmp=100;
else Tmp=Tmp/Tmp1;
}break;
case 20: {//100*(Bottom Shade)/(High-Low)
Tmp1=High[Index]-Low[Index];
if(Open[Index]<Close[Index])
Tmp=(-1)*100*(Open[Index]-Low[Index]);
else Tmp=(-1)*100*(Close[Index]-Low[Index]);
if(Tmp1==0)
Tmp=100;
else Tmp=Tmp/Tmp1;
}break;
case 21: {//100*(Top Shade+Bottom Shade)/(High-Low)
Tmp2=High[Index]-Low[Index];
if(Open[Index]>Close[Index])
Tmp=100*(High[Index]-Open[Index]);
else Tmp=100*(High[Index]-Close[Index]);
if(Open[Index]<Close[Index])
Tmp1=100*(Open[Index]-Low[Index]);
else Tmp1=100*(Close[Index]-Low[Index]);
Tmp=Tmp+Tmp1;
if(Tmp2==0)
Tmp=100;
else Tmp=Tmp/Tmp2;
}break;
case 22: {//100*(Top Shade-Bottom Shade)/(High-Low)
Tmp2=High[Index]-Low[Index];
if(Open[Index]>Close[Index])
Tmp=100*(High[Index]-Open[Index]);
else Tmp=100*(High[Index]-Close[Index]);
if(Open[Index]<Close[Index])
Tmp1=100*(Open[Index]-Low[Index]);
else Tmp1=100*(Close[Index]-Low[Index]);
Tmp=Tmp-Tmp1;
if(Tmp2==0)
Tmp=100;
else Tmp=Tmp/Tmp2;
}break;
case 23: {//Close - Öåíà çàêðûòèÿ
Tmp=K*(Close[Index]);
}break;
case 24: {//Öåíà îòêðûòèÿ
Tmp=K*(Open[Index]);
}break;
case 25: {//Ìàêñèìàëüíàÿ öåíà
Tmp=K*(High[Index]);
}break;
case 26: {//Ìèíèìàëüíàÿ öåíà
Tmp=K*(Low[Index]);
}break;
case 27: {//Ñðåäíÿÿ öåíà
Tmp=K*(High[Index]+Low[Index])/2;
}break;
case 28: {//Òèïè÷íàÿ öåíà
Tmp=K*(High[Index]+Low[Index]+Close[Index])/3;
}break;
case 29: {//Âçâåøåííàÿ öåíà çàêðûòèÿ
Tmp=K*(High[Index]+Low[Index]+Close[Index]+Close[Index])/4;
}break;
}
return(Tmp);
}
Comments