//+------------------------------------------------------------------+
//|                                         Multi Moving Average.mq4 |
//|                      Copyright © 2009, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2009, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net" // http://www.mql4.com/ru/users/Alex5757000
//----
#property indicator_separate_window
#property indicator_minimum 1.0
#property indicator_maximum 4.0
#property indicator_buffers 8
#property indicator_color1  DarkGreen
#property indicator_color2  Red
#property indicator_color3  DarkGreen
#property indicator_color4  Red
#property indicator_color5  DarkGreen
#property indicator_color6  Red
#property indicator_color7  DarkGreen
#property indicator_color8  Red
//----
extern string MA1            = "Входные параметры первой МА";
//----
extern int    MA1.Period     = 13;                            // Период усреднения.
extern int    MA1.Mode       = MODE_EMA;                      // Метод вычисления скользящего среднего (Moving Average).
extern int    MA1.Price      = PRICE_MEDIAN;                  // Используемая цена для расчёта скользящего среднего (Moving Average).
//----
extern string MA2            = "Входные параметры второй МА";
//----
extern int    MA2.Period     = 34;
extern int    MA2.Mode       = MODE_EMA;
extern int    MA2.Price      = PRICE_MEDIAN;
//----
extern string MA3            = "Входные параметры третьей МА";
//----
extern int    MA3.Period     = 55;
extern int    MA3.Mode       = MODE_EMA;
extern int    MA3.Price      = PRICE_MEDIAN;
//----
extern string MA4            = "Входные параметры четвертой МА";
//----
extern int    MA4.Period     = 89;
extern int    MA4.Mode       = MODE_EMA;
extern int    MA4.Price      = PRICE_MEDIAN;
//----
extern string Visual         = "Параметры визуализации";
//----
extern string Wingdings      = "0 -квадрат, 1 - стрелка";
//----
extern int    Bar.Wingdings  = 0;
extern int    Bar.Width      = 0;
extern color  Bar.Color.Up   = Lime;
extern color  Bar.Color.Down = Red;
//----
extern int    P1.Position    = 4;
extern int    P2.Position    = 3;
extern int    P3.Position    = 2;
extern int    P4.Position    = 1;
//----
extern double Gap            = 0.6;
//----
extern string Set.Label      = "Установка текстовые метки";
//----
extern bool   Show.Label     = true;
//----
extern string V.Label        = "Вертикальный сдвиг текстовой метки";
//----
extern double V.Shift        = 0.5;
//----
extern string H.Label        = "Горизонтальный сдвиг текстовой метки";
//----
extern int    H.Shift        = 20;
//----
extern string UP.DN          = "Положение МА по отношению к цене: выше/ниже";
extern color  Text.Color.Up    = Lime;
extern color  Text.Color.Down  = Red;
//+------------------------------------------------------------------+
string Label ="", Short.Name;
//----
double MA1.UP.Buffer[];
double MA1.DN.Buffer[];
double MA2.UP.Buffer[];
double MA2.DN.Buffer[];
double MA3.UP.Buffer[];
double MA3.DN.Buffer[];
double MA4.UP.Buffer[];
double MA4.DN.Buffer[];
//----
double MA0.Buffer.0;
//----
double MA1.Buffer.1;
double MA1.Buffer.0;
double MA2.Buffer.1;
double MA2.Buffer.0;
double MA3.Buffer.1;
double MA3.Buffer.0;
double MA4.Buffer.1;
double MA4.Buffer.0;
//----
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   //----
   int Wingdings.UP, Wingdings.DOWN;
   //----
   if(Bar.Wingdings==0) { Wingdings.UP = 167; Wingdings.DOWN = 167; }
   if(Bar.Wingdings==1) { Wingdings.UP = 217; Wingdings.DOWN = 218; }
   if(Bar.Wingdings!=0 && Bar.Wingdings!=1) { Alert("Введите корректно значение переменной Bar.Wingdings ! (0-3)"); return; }
   //----
   SetIndexStyle (0, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Up);
   SetIndexArrow (0, Wingdings.UP);
   SetIndexBuffer(0, MA1.UP.Buffer);
   SetIndexEmptyValue(0, 0.0);
   SetIndexStyle (1, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Down);
   SetIndexArrow (1, Wingdings.DOWN);
   SetIndexBuffer(1, MA1.DN.Buffer);
   SetIndexEmptyValue(1, 0.0);
   SetIndexStyle (2, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Up);
   SetIndexArrow (2, Wingdings.UP);
   SetIndexBuffer(2, MA2.UP.Buffer);
   SetIndexEmptyValue(2, 0.0);
   SetIndexStyle (3, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Down);
   SetIndexArrow (3, Wingdings.DOWN);
   SetIndexBuffer(3, MA2.DN.Buffer);
   SetIndexEmptyValue(3, 0.0);
   SetIndexStyle (4, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Up);
   SetIndexArrow (4, Wingdings.UP);
   SetIndexBuffer(4, MA3.UP.Buffer);
   SetIndexEmptyValue(4, 0.0);
   SetIndexStyle (5, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Down);
   SetIndexArrow (5, Wingdings.DOWN);
   SetIndexBuffer(5, MA3.DN.Buffer);
   SetIndexEmptyValue(5, 0.0);
   SetIndexStyle (6, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Up);
   SetIndexArrow (6, Wingdings.UP);
   SetIndexBuffer(6, MA4.UP.Buffer);
   SetIndexEmptyValue(6, 0.0);
   SetIndexStyle (7, DRAW_ARROW, STYLE_SOLID, Bar.Width, Bar.Color.Down);
   SetIndexArrow (7, Wingdings.DOWN);
   SetIndexBuffer(7, MA4.DN.Buffer);
   SetIndexEmptyValue(7, 0.0);
   SetIndexLabel(0, "1.Buffer.UP");
   SetIndexLabel(1, "1.Buffer.DN");
   SetIndexLabel(2, "2.Buffer.UP");
   SetIndexLabel(3, "2.Buffer.DN");
   SetIndexLabel(4, "3.Buffer.UP");
   SetIndexLabel(5, "3.Buffer.DN");
   SetIndexLabel(6, "4.Buffer.UP");
   SetIndexLabel(7, "4.Buffer.DN");
   IndicatorDigits(0);
   Short.Name = "Alex5757000 - MTF Moving Average";
   IndicatorShortName(Short.Name);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
   //----
   int Counted.Bars = IndicatorCounted(), i;
   if(Counted.Bars<0) return(-1);
   if(Counted.Bars>0) Counted.Bars--;
   int Limit = Bars - Counted.Bars;
   color Text.Color.1, Text.Color.2, Text.Color.3, Text.Color.4;
   //----
   for(i=Limit; i>=0; i--)
     {
      MA0.Buffer.0 = iMA(NULL, 0, 1, 0, MODE_SMA, PRICE_MEDIAN, i);
      //----
      MA1.Buffer.0 = iMA(NULL, 0, MA1.Period, 0, MA1.Mode, MA1.Price, i);
      MA1.Buffer.1 = iMA(NULL, 0, MA1.Period, 0, MA1.Mode, MA1.Price, i+1);
      MA2.Buffer.0 = iMA(NULL, 0, MA2.Period, 0, MA2.Mode, MA2.Price, i);
      MA2.Buffer.1 = iMA(NULL, 0, MA2.Period, 0, MA2.Mode, MA2.Price, i+1);
      MA3.Buffer.0 = iMA(NULL, 0, MA3.Period, 0, MA3.Mode, MA3.Price, i);
      MA3.Buffer.1 = iMA(NULL, 0, MA3.Period, 0, MA3.Mode, MA3.Price, i+1);
      MA4.Buffer.0 = iMA(NULL, 0, MA4.Period, 0, MA4.Mode, MA4.Price, i);
      MA4.Buffer.1 = iMA(NULL, 0, MA4.Period, 0, MA4.Mode, MA4.Price, i+1);
      
      MA1.UP.Buffer[i] = EMPTY_VALUE;
      MA1.DN.Buffer[i] = EMPTY_VALUE;
      
      if(MA1.Buffer.0 < MA1.Buffer.1) MA1.DN.Buffer[i] = Gap * P1.Position + 1.0;
      else                            MA1.UP.Buffer[i] = Gap * P1.Position + 1.0;
      if(MA1.Buffer.0 < MA0.Buffer.0) Text.Color.1 = Text.Color.Up;
      else                            Text.Color.1 = Text.Color.Down;
      //----
      MA2.UP.Buffer[i] = EMPTY_VALUE;
      MA2.DN.Buffer[i] = EMPTY_VALUE;
      
      if(MA2.Buffer.0 < MA2.Buffer.1) MA2.DN.Buffer[i] = Gap * P2.Position + 1.0;
      else                            MA2.UP.Buffer[i] = Gap * P2.Position + 1.0;
      if(MA2.Buffer.0 < MA0.Buffer.0) Text.Color.2 = Text.Color.Up;
      else                            Text.Color.2 = Text.Color.Down;
      //----
      MA3.UP.Buffer[i] = EMPTY_VALUE;
      MA3.DN.Buffer[i] = EMPTY_VALUE;
      
      if(MA3.Buffer.0 < MA3.Buffer.1) MA3.DN.Buffer[i] = Gap * P3.Position + 1.0;
      else                            MA3.UP.Buffer[i] = Gap * P3.Position + 1.0;
      if(MA3.Buffer.0 < MA0.Buffer.0) Text.Color.3 = Text.Color.Up;
      else                            Text.Color.3 = Text.Color.Down;
      //----
      MA4.UP.Buffer[i] = EMPTY_VALUE;
      MA4.DN.Buffer[i] = EMPTY_VALUE;
      
      if(MA4.Buffer.0 < MA4.Buffer.1) MA4.DN.Buffer[i] = Gap * P4.Position + 1.0;
      else                            MA4.UP.Buffer[i] = Gap * P4.Position + 1.0;
      if(MA4.Buffer.0 < MA0.Buffer.0) Text.Color.4 = Text.Color.Up;
      else                            Text.Color.4 = Text.Color.Down;
      //----
      //----
      LabelSet(Text.Color.1, Text.Color.2, Text.Color.3, Text.Color.4);
      //----
     }   
//----
   return(0);
  }
//+------------------------------------------------------------------+
int LabelSet(color Text.Color.1, color Text.Color.2, color Text.Color.3, color Text.Color.4)
  {
   //----
   int i;
   double Price, ID =Time[0] - Time[1];
   string Name, Text;
   color Text.Color;
   //----
   if(Show.Label==TRUE)
     {
      for(i=1; i<=4; i++)
        {
         switch(i)
           {
            case 1: Text       = Time.Frame() + " " + Mode(MA1.Mode) + " " + "(" + MA1.Period + ")";
                    Price      = Gap * P1.Position + 1.0 + V.Shift;
                    Text.Color = Text.Color.1;
                    break;
            case 2: Text       = Time.Frame() + " " + Mode(MA2.Mode) + " " + "(" + MA2.Period + ")";
                    Price      = Gap * P2.Position + 1.0 + V.Shift;
                    Text.Color = Text.Color.2;
                    break;
            case 3: Text       = Time.Frame() + " " + Mode(MA3.Mode) + " " + "(" + MA3.Period + ")";
                    Price      = Gap * P3.Position + 1.0 + V.Shift;
                    Text.Color = Text.Color.3;
                    break;
            case 4: Text       = Time.Frame() + " " + Mode(MA4.Mode) + " " + "(" + MA4.Period + ")";
                    Price      = Gap * P4.Position + 1.0 + V.Shift;
                    Text.Color = Text.Color.4;
           }
           
         Name = WindowFind(Short.Name);
         ObjectDelete (Name + i);
         ObjectCreate (Name + i, OBJ_TEXT, WindowFind(Short.Name), iTime(NULL, 0, 0) + ID * H.Shift, Price);
         ObjectSetText(Name + i, Text, 8, "Arial Bold", Text.Color);
        }
     }
   return(0);
  }       
//----
string Time.Frame()
  {
   if (Period() == PERIOD_M1 ) return ("M1");
   if (Period() == PERIOD_M5 ) return ("M5");
   if (Period() == PERIOD_M15) return ("M15");
   if (Period() == PERIOD_M30) return ("M30");
   if (Period() == PERIOD_H1 ) return ("H1");
   if (Period() == PERIOD_H4 ) return ("H4");
   if (Period() == PERIOD_D1 ) return ("D1");
   if (Period() == PERIOD_W1 ) return ("W1");
   if (Period() == PERIOD_MN1) return ("MN");
  }
//----
string Mode(int MA_Mode)
  {
   switch(MA_Mode)
     {
      case 0 : return("SMA");
               break;
     
      case 1 : return("EMA");
               break;
               
      case 2 : return("SSMA");
               break;
               
      case 3 : return("LWMA");
     }
  }
//+------------------------------------------------------------------+