//+------------------------------------------------------------------+
//|                                                     # Two MA.mq4 |
//|                                     Copyright 2013, Kolosov D.E. |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, Kolosov D.E."

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_width1 2
#property indicator_color2 Blue
#property indicator_width2 2

extern string  Использовать_обе_МА_?;
extern bool    использовать_?   = true;

extern string  Параметры_первой_МА;
extern int     период_первой_ма = 100;
extern int     сдвиг_первой_ма  = 0;
extern int     метод_первой_ма  = 0;

extern string  Параметры_второй_МА;
extern int     период_второй_ма = 200;
extern int     сдвиг_второй_ма  = 0;
extern int     метод_второй_ма  = 0;

extern color   цвет_метки       = Green;
extern int     размер_шрифта    = 10;

double ExtMapBuffer1[];
double ExtMapBuffer2[];

string первый_ма = "one";
string второй_ма = "two";

int ExtCountedBars=0;

int init()
{
   int    draw_begin, max;
   string short_name;

   SetIndexStyle(0, DRAW_LINE);
   SetIndexShift(0, сдвиг_первой_ма);
   SetIndexStyle(1, DRAW_LINE);
   SetIndexShift(1, сдвиг_второй_ма);
   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
   
   max = MathMax(период_первой_ма,период_второй_ма);
   if (max < 2) max = MathMin(период_первой_ма,период_второй_ма);
   draw_begin = max - 1;
   
   short_name = "";
   switch(метод_первой_ма)
   {
      case 1 : short_name = "EMA (";  draw_begin=0; break;
      case 2 : short_name = "SMMA ("; break;
      case 3 : short_name = "LWMA ("; break;
      default :
         метод_первой_ма = 0;
         short_name = "SMA (";
   }
   if (использовать_?) {
      switch(метод_второй_ма)
      {
         case 1 : short_name = short_name + период_первой_ма + ")  " + "EMA (";  draw_begin=0; break;
         case 2 : short_name = short_name + период_первой_ма + ")  " + "SMMA ("; break;
         case 3 : short_name = short_name + период_первой_ма + ")  " + "LWMA ("; break;
         default :
            метод_второй_ма = 0;
            short_name = short_name + период_первой_ма + ")  " + "SMA (";
      }
      short_name = short_name + период_второй_ма + ")";
   } else short_name = short_name + период_первой_ма + ")";
   
   IndicatorShortName(short_name);
   
   SetIndexDrawBegin(0,draw_begin);
   SetIndexDrawBegin(1,draw_begin);

   SetIndexBuffer(0, ExtMapBuffer1);
   SetIndexBuffer(1, ExtMapBuffer2);

   return(0);
}

int deinit()
{
   ObjectDelete(первый_ма);
   if (использовать_?) ObjectDelete(второй_ма);
   return (0);
}

int start()
{
   if (Bars <= MathMax(период_первой_ма,период_второй_ма)) return(0);
   ExtCountedBars = IndicatorCounted();

   if (ExtCountedBars < 0) return(-1);
   if (ExtCountedBars > 0) ExtCountedBars--;

   switch(метод_первой_ма)
   {
      case 0 : sma(период_первой_ма,1);  break;
      case 1 : ema(период_первой_ма,1);  break;
      case 2 : smma(период_первой_ма,1); break;
      case 3 : lwma(период_первой_ма,1);
   }
   
   if (использовать_?) {
      switch(метод_второй_ма)
      {
         case 0 : sma(период_второй_ма,2);  break;
         case 1 : ema(период_второй_ма,2);  break;
         case 2 : smma(период_второй_ма,2); break;
         case 3 : lwma(период_второй_ма,2);
      }
   }
   
   upd_object();

   return(0);
}
//+------------------------------------------------------------------+
//| Simple Moving Average                                            |
//+------------------------------------------------------------------+
void sma(int период_ма, int номер_буфера)
{
   double sum = 0;
   int    i, pos = Bars - ExtCountedBars - 1;

   if (pos < период_ма) pos = период_ма;
   for (i = 1; i < период_ма; i++, pos--)
      sum += Close[pos];

   while(pos >= 0)
   {
      sum += Close[pos];
      if (номер_буфера == 1) ExtMapBuffer1[pos] = sum/период_ма;
      if (номер_буфера == 2) ExtMapBuffer2[pos] = sum/период_ма;
	   sum -= Close[pos+период_ма-1];
 	   pos--;
   }

   if (ExtCountedBars < 1) {
      for (i = 1; i < период_ма; i++) {
         if (номер_буфера == 1) ExtMapBuffer1[Bars-i] = 0;
         if (номер_буфера == 2) ExtMapBuffer2[Bars-i] = 0;
      }
   }
}
//+------------------------------------------------------------------+
//| Exponential Moving Average                                       |
//+------------------------------------------------------------------+
void ema(int период_ма, int номер_буфера)
{
   double pr  = 2.0/(период_ма + 1);
   int    pos = Bars-2;
   if (ExtCountedBars > 2) pos = Bars - ExtCountedBars - 1;

   while(pos >= 0)
   {
      if (pos == Bars-2) {
         if (номер_буфера == 1) ExtMapBuffer1[pos+1] = Close[pos+1];
         if (номер_буфера == 2) ExtMapBuffer2[pos+1] = Close[pos+1];
      }
      if (номер_буфера == 1) ExtMapBuffer1[pos] = Close[pos]*pr + ExtMapBuffer1[pos+1]*(1-pr);
      if (номер_буфера == 2) ExtMapBuffer2[pos] = Close[pos]*pr + ExtMapBuffer2[pos+1]*(1-pr);
      pos--;
   }
}
//+------------------------------------------------------------------+
//| Smoothed Moving Average                                          |
//+------------------------------------------------------------------+
void smma(int период_ма, int номер_буфера)
{
   double sum = 0;
   int    i, k, pos = Bars - ExtCountedBars + 1;

   pos = Bars - период_ма;
   if (pos > Bars-ExtCountedBars) pos = Bars-ExtCountedBars;
   while (pos >= 0) {
      if (pos == Bars - период_ма) {
         for (i = 0, k = pos; i < период_ма; i++, k++) {
            sum += Close[k];
            if (номер_буфера == 1) ExtMapBuffer1[k] = 0;
            if (номер_буфера == 2) ExtMapBuffer2[k] = 0;
         }
      } else { 
         if (номер_буфера == 1) sum = ExtMapBuffer1[pos+1]*(период_ма-1)+Close[pos];
         if (номер_буфера == 2) sum = ExtMapBuffer2[pos+1]*(период_ма-1)+Close[pos];
      }
      if (номер_буфера == 1) ExtMapBuffer1[pos] = sum/период_ма;
      if (номер_буфера == 2) ExtMapBuffer2[pos] = sum/период_ма;

 	   pos--;
   }
}
//+------------------------------------------------------------------+
//| Linear Weighted Moving Average                                   |
//+------------------------------------------------------------------+
void lwma(int период_ма, int номер_буфера)
{
   double sum = 0.0, lsum = 0.0;
   double price;
   int    i, weight = 0, pos = Bars - ExtCountedBars - 1;

   if (pos < период_ма) pos = период_ма;
   for (i = 1; i <= период_ма; i++, pos--) {
      price  = Close[pos];
      sum   += price*i;
      lsum  += price;
      weight+= i;
   }

   pos++;
   i = pos + период_ма;
   while (pos >= 0) {
      if (номер_буфера == 1) ExtMapBuffer1[pos] = sum/weight;
      if (номер_буфера == 2) ExtMapBuffer2[pos] = sum/weight;
      if (pos == 0) break;
      pos--;
      i--;
      price = Close[pos];
      sum   = sum - lsum + price*период_ма;
      lsum -= Close[i];
      lsum += price;
     }

   if (ExtCountedBars < 1) {
      for (i = 1; i < период_ма; i++) {
         if (номер_буфера == 1) ExtMapBuffer1[Bars-i] = 0;
         if (номер_буфера == 2) ExtMapBuffer2[Bars-i] = 0;
      }
   }
}

void upd_object()
{
   string лэйбл_первой_ма = "            MA" + период_первой_ма;
   string лэйбл_второй_ма = "            MA" + период_второй_ма;
   
   int время_1 = Time[0] + Period()*60*сдвиг_первой_ма;
   int время_2 = Time[0] + Period()*60*сдвиг_второй_ма;   
   
   if (ObjectFind(первый_ма) == -1) {
      ObjectCreate( первый_ма, OBJ_TEXT, 0, 0, 0);
      ObjectSet(    первый_ма, OBJPROP_TIME1, время_1);
      ObjectSet(    первый_ма, OBJPROP_PRICE1, ExtMapBuffer1[0]);
      ObjectSetText(первый_ма, лэйбл_первой_ма, размер_шрифта, "Arial", цвет_метки);
   } else {
      ObjectSet(    первый_ма, OBJPROP_TIME1, время_1);
      ObjectSet(    первый_ма, OBJPROP_PRICE1, ExtMapBuffer1[0]);
      ObjectSetText(первый_ма, лэйбл_первой_ма, размер_шрифта, "Arial", цвет_метки);
   }
   
   if (использовать_?) {
   if (ObjectFind(второй_ма) == -1) {
      ObjectCreate( второй_ма, OBJ_TEXT, 0, 0, 0);
      ObjectSet(    второй_ма, OBJPROP_TIME1, время_2);
      ObjectSet(    второй_ма, OBJPROP_PRICE1, ExtMapBuffer2[0]);
      ObjectSetText(второй_ма, лэйбл_второй_ма, размер_шрифта, "Arial", цвет_метки);
   } else {
      ObjectSet(    второй_ма, OBJPROP_TIME1, время_2);
      ObjectSet(    второй_ма, OBJPROP_PRICE1, ExtMapBuffer2[0]);
      ObjectSetText(второй_ма, лэйбл_второй_ма, размер_шрифта, "Arial", цвет_метки);
   }}
}

