MAChannel_Close_AD

Author: Scriptong
Indicators Used
Moving average indicator
Miscellaneous
It issuies visual alerts to the screenImplements a curve of type %1
0 Views
0 Downloads
0 Favorites
MAChannel_Close_AD
#property copyright "Scriptong"
#property link      "http://advancetools.net"
#property description "English: Horizontal channel, based on extremums between the crossing of the two Moving Averages.\nRussian: Ãîðèçîíòàëüíûé êàíàë, îïèðàþùèéñÿ íà ýêñòðåìóìû ìåæäó ïåðåñå÷åíèÿìè äâóõ Moving Average."
#property version "1.03"
#property strict

#property indicator_chart_window
#property indicator_buffers 5
#property indicator_color1 clrBlue
#property indicator_color2 clrRed
#property indicator_color3 clrBlue
#property indicator_color4 clrRed
#property indicator_color5 clrNONE

#property indicator_width1 2
#property indicator_width2 2

#property  indicator_style3 STYLE_DOT
#property  indicator_style4 STYLE_DOT

enum ENUM_YESNO
{
   NO,                                                                                             // No / Íåò
   YES                                                                                             // Yes / Äà
};

input    uint                 i_maFastPeriod             = 1;                                      // Period of fast MA / Ïåðèîä ðàñ÷åòà áûñòðîé ÌÀ
input    ENUM_MA_METHOD       i_maFastMethod             = MODE_SMA;                               // Method of fast MA / Ìåòîä ðàñ÷åòà áûñòðîé ÌÀ
input    ENUM_APPLIED_PRICE   i_maFastPrice              = PRICE_WEIGHTED;                         // Applied price of fast MA / Öåíà ðàñ÷åòà áûñòðîé ÌÀ
input    uint                 i_maSlowPeriod             = 21;                                     // Period of slow MA / Ïåðèîä ðàñ÷åòà ìåäëåííîé ÌÀ
input    ENUM_MA_METHOD       i_maSlowMethod             = MODE_EMA;                               // Method of slow MA / Ìåòîä ðàñ÷åòà ìåäëåííîé ÌÀ
input    ENUM_APPLIED_PRICE   i_maSlowPrice              = PRICE_WEIGHTED;                         // Applied price od slow MA / Öåíà ðàñ÷åòà ìåäëåííîé ÌÀ
input    ENUM_YESNO           i_isAlert                  = YES;                                    // Alert on trend change? / Ñèãíàë ïðè ñìåíå òðåíäà?
input    ENUM_YESNO           i_isPush                   = YES;                                    // Notification on trend change? / Óâåäîìëÿòü ïðè ñìåíå òðåíäà?
input    int                  i_indBarsCount             = 10000;                                  // Number of bars to display / Êîë-âî áàðîâ îòîáðàæåíèÿ

bool g_activate;

int      g_maxMAPeriod;                                                                            

double   g_point,                                                                                  
         g_delta;                                                                                  

enum ENUM_TREND_TYPE
{
   TREND_TYPE_NONE,
   TREND_TYPE_UPWARD,
   TREND_TYPE_DOWNWARD
};

enum ENUM_MESSAGE_CODE
{
   MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO,
   MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO,
   MESSAGE_CODE_TERMINAL_FATAL_ERROR1,
   MESSAGE_CODE_TREND_CHANGE_TO_UPWARD,
   MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD,
   MESSAGE_CODE_BIND_ERROR
};


// Ìàññèâû áóôåðîâ íäèêàòîðà
double g_highSolid[];                                                                              
double g_lowSolid[];                                                                               
double g_highDot[];                                                                                
double g_lowDot[];                                                                                 
double g_curTrend[];                                                                               

//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                                                                                                                                          |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnInit()
{
   g_activate = false;
   
   if (!TuningParameters())                        
      return INIT_FAILED;                          
       
   if (!BuffersBind())                             
      return INIT_FAILED;                          
                                                   
   g_activate = true;
   
   return INIT_SUCCEEDED;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Checking the correctness of values of tuning parameters                                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool TuningParameters()
{
   string name = WindowExpertName();

   if (i_maFastPeriod < 1)
   {
      Alert(name, GetStringByMessageCode(MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO));
      return false;
   } 
   
   if (i_maSlowPeriod < 1)
   {
      Alert(name, GetStringByMessageCode(MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO));
      return false;
   } 

   g_point = Point;
   g_delta = -g_point / 10;
   if (g_point == 0)
   {
      Alert(name, GetStringByMessageCode(MESSAGE_CODE_TERMINAL_FATAL_ERROR1));
      return false;
   } 
   
   g_maxMAPeriod = (int)MathMax(i_maFastPeriod, i_maSlowPeriod);
   
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Binding of array and the indicator buffers                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
bool BuffersBind()
{
   string name = WindowExpertName();
   
 //  IndicatorBuffers(5);

   // Ñâÿçûâàíèå áóôåðîâ èíäèêàòîðà ñ ìàññèâàìè
   if (!SetIndexBuffer(0, g_highSolid)                      ||
       !SetIndexBuffer(1, g_lowSolid)                       ||
       !SetIndexBuffer(2, g_highDot)                        ||
       !SetIndexBuffer(3, g_lowDot)                         ||
       !SetIndexBuffer(4, g_curTrend))
   {
      Alert(name, GetStringByMessageCode(MESSAGE_CODE_BIND_ERROR), GetLastError());
      return false;
   }

   // Çàäàíèå ãðàôè÷åñêîãî òèïà áóôåðîâ
   for (int i = 0; i < 4; i++)
      SetIndexStyle(i, DRAW_LINE);
      
   SetIndexStyle(4, DRAW_NONE);
      
   SetIndexLabel(0, "Resistance of downward trend");
   SetIndexLabel(1, "Support of upward trend");
   SetIndexLabel(2, "Breaking resistance");
   SetIndexLabel(3, "Breaking support");
   SetIndexLabel(4, "Trend Direction");
   
   return true;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Initialize of all indicator buffers                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void BuffersInitializeAll()
{
   ArrayInitialize(g_highSolid, EMPTY_VALUE);  
   ArrayInitialize(g_lowSolid, EMPTY_VALUE);  
   ArrayInitialize(g_highDot, EMPTY_VALUE);  
   ArrayInitialize(g_lowDot, EMPTY_VALUE);  
   ArrayInitialize(g_curTrend, TREND_TYPE_NONE);  
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Determination of bar index which needed to recalculate                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int GetRecalcIndex(int &total, const int ratesTotal, const int prevCalculated)
{
   total = ratesTotal - g_maxMAPeriod - 2;                                                                         
                                                   
   if (i_indBarsCount > 0 && i_indBarsCount < total)
      total = MathMin(i_indBarsCount, total);                      
                                                   
   if (prevCalculated < ratesTotal - 1)                     
   {       
      BuffersInitializeAll();
      return total;
   }
   
   return (MathMin(ratesTotal - prevCalculated, total));                            
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The minimal price at the downtrend interval                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double GetLowPrice(int barIndex)
{
   double lowPrice = Low[barIndex];
   for (int i = barIndex + 1; i < Bars; i++)
   {
      double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);  
      double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
      if (maFast > maSlow)
         return lowPrice;
         
      lowPrice = MathMin(lowPrice, Low[i]);
   }
   
   return lowPrice;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//|  The maximal price at the downtrend interval                                                                                                                                                      |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
double GetHighPrice(int barIndex)
{
   double highPrice = High[barIndex];
   for (int i = barIndex + 1; i < Bars; i++)
   {
      double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, i);  
      double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, i);
      if (maFast < maSlow)
         return highPrice;
         
      highPrice = MathMax(highPrice, High[i]);
   }
   
   return highPrice;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| The continuity of the indicator buffers values                                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ContinuityBuffers(int barIndex)
{
   if (g_curTrend[barIndex + 1] == TREND_TYPE_UPWARD)
   {
      g_lowDot[barIndex + 1] = EMPTY_VALUE;
      g_highSolid[barIndex + 1] = EMPTY_VALUE;
   }

   if (g_curTrend[barIndex + 1] == TREND_TYPE_DOWNWARD)
   {
      g_highDot[barIndex + 1] = EMPTY_VALUE;
      g_lowSolid[barIndex + 1] = EMPTY_VALUE;
   }

   g_highSolid[barIndex] = g_highSolid[barIndex + 1];
   g_lowSolid[barIndex] = g_lowSolid[barIndex + 1]; 
   g_highDot[barIndex] = g_highDot[barIndex + 1];
   g_lowDot[barIndex] = g_lowDot[barIndex + 1]; 
   g_curTrend[barIndex] = g_curTrend[barIndex + 1];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process the upward MA cross                                                                                                                                                                    |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessUpwardMACross(int barIndex)
{
   if (g_curTrend[barIndex + 1] == TREND_TYPE_DOWNWARD)
   {
      g_lowDot[barIndex] = GetLowPrice(barIndex);
      g_lowSolid[barIndex] = EMPTY_VALUE;
      if (g_lowDot[barIndex + 1] == EMPTY_VALUE)
         g_lowDot[barIndex + 1] = g_lowDot[barIndex];
         
      return;
   }

   g_lowSolid[barIndex] = GetLowPrice(barIndex);
   g_lowDot[barIndex] = EMPTY_VALUE;
   if (g_lowSolid[barIndex + 1] == EMPTY_VALUE)
      g_lowSolid[barIndex + 1] = g_lowSolid[barIndex];
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process the downward MA cross                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessDownwardMACross(int barIndex)
{
   if (g_curTrend[barIndex + 1] == TREND_TYPE_UPWARD)
   {
      g_highDot[barIndex] = GetHighPrice(barIndex);
      g_highSolid[barIndex] = EMPTY_VALUE;
      if (g_highDot[barIndex + 1] == EMPTY_VALUE)
         g_highDot[barIndex + 1] = g_highDot[barIndex];
      return;
   }

   g_highSolid[barIndex] = GetHighPrice(barIndex);
   g_highDot[barIndex] = EMPTY_VALUE;
   if (g_highSolid[barIndex + 1] == EMPTY_VALUE)
      g_highSolid[barIndex + 1] = g_highSolid[barIndex];
      
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Cast the timeframe to string value                                                                                                                                                                |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string CastTFToString(ENUM_TIMEFRAMES tf)
{

   switch(tf)
   {
      case PERIOD_H1: return "H1";
      case PERIOD_H4: return "H4";
      case PERIOD_D1: return "D1";
      case PERIOD_W1: return "W1";
      case PERIOD_MN1: return "MN1";
   }
   
   return "M" + IntegerToString((int)tf);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process of breakout of resistance level                                                                                                                                                        |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessResistanceBreak(int barIndex)
{
   g_curTrend[barIndex] = TREND_TYPE_UPWARD;

   g_highDot[barIndex + 1] = g_highSolid[barIndex + 1];
   g_highDot[barIndex] = (g_highSolid[barIndex] == EMPTY_VALUE)? g_highSolid[barIndex + 1] : g_highSolid[barIndex];
   g_highSolid[barIndex] = EMPTY_VALUE;
   
   if (g_lowDot[barIndex + 1] == EMPTY_VALUE)
      return;
      
   g_lowSolid[barIndex + 1] = g_lowDot[barIndex + 1];
   g_lowSolid[barIndex] = (g_lowDot[barIndex] == EMPTY_VALUE)? g_lowDot[barIndex + 1] : g_lowDot[barIndex];
   g_lowDot[barIndex] = EMPTY_VALUE;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| To process of breakout of the support level                                                                                                                                                       |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void ProcessSupportBreak(int barIndex)
{
   g_curTrend[barIndex] = TREND_TYPE_DOWNWARD;

   g_lowDot[barIndex + 1] = g_lowSolid[barIndex + 1];
   g_lowDot[barIndex] = (g_lowSolid[barIndex] == EMPTY_VALUE)? g_lowSolid[barIndex + 1] : g_lowSolid[barIndex];
   g_lowSolid[barIndex] = EMPTY_VALUE;

   if (g_highDot[barIndex + 1] == EMPTY_VALUE)
      return;

   g_highSolid[barIndex + 1] = g_highDot[barIndex + 1];
   g_highSolid[barIndex] = (g_highDot[barIndex] == EMPTY_VALUE)? g_highDot[barIndex + 1] : g_highDot[barIndex];
   g_highDot[barIndex] = EMPTY_VALUE;   
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation of the indicators values at the specified bar                                                                                                                                         |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalculateOneBarMA(int barIndex)
{
   double maFast = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, barIndex);  
   double maSlow = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, barIndex);
   double maFast2 = iMA(NULL, 0, i_maFastPeriod, 0, i_maFastMethod, i_maFastPrice, barIndex + 1);  
   double maSlow2 = iMA(NULL, 0, i_maSlowPeriod, 0, i_maSlowMethod, i_maSlowPrice, barIndex + 1);
   
   ContinuityBuffers(barIndex);

   if (maFast > maSlow && maFast2 < maSlow2)
      ProcessUpwardMACross(barIndex);

   if (maFast < maSlow && maFast2 > maSlow2)
      ProcessDownwardMACross(barIndex);   
   
   if (g_curTrend[barIndex] != TREND_TYPE_UPWARD && Close[barIndex] > g_highSolid[barIndex])
   {
      ProcessResistanceBreak(barIndex);
      return;
   }
   
   if (g_curTrend[barIndex] != TREND_TYPE_DOWNWARD && Close[barIndex] < g_lowSolid[barIndex] && g_lowSolid[barIndex] != EMPTY_VALUE)
      ProcessSupportBreak(barIndex);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Alert and notification on trend change                                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void SignalOnTrendChange(string text)
{
   static datetime lastSignal = 0;
   if (lastSignal >= Time[0])
      return;
      
   lastSignal = Time[0];
   
   if (i_isAlert)
      Alert(_Symbol, ", ", CastTFToString((ENUM_TIMEFRAMES)_Period), ": ", text);
      
   if (i_isPush)
      SendNotification(_Symbol + ", " + CastTFToString((ENUM_TIMEFRAMES)_Period) + ": " + text);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Calculation of indicators values                                                                                                                                                                  |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
void CalcIndicatorData(int limit, int total)
{
   for (int i = limit; i >= 0; i--)
      CalculateOneBarMA(i);
      
   if (g_curTrend[1] == TREND_TYPE_UPWARD && g_curTrend[2] != TREND_TYPE_UPWARD)
      SignalOnTrendChange(GetStringByMessageCode(MESSAGE_CODE_TREND_CHANGE_TO_UPWARD));
   
   if (g_curTrend[1] == TREND_TYPE_DOWNWARD && g_curTrend[2] != TREND_TYPE_DOWNWARD)
      SignalOnTrendChange(GetStringByMessageCode(MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD));
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Custom indicator iteration function                                                                                                                                                               |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
{
   if (!g_activate)                                                                                
      return rates_total;                                 
    
   int total;   
   int limit = GetRecalcIndex(total, rates_total, prev_calculated);                                

   CalcIndicatorData(limit, total);                                                                
   
   return rates_total;
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message and terminal language                                                                                                                                           |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetStringByMessageCode(ENUM_MESSAGE_CODE messageCode)
{
   string language = TerminalInfoString(TERMINAL_LANGUAGE);
   if (language == "Russian")
      return GetRussianMessage(messageCode);
      
   return GetEnglishMessage(messageCode);
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message for russian language                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetRussianMessage(ENUM_MESSAGE_CODE messageCode)
{
   switch (messageCode)
   {
      case MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO:            return ": ïåðèîä ðàñ÷åòà áûñòðîãî ñðåäíåãî äîëæåí áûòü áîëüøå íóëÿ. Èíäèêàòîð îòêëþ÷åí.";
      case MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO:            return ": ïåðèîä ðàñ÷åòà ìåäëåííîãî ñðåäíåãî äîëæåí áûòü áîëüøå íóëÿ. Èíäèêàòîð îòêëþ÷åí.";
      case MESSAGE_CODE_TERMINAL_FATAL_ERROR1:             return ": ôàòàëüíàÿ îøèáêà òåðìèíàëà - ïóíêò ðàâåí íóëþ. Èíäèêàòîð îòêëþ÷åí.";
      case MESSAGE_CODE_BIND_ERROR:                        return ": îøèáêà ñâÿçûâàíèÿ ìàññèâîâ ñ áóôåðàìè èíäèêàòîðà. Îøèáêà ¹";
      case MESSAGE_CODE_TREND_CHANGE_TO_UPWARD:            return ": ñìåíà òðåíäà. Íîâûé òðåíä - âîñõîäÿùèé.";
      case MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD:          return ": ñìåíà òðåíäà. Íîâûé òðåíä - íèñõîäÿùèé.";
   }
   
   return "";
}
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
//| Getting string by code of message for english language                                                                                                                                            |
//+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
string GetEnglishMessage(ENUM_MESSAGE_CODE messageCode)
{
   switch (messageCode)
   {
      case MESSAGE_CODE_MA_FAST_LESS_THAN_ZERO:            return ": calculation period of fast MA must be more than zero. The indicator is turned off.";
      case MESSAGE_CODE_MA_SLOW_LESS_THAN_ZERO:            return ": calculation period of slow MA must be more than zero. The indicator is turned off.";
      case MESSAGE_CODE_TERMINAL_FATAL_ERROR1:             return ": terminal fatal error - point equals to zero. The indicator is turned off.";
      case MESSAGE_CODE_BIND_ERROR:                        return ": error of binding of the arrays and the indicator buffers. Error N";
      case MESSAGE_CODE_TREND_CHANGE_TO_UPWARD:            return ": change of trend. The new trend - upward.";
      case MESSAGE_CODE_TREND_CHANGE_TO_DOWNWARD:          return ": change of trend. The new trend - downward.";
   }

   return "";
}

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---