//+------------------------------------------------------------------+
//|                                                     AlertSMA.mq4 |
//|                                                 Marcin Konieczny |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Marcin Konieczny"
#property link      ""

#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Red
#property indicator_width1 3
#property indicator_color2 Lime
#property indicator_width2 2
#property indicator_color3 Red
#property indicator_width3 2

extern int       MA_Period=10;
extern int       MA_Shift=0;
extern int       MA_Type=0;
extern string    types="0-SMA,1-EMA,2-SMMA,3-LWMA";
extern bool      Mail=true;
extern bool      Alert_Window=false;

double ma[];
double up[], down[];
datetime lastAlert;
string name;

int init()
{
   lastAlert = 0;
   if(MA_Shift < 0) MA_Shift = 0;
   if(MA_Period <= 0) MA_Period = 10;
   if(MA_Type < 0 || MA_Type > 3) MA_Type = 0;
   
   switch(MA_Type){
      case 0: name = "SMA("; break;
      case 1: name = "EMA("; break;
      case 2: name = "SMMA("; break;
      case 3: name = "LWMA("; break;
   }
   //название SMA +10 
   name = name + MA_Period + "," + MA_Shift + ")";
   
   //Буфер для первого значения ma,может быть от 0 до 7
   SetIndexBuffer(0,ma);
   // Отризовака нулевой линии ma, может быть от 0 до 7с десятого  бара
   SetIndexDrawBegin(0,MA_Period+MA_Shift);
   //Отображении имени нулевой линии ma,может быть от 0 до 7 
   SetIndexLabel(0, name);
   
   //Буфер для второго значения вверх,может быть от 0 до 7
   SetIndexBuffer(1,up);
   SetIndexDrawBegin(1,MA_Period+MA_Shift);
  //Выводит стрелку вверх для второй линии
   SetIndexLabel(1, "up");
   // устанавливаем тип стрелку вверх, без ширины и цвета
   SetIndexStyle(1,DRAW_ARROW);
   // назначаем значок для второй линии 
   //Код символа из шрифта Wingdings=233,стрелка вверх
   SetIndexArrow(1,233);
   
   //Буфер 3 для стрелки вниз
   SetIndexBuffer(2,down);
   SetIndexDrawBegin(2,MA_Period+MA_Shift);
   SetIndexLabel(2, "down");
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,234);
   
   return(0);
}

int start(){
//возвращает количество баров,
// не измененных после последнего вызова индикатора.
//То есть Реально посчитанных минус один
//самый последний бар не считается посчитанным, 
//и в большинстве случаев необходимо пересчитывать только его
   int counted = IndicatorCounted();
   int start;
   int factor = 5;
   //Если Менше нули Выход с функции старт
   if(counted < 0) return(0);
   //Если равно нули,То к-во баров на текущ графике уменшаем на единицу
   if(counted == 0) start = Bars - 1;
   //Если больше нуля ,то к-во баров на текущ графике отнимаем посчитанные
   if(counted > 0) start = Bars - counted;
   
   for(int i=start; i>=0; i--){
  // Заносим в масив ма    Расчет скользящего среднего
  //на текущей валютной паре с текущим таймфреймом
  // спериодом 10
  //со сдвигом индикатора на 0 относительно ценового графика
  // с типом SMA
  // по цене закрытия
  // со сдвигом і ,может быть от 0 до 7
      ma[i] = iMA(Symbol(),0,MA_Period,MA_Shift,MA_Type,PRICE_CLOSE,i);
  //  Свеча по ценам закрытия  должна явно закрыться ниже скользящей средней 10 sma.  
      if(i > 0 && Close[i] > ma[i] && Close[i+1] <= ma[i+1])
     // в масив вверх тость на продажу заносим значение
     // от мин цены свечи отнимаем 5 размеров пункта
         up[i] = Low[i] - factor * Point;
 
 //  Свеча по ценам закрытия  должна явно закрыться Выше скользящей средней 10 sma.          
      if(i > 0 && Close[i] < ma[i] && Close[i+1] >= ma[i+1])
        // в масив на покупку тоесть вниз заносим значения
        //максимум свечи +5 размеров пункта
         down[i] = High[i] + factor * Point;     
   }
   // До тех пор пока последнее время не сравняеться с 0,тозаносим внего текущее время
   if(lastAlert == 0) lastAlert = Time[0];
   
   if(up[1] != EMPTY_VALUE && Time[0] > lastAlert){
      SendAlert(true);
   }
   
   if(down[1] != EMPTY_VALUE && Time[0] > lastAlert){
      SendAlert(false);
   }
   
   lastAlert = Time[0];
   return(0);
}

void SendAlert(bool up){
   string txt = Symbol() + " " + TFtoString(Period()) + ": " + name + " cross ";
   
   if(up)
      txt = txt + "UP";
   else
      txt = txt + "DOWN";

   if(Mail)
      SendMail(txt, txt);
   if(Alert_Window)
      Alert(txt);
}

string TFtoString(int period){
    string tf = "";

    switch(period){
      case 1: tf = "M1"; break;
      case 5: tf = "M5"; break;
      case 15: tf = "M15"; break;
      case 30: tf = "M30"; break;
      case 60: tf = "H1"; break;
      case 240: tf = "H4"; break;
      case 1440: tf = "D1"; break;
      case 10080: tf = "W1"; break;
      case 43200: tf = "MN1"; break;
      default: tf = "";
    }

    return(tf);
}

