//+------------------------------------------------------------------+
//|                                              VilkaChuwashowa.mq4 |
//|                                                           Rodion |
//|                                                                  |eurusd m15
//+------------------------------------------------------------------+
#property copyright "Rodion"
#property link      ""
#property indicator_buffers 3

extern bool       Alarmset=true;
extern double     Lot=0.1;
extern int        StopLoss = 0;
extern int        TakeProfit = 0;
int               MG;

extern string Ind_Coment1= "--- Внешние параметры индикатора ---";
extern bool  ShowFractals     =  true;         // Вкл/выкл значков фракталов
extern bool  OnAlert          = false;         // Вкл/выкл сигнала
extern bool  OnPrint          = false;         // Вкл/выкл вывод сигнала в журнале эксперта
extern int   nVilka.Upper     =     1;         // Количество выводимых восходящих "вилок"
extern int   nVilka.Lower     =     1;         // Количество выводимых нисходящих "вилок"
extern color Color.LineUpper  =   Red;         // Цвет восходящих "вилок"
extern color Color.LineLower  =  Blue;         // Цвет нисходящих "вилок"
extern int   Width.LineUpper  =     2;         // Ширина восходящих "вилок"
extern int   Width.LineLower  =     2;         // Ширина нисходящих "вилок"
extern string Ind_Coment2= "--- Параметры отображения ордеров ---";
extern bool  ShowOrders       =  true;         // Вкл/выкл отображения ордеров
extern bool  OnAlert.Orders   =  true;         // Вкл/выкл сигнала
extern color Color.OrderBuy   =  Blue;         // Цвет ордеров на покупку
extern color Color.OrderSell  = Green;         // Цвет ордеров на продажу
extern int   Width.OrderBuy   =     2;         // Ширина ордеров на покупку
extern int   Width.OrderSell  =     2;         // Ширина ордеров на продажу
extern color Color.SLBuy      =   Red;         // Цвет стоплосса на покупку
extern color Color.SLSell     =   Red;         // Цвет стоплосса на продажу
extern int   Orders.FontSize  =    12;         // Размер шрифта ордеров
extern string Ind_Coment3= "--- Параметры E-mail сообщений ---";
extern bool  SendEnter        = false;         // сигналы Buy, Sell
extern bool  SendLoss         = false;         // сигналы StopLoss
//+---------------------------------------------------------------------------+
// глобальные переменные
int          nLine.Upper      =     0,         // Количество трендовых линий, направленных вверх
             nLine.Lower      =     0,         // Количество трендовых линий, направленных вниз
             nBars            =     0;         //
datetime     mLineUpper.DateTime[][2];         // массив с параметрами восходящих "вилок"
         //  mLineUpper.DateTime[i][0]         // Время первой координаты
         //  mLineUpper.DateTime[i][1]         // Время второй координаты
double       mLineUpper.Price[][2];            // массив с параметрами восходящих "вилок"
         //  mLineUpper.Price[i][0]            // Цена первой координаты
         //  mLineUpper.Price[i][1]            // Цена второй координаты
datetime     mLineLower.DateTime[][2];         // массив с параметрами нисходящих "вилок"
         //  mLineLower.DateTime[i][0]         // Время первой координаты
         //  mLineLower.DateTime[i][1]         // Время второй координаты
double       mLineLower.Price[][2];            // массив с параметрами нисходящих "вилок"
         //  mLineLower.Price[i][0]            // Цена первой координаты
         //  mLineLower.Price[i][1]            // Цена второй координаты
string       mOrders[2][5];                    // массив с параметрами "открытых" позиций
         //  mOrders[0][0]                     // Buy - 0-нет ордера, 10-есть ордер
         //  mOrders[1][0]                     // Sell- 0-нет ордера, 20-есть ордер
         //  mOrders[i][1]                     // Дата и время "открытия" ордера
         //  mOrders[i][2]                     // Цена ордера ордера
         //  mOrders[i][3]                     // Стоплосс ордера ордера
         //  mOrders[i][4]                     // 0-стоплосс НЕ сработал, 1-стоплосс сработал
string       NameLine.Buy="";                  // имя сигнальной трендовой линии для покупки
string       NameLine.Sell="";                 // имя сигнальной трендовой линии для продажи
//----- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];

//+---------------------------------------------------------------------------+
int init()
  {
  MG=StringGetChar(Symbol(),0)+StringGetChar(Symbol(),3)+231;
      
  int Qnt=ObjectsTotal();
  // ----- Indicators Properties
  SetIndexStyle(0,DRAW_ARROW);
  SetIndexArrow(0,217);
  SetIndexBuffer(0,ExtMapBuffer1);
  SetIndexEmptyValue(0,0.0);
  SetIndexStyle(1,DRAW_ARROW);
  SetIndexArrow(1,218);
  SetIndexBuffer(1,ExtMapBuffer2);
  SetIndexEmptyValue(1,0.0);
  // ----- Name for DataWindow and indicator subwindow label
  IndicatorShortName("Fractals");
  SetIndexLabel(0,"FractalsUp");
  SetIndexLabel(1,"FractalsDown");
  // ----- устанавливаем количество элементов в массивах трендовых линий
  ArrayResize(mLineUpper.DateTime,nVilka.Upper*2); ArrayResize(mLineUpper.Price,nVilka.Upper*2);
  ArrayResize(mLineLower.DateTime,nVilka.Lower*2); ArrayResize(mLineLower.Price,nVilka.Lower*2);
  // ----- определяемся с именами сигнальных трендовых линий
  if (nVilka.Lower==1) NameLine.Buy ="Line.Lower1";
  if (nVilka.Lower>1)  NameLine.Buy ="Line.Lower"+DoubleToStr(nVilka.Lower*2-1,0);
  if (nVilka.Upper==1) NameLine.Sell="Line.Upper1";
  if (nVilka.Upper>1)  NameLine.Sell="Line.Upper"+DoubleToStr(nVilka.Upper*2-1,0);
  
  return;
}


//+---------------------------------------------------------------------------+
void deinit()   {     // Custom indicator deinitialization function
int    Qnt=ObjectsTotal();
  // ----- Удаляем трендовые линии
  for (int i=0; i<Qnt; i++)   {  // Цикл по объектам
    if(StringFind(ObjectName(i),"Line.Upper",0)>=0) {
      ObjectDelete(ObjectName(i));     // направленные вверх
      i--; continue;
    }
    if(StringFind(ObjectName(i),"Line.Lower",0)>=0) {
      ObjectDelete(ObjectName(i));     // направленные вниз
      i--; continue;
    }
    if(i>=ObjectsTotal()) break;
  }
  DeleteOrders(10); DeleteOrders(20);
 return;
}
///+------------------------------------------------------------------+

void start() {        // Custom indicator iteration function

double s=iStochastic(NULL,0,14,3,3,MODE_EMA,0,MODE_MAIN,1);

int    counted_bars=IndicatorCounted();
int    limit;
int    Spred=MarketInfo(Symbol(),MODE_SPREAD);
  // ----- Проверка внешних параметров индикатора
  if(!CheckParameters()) return;
  // ----- новый бар не появился
  if(!isNewBar()) return;
  // ----- Последний посчитанный бар будет пересчитан
  if (counted_bars>0) counted_bars--;
  limit=Bars-counted_bars;
  // ----- Основной цикл
  //for (int i=limit; i>2; i--)   {
  for (int i=limit; i>=0; i--)   
  {
    if(ShowFractals)  
    {                    // отображаем вракталы на графике
      ExtMapBuffer1[i]=iFractals(NULL,0,MODE_UPPER,i)+Spred*Point;
      ExtMapBuffer2[i]=iFractals(NULL,0,MODE_LOWER,i)-Spred*Point;
    }
    //---- Блок Upper-фракталов (нисходящие "вилки")
    if (iFractals(NULL,0,MODE_UPPER,i)!=0)  {
      if(LowerVilka(i)) {
        if(i==0)  {
          if(OnAlert) Alert(Symbol(),Period()," Нисходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
          if(OnPrint) Print(Symbol(),Period()," Нисходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
        }
      }
    }
    //---- Блок Lower-фракталов (восходящие "вилки")
    if (iFractals(NULL,0,MODE_LOWER,i)!=0)  {
      if(UpperVilka(i)) {
        if(i==0)  {
          if(OnAlert) Alert(Symbol(),Period()," Восходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
          if(OnPrint) Print(Symbol(),Period()," Восходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
        }
      }
    }
    //----- пересечение нисходящей "вилки" - сигнал на покупку
    if((StrToDouble(mOrders[0][0])==0 || (StrToDouble(mOrders[0][0])==10 && StrToDouble(mOrders[0][4])==1)) && 
       (Close[i+1]>ObjectGetValueByShift(NameLine.Buy,i+1) || Open[i]>ObjectGetValueByShift(NameLine.Buy,i)))  {
      if(DrawOrdersBuy(i))  
      {
        if(OnAlert.Orders)  
        {
          if(i==0 && colOrders(OP_BUY) == 0 && s < 80)  
          {
          Alert(Symbol(),Period(),": Сигнал на покупку! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
          OrderCl(OP_SELL); 
          OrderOp(OP_BUY, Symbol(), TakeProfit, StopLoss, Lot);
          }
        }
        if(SendEnter)  
        {
          if(i==0)  
          {
            SendMailSignals(i, 10);
          }
        }        
      }
    }
    //----- пересечение стоплосса ордера на покупку
    if(StrToDouble(mOrders[0][0])==10 && StrToDouble(mOrders[0][4])==0 && 
      (StrToDouble(mOrders[0][3])>=Low[i+1] || StrToDouble(mOrders[0][3])>=Open[i]))  {
      // ----- устанавливаем флаг срабатывания стоплосса
      mOrders[0][4]=1;
      // ----- 
      if(OnAlert.Orders)  
      {
        if(i==0)  
        {
          Alert(Symbol(),Period(),": Сработал стоплосс для оредра Buy! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
        }
      }
      if(SendLoss)  
      {
        if(i==0)  
        {
          SendMailSignals(i, 11);
        }
      }        
    }
    //----- пересечение восходящей "вилки" - сигнал на продажу
    if((StrToDouble(mOrders[1][0])==0 || (StrToDouble(mOrders[1][0])==20 && StrToDouble(mOrders[1][4])==1)) &&
       (Close[i+1]<ObjectGetValueByShift(NameLine.Sell,i+1) || Open[i]<ObjectGetValueByShift(NameLine.Sell,i)))  {
      if(DrawOrdersSell(i))  {
        if(OnAlert.Orders)  {
          if(i==0 && colOrders(OP_SELL)==0 && s > 20)  
          {
          Alert(Symbol(),Period(),": Сигнал на продажу! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
          OrderCl(OP_BUY); 
          OrderOp(OP_SELL, Symbol(), TakeProfit, StopLoss, Lot);
          }
        }
        if(SendEnter)  
        {
          if(i==0)  
          {
            SendMailSignals(i, 20);
          }
        }        
      }
    }
    //----- пересечение стоплосса ордера на продажу
    if(StrToDouble(mOrders[1][0])==20 && StrToDouble(mOrders[1][4])==0 && 
      (StrToDouble(mOrders[1][3])<=High[i+1] || StrToDouble(mOrders[1][3])<=Open[i]))  {
      // ----- устанавливаем флаг срабатывания стоплосса
      mOrders[1][4]=1;
      // ----- 
      if(OnAlert.Orders)  {
        if(i==0)  {
          Alert(Symbol(),Period(),": Сработал стоплосс для оредра Sell! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS));
        }
      }
      if(SendLoss)  {
        if(i==0)  {
          SendMailSignals(i, 21);
        }
      }        
    }

  }


  return;
}



//+------------------------------------------------------------------+
//+---------------------------------------------------------------------------+
bool UpperVilka(int nBar)  {     // Функция определяет и рисует восходящие "вилки"
int         j=0;
double      Fractal.Lower=0;
double      mFractals.Price[3];
datetime    mFractals.DateTime[3];
   // ----- заполняем массивы информацией о последних трех фракталах
   ArrayInitialize(mFractals.Price,0); ArrayInitialize(mFractals.DateTime,0);
   for (int i=nBar; i<Bars; i++)   {  // Цикл по барам
      Fractal.Lower=iFractals(NULL,0,MODE_LOWER,i);
      if(Fractal.Lower!=0) {
         mFractals.Price[j]=Fractal.Lower-MarketInfo(Symbol(),MODE_SPREAD)*Point;
         mFractals.DateTime[j]=Time[i];
         j++;
      }
      if(j>2) break;
   }
   // ----- рисуем восходящую "вилку"
   if(mFractals.Price[2]<mFractals.Price[1] && mFractals.Price[1]<mFractals.Price[0])  {
      string Name1="Line.Upper"+DoubleToStr(nLine.Upper,0); nLine.Upper++;
      string Name2="Line.Upper"+DoubleToStr(nLine.Upper,0); nLine.Upper++;

      ObjectCreate(Name1,OBJ_TREND,0,mFractals.DateTime[2],mFractals.Price[2],mFractals.DateTime[1],mFractals.Price[1]);
      ObjectCreate(Name2,OBJ_TREND,0,mFractals.DateTime[1],mFractals.Price[1],mFractals.DateTime[0],mFractals.Price[0]);
      if (ObjectGetValueByShift(Name1,nBar)<ObjectGetValueByShift(Name2,nBar))  {
        ObjectDelete(Name1); ObjectDelete(Name2); nLine.Upper--; nLine.Upper--; return(false);
      }
      ObjectSet(Name1,OBJPROP_COLOR,Color.LineUpper);   ObjectSet(Name2,OBJPROP_COLOR,Color.LineUpper);
      ObjectSet(Name1,OBJPROP_WIDTH,Width.LineUpper);   ObjectSet(Name2,OBJPROP_WIDTH,Width.LineUpper);
      ObjectSet(Name1,OBJPROP_RAY,True);                ObjectSet(Name2,OBJPROP_RAY,True);
      CheckNumVilka(10);
      // ----- удаляем предыдущий ордер на продажу
      DeleteOrders(20);
      return(true);
   }
   return(false);
}

//+---------------------------------------------------------------------------+
bool LowerVilka(int nBar)  {     // Функция определяет и рисует нисходящие "вилки"
int         j=0;
double      Fractal.Upper=0;
double      mFractals.Price[3];
datetime    mFractals.DateTime[3];
   // ----- заполняем массивы информацией о последних трех фракталах
   ArrayInitialize(mFractals.Price,0); ArrayInitialize(mFractals.DateTime,0);
   for (int i=nBar; i<Bars; i++)   {  // Цикл по барам
      Fractal.Upper=iFractals(NULL,0,MODE_UPPER,i);
      if(Fractal.Upper!=0) {
         mFractals.Price[j]=Fractal.Upper+MarketInfo(Symbol(),MODE_SPREAD)*Point;
         mFractals.DateTime[j]=Time[i];
         j++;
      }
      if(j>2) break;
   }
   // ----- рисуем нисходящие "вилку"
   if(mFractals.Price[2]>mFractals.Price[1] && mFractals.Price[1]>mFractals.Price[0])  {
      string Name1="Line.Lower"+DoubleToStr(nLine.Lower,0); nLine.Lower++;
      string Name2="Line.Lower"+DoubleToStr(nLine.Lower,0); nLine.Lower++;

      ObjectCreate(Name1,OBJ_TREND,0,mFractals.DateTime[2],mFractals.Price[2],mFractals.DateTime[1],mFractals.Price[1]);
      ObjectCreate(Name2,OBJ_TREND,0,mFractals.DateTime[1],mFractals.Price[1],mFractals.DateTime[0],mFractals.Price[0]);
      if (ObjectGetValueByShift(Name1,nBar)>ObjectGetValueByShift(Name2,nBar))  {
        ObjectDelete(Name1); ObjectDelete(Name2); nLine.Lower--; nLine.Lower--; return(false);
      }
      ObjectSet(Name1,OBJPROP_COLOR,Color.LineLower);   ObjectSet(Name2,OBJPROP_COLOR,Color.LineLower);
      ObjectSet(Name1,OBJPROP_WIDTH,Width.LineLower);   ObjectSet(Name2,OBJPROP_WIDTH,Width.LineLower);
      ObjectSet(Name1,OBJPROP_RAY,True);                ObjectSet(Name2,OBJPROP_RAY,True);
      CheckNumVilka(20);
      // ----- удаляем предыдущий ордер на покупку
      DeleteOrders(10);
      return(true);
   }
   return(false);
}

//+---------------------------------------------------------------------------+
bool isNewBar() {                     // Функция возвращает true, если появиться новый бар, иначе false
  if(nBars!=Bars) {
    nBars=Bars; return(true);
  }
  return(false);
}

//+---------------------------------------------------------------------------+
void CheckNumVilka(int Type)  {     // Функция проверяет допустимое количество вилок указанного типа
int i;
  switch(Type)  {
    case 10:
      //--------------------------------------------------------- 1 --
      if(nLine.Upper<=nVilka.Upper*2)  {
        mLineUpper.DateTime[nLine.Upper-2][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME1);
        mLineUpper.DateTime[nLine.Upper-2][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME2);
        mLineUpper.Price[nLine.Upper-2][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE1);
        mLineUpper.Price[nLine.Upper-2][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        mLineUpper.DateTime[nLine.Upper-1][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME1);
        mLineUpper.DateTime[nLine.Upper-1][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME2);
        mLineUpper.Price[nLine.Upper-1][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE1);
        mLineUpper.Price[nLine.Upper-1][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE2);
      }
      //--------------------------------------------------------- 2 --
      if(nLine.Upper >nVilka.Upper*2)  {
        for (i=0; i<nLine.Upper-4; i++)  {
          mLineUpper.DateTime[i][0]=mLineUpper.DateTime[i+2][0]; mLineUpper.DateTime[i][1]=mLineUpper.DateTime[i+2][1];
          mLineUpper.Price[i][0]=mLineUpper.Price[i+2][0]; mLineUpper.Price[i][1]=mLineUpper.Price[i+2][1];
        }
        mLineUpper.DateTime[nLine.Upper-4][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME1);
        mLineUpper.DateTime[nLine.Upper-4][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME2);
        mLineUpper.Price[nLine.Upper-4][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE1);
        mLineUpper.Price[nLine.Upper-4][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        mLineUpper.DateTime[nLine.Upper-3][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME1);
        mLineUpper.DateTime[nLine.Upper-3][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME2);
        mLineUpper.Price[nLine.Upper-3][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE1);
        mLineUpper.Price[nLine.Upper-3][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        ObjectDelete("Line.Upper"+(nLine.Upper-2)); ObjectDelete("Line.Upper"+(nLine.Upper-1));
        nLine.Upper--;nLine.Upper--;
        //+------------------------------------------------------------------+
        for (i=0; i<nLine.Upper; i++)  {
          ObjectMove("Line.Upper"+i,0,mLineUpper.DateTime[i][0],mLineUpper.Price[i][0]);
          ObjectMove("Line.Upper"+i,1,mLineUpper.DateTime[i][1],mLineUpper.Price[i][1]);
        } 
      }
      break;  // это добавил после внимательного прочтения справки
    case 20:
      //--------------------------------------------------------- 1 --
      if(nLine.Lower<=nVilka.Lower*2)  {
        mLineLower.DateTime[nLine.Lower-2][0]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_TIME1);
        mLineLower.DateTime[nLine.Lower-2][1]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_TIME2);
        mLineLower.Price[nLine.Lower-2][0]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_PRICE1);
        mLineLower.Price[nLine.Lower-2][1]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        mLineLower.DateTime[nLine.Lower-1][0]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_TIME1);
        mLineLower.DateTime[nLine.Lower-1][1]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_TIME2);
        mLineLower.Price[nLine.Lower-1][0]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_PRICE1);
        mLineLower.Price[nLine.Lower-1][1]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_PRICE2);
      }
      //--------------------------------------------------------- 2 --
      if(nLine.Lower >nVilka.Lower*2)  {
        for (i=0; i<nLine.Lower-4; i++)  {
          mLineLower.DateTime[i][0]=mLineLower.DateTime[i+2][0]; mLineLower.DateTime[i][1]=mLineLower.DateTime[i+2][1];
          mLineLower.Price[i][0]=mLineLower.Price[i+2][0]; mLineLower.Price[i][1]=mLineLower.Price[i+2][1];
        }
        mLineLower.DateTime[nLine.Lower-4][0]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_TIME1);
        mLineLower.DateTime[nLine.Lower-4][1]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_TIME2);
        mLineLower.Price[nLine.Lower-4][0]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_PRICE1);
        mLineLower.Price[nLine.Lower-4][1]=ObjectGet("Line.Lower"+(nLine.Lower-2),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        mLineLower.DateTime[nLine.Lower-3][0]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_TIME1);
        mLineLower.DateTime[nLine.Lower-3][1]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_TIME2);
        mLineLower.Price[nLine.Lower-3][0]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_PRICE1);
        mLineLower.Price[nLine.Lower-3][1]=ObjectGet("Line.Lower"+(nLine.Lower-1),OBJPROP_PRICE2);
        //+------------------------------------------------------------------+
        ObjectDelete("Line.Lower"+(nLine.Lower-2)); ObjectDelete("Line.Lower"+(nLine.Lower-1));
        nLine.Lower--;nLine.Lower--;
        //+------------------------------------------------------------------+
        for (i=0; i<nLine.Lower; i++)  {
          ObjectMove("Line.Lower"+i,0,mLineLower.DateTime[i][0],mLineLower.Price[i][0]);
          ObjectMove("Line.Lower"+i,1,mLineLower.DateTime[i][1],mLineLower.Price[i][1]);
        } 
      }
      break;  // это добавил после внимательного прочтения справки
  }
  return;
}

//+---------------------------------------------------------------------------+
void DeleteOrders(int Type)  {     // Функция удаляет ордера указанного типа
  if(Type==10)  {
    //--------------------------------------------------------- 1 --
    mOrders[0][0]=0; mOrders[0][1]=""; mOrders[0][2]=""; mOrders[0][3]=""; mOrders[0][4]=0;
    ObjectDelete("Order.Buy"); ObjectDelete("OrderArrow.Buy");
    ObjectDelete("StopLoss.Buy"); ObjectDelete("StopLossArrow.Buy");
    ObjectDelete("LabelPrice.Buy"); ObjectDelete("LabelStopLoss.Buy");
  }
  if(Type==20)  {
    //--------------------------------------------------------- 2 --
    mOrders[1][0]=0; mOrders[1][1]=""; mOrders[1][2]=""; mOrders[1][3]=""; mOrders[1][4]=0;
    ObjectDelete("Order.Sell"); ObjectDelete("OrderArrow.Sell");
    ObjectDelete("StopLoss.Sell"); ObjectDelete("StopLossArrow.Sell");
    ObjectDelete("LabelPrice.Sell"); ObjectDelete("LabelStopLoss.Sell");
  }
  return;
}

//+---------------------------------------------------------------------------+
bool DrawOrdersBuy(int nBar)  {     // Функция рисут ордера Buy
double Price.Buy=Open[nBar];
double StopLoss.Buy;
  // ----- определяем стоплосс
  for (int i=nBar+1; i<Bars; i++)   {  // Цикл по барам
    StopLoss.Buy=iFractals(NULL,0,MODE_LOWER,i);
    if(StopLoss.Buy!=0)  {
      StopLoss.Buy=StopLoss.Buy-MarketInfo(Symbol(),MODE_SPREAD)*Point;
      break;
    }
  }
  // ----- проверяем условия для открытия позиции
  // 1. Фрактал должен быть ниже верхнего луча вилки.
  // 2. Значение фрактала должно быть меньше значения открытия позиции(пересечения).
  if(StopLoss.Buy>=ObjectGetValueByShift(NameLine.Buy,i) || StopLoss.Buy>=Price.Buy)  {
    return(false);
  }
  // ----- удаляем предыдущий ордер на покупку
  DeleteOrders(10);
  // ----- определяемся с параметрами ордера
  mOrders[0][0]=10;                                             // устанавливаем флаг "открытого" ордера на покупку
  mOrders[0][1]=TimeToStr(Time[nBar],TIME_DATE|TIME_MINUTES);   // Дата и время "открытия" ордера
  mOrders[0][2]=Price.Buy;                                      // Цена ордера ордера
  mOrders[0][3]=StopLoss.Buy;                                   // Стоплосс ордера ордера
  mOrders[0][4]=0;                                              // флаг срабатывания стоплосса: 0-стоплосс НЕ сработал, 1-стоплосс сработал
  // ----- рисуем, если разрешено
  if(ShowOrders)  {
    // ----- рисуем ордер на покупку
    ObjectCreate("Order.Buy",OBJ_TREND,0,Time[nBar+25],Price.Buy,Time[nBar],Price.Buy);
    ObjectCreate("OrderArrow.Buy",OBJ_ARROW,0,Time[nBar+23],Price.Buy);
    ObjectSet("Order.Buy",OBJPROP_COLOR,Color.OrderBuy);  ObjectSet("OrderArrow.Buy",OBJPROP_COLOR,Color.OrderBuy);
    ObjectSet("Order.Buy",OBJPROP_WIDTH,Width.OrderBuy);  ObjectSet("OrderArrow.Buy",OBJPROP_WIDTH,Width.OrderBuy);
    ObjectSet("Order.Buy",OBJPROP_RAY,false);             ObjectSet("OrderArrow.Buy",OBJPROP_ARROWCODE,225);
    ObjectCreate("LabelPrice.Buy",OBJ_TEXT,0,Time[nBar+10],Price.Buy);
    ObjectSetText("LabelPrice.Buy","Buy: "+DoubleToStr(Price.Buy,Digits),Orders.FontSize, "Times New Roman", 
                                                                                            Color.OrderBuy);
    // ----- рисуем стоплос на покупку
    ObjectCreate("StopLoss.Buy",OBJ_TREND,0,Time[nBar+25],StopLoss.Buy,Time[nBar],StopLoss.Buy);
    ObjectCreate("StopLossArrow.Buy",OBJ_ARROW,0,Time[nBar+23],StopLoss.Buy);
    ObjectSet("StopLoss.Buy",OBJPROP_COLOR,Color.SLBuy);     ObjectSet("StopLossArrow.Buy",OBJPROP_COLOR,Color.SLBuy);
    ObjectSet("StopLoss.Buy",OBJPROP_WIDTH,Width.OrderBuy);  ObjectSet("StopLossArrow.Buy",OBJPROP_WIDTH,Width.OrderBuy);
    ObjectSet("StopLoss.Buy",OBJPROP_RAY,false);             ObjectSet("StopLossArrow.Buy",OBJPROP_ARROWCODE,251);
    ObjectCreate("LabelStopLoss.Buy",OBJ_TEXT,0,Time[nBar+10],StopLoss.Buy);
    ObjectSetText("LabelStopLoss.Buy","SL Buy: "+DoubleToStr(StopLoss.Buy,Digits),Orders.FontSize, "Times New Roman", 
                                                                                                    Color.SLBuy);
  }
  return(true);
}

//+---------------------------------------------------------------------------+
bool DrawOrdersSell(int nBar)  {     // Функция рисут ордера Sell
double Price.Sell=Open[nBar];
double StopLoss.Sell;
  // ----- определяем стоплосс
  for (int i=nBar; i<Bars; i++)   {  // Цикл по барам
    StopLoss.Sell=iFractals(NULL,0,MODE_UPPER,i);
    if(StopLoss.Sell!=0)  {
      StopLoss.Sell=StopLoss.Sell+MarketInfo(Symbol(),MODE_SPREAD)*Point;
      break;
    }
  }
  // ----- проверяем условия для открытия позиции
  // 1. Фрактал должен быть выше верхнего луча вилки.
  // 2. Значение фрактала должно быть больше значения открытия позиции(пересечения).
  if(StopLoss.Sell<=ObjectGetValueByShift(NameLine.Sell,i) || StopLoss.Sell<=Price.Sell)  {
    return(false);
  }
  // ----- удаляем предыдущий ордер на продажу
  DeleteOrders(20);
  // ----- определяемся с параметрами ордера
  mOrders[1][0]=20;                                             // устанавливаем флаг "открытого" ордера на продажу
  mOrders[1][1]=TimeToStr(Time[nBar],TIME_DATE|TIME_MINUTES);   // Дата и время "открытия" ордера
  mOrders[1][2]=Price.Sell;                                     // Цена ордера ордера
  mOrders[1][3]=StopLoss.Sell;                                  // Стоплосс ордера ордера
  mOrders[1][4]=0;                                              // флаг срабатывания стоплосса: 0-стоплосс НЕ сработал, 1-стоплосс сработал
  // ----- рисуем, если разрешено
  if(ShowOrders)  {
    // ----- рисуем ордер на продажу
    ObjectCreate("Order.Sell",OBJ_TREND,0,Time[nBar+25],Price.Sell,Time[nBar],Price.Sell);
    ObjectCreate("OrderArrow.Sell",OBJ_ARROW,0,Time[nBar+23],Price.Sell+10*Point);
    ObjectSet("Order.Sell",OBJPROP_COLOR,Color.OrderSell);  ObjectSet("OrderArrow.Sell",OBJPROP_COLOR,Color.OrderSell);
    ObjectSet("Order.Sell",OBJPROP_WIDTH,Width.OrderSell);  ObjectSet("OrderArrow.Sell",OBJPROP_WIDTH,Width.OrderSell);
    ObjectSet("Order.Sell",OBJPROP_RAY,false);              ObjectSet("OrderArrow.Sell",OBJPROP_ARROWCODE,226);
    ObjectCreate("LabelPrice.Sell",OBJ_TEXT,0,Time[nBar+10],Price.Sell+10*Point);
    ObjectSetText("LabelPrice.Sell","Sell: "+DoubleToStr(Price.Sell,Digits),Orders.FontSize, "Times New Roman", 
                                                                                              Color.OrderSell);
    // ----- рисуем стоплос на продажу
    ObjectCreate("StopLoss.Sell",OBJ_TREND,0,Time[nBar+25],StopLoss.Sell,Time[nBar],StopLoss.Sell);
    ObjectCreate("StopLossArrow.Sell",OBJ_ARROW,0,Time[nBar+23],StopLoss.Sell+10*Point);
    ObjectSet("StopLoss.Sell",OBJPROP_COLOR,Color.SLSell);   ObjectSet("StopLossArrow.Sell",OBJPROP_COLOR,Color.SLSell);
    ObjectSet("StopLoss.Sell",OBJPROP_WIDTH,Width.OrderSell);ObjectSet("StopLossArrow.Sell",OBJPROP_WIDTH,Width.OrderSell);
    ObjectSet("StopLoss.Sell",OBJPROP_RAY,false);            ObjectSet("StopLossArrow.Sell",OBJPROP_ARROWCODE,251);
    ObjectCreate("LabelStopLoss.Sell",OBJ_TEXT,0,Time[nBar+10],StopLoss.Sell+10*Point);
    ObjectSetText("LabelStopLoss.Sell","SL Sell: "+DoubleToStr(StopLoss.Sell,Digits),Orders.FontSize, "Times New Roman", 
                                                                                                     Color.SLSell);
  }
  return;
}

//+---------------------------------------------------------------------------+
void SendMailSignals(int nBar, int SignalId)  {   // отсылает сообщение на e-mail торговые сигналы
string Mail.Message;
  switch(SignalId)  {
    //--------------------------------------------------------- 1 --
    case 10:
      Mail.Message="Buy signal!"+CharToStr(13)+"Symbol: "+Symbol()+CharToStr(13)+
                   "Timeframe: "+GetNameTF()+CharToStr(13)+"DateTime: "+mOrders[0][1]+CharToStr(13)+
                   "Price: "+mOrders[0][2]+CharToStr(13)+"StopLoss: "+mOrders[0][3];
      SendMail("Buy signal!",Mail.Message);
      break;
    //--------------------------------------------------------- 2 --
    case 11:
      Mail.Message="Attention! Stop Loss  Buy!"+CharToStr(13)+"Symbol: "+Symbol()+CharToStr(13)+
                   "Timeframe: "+GetNameTF()+CharToStr(13)+"DateTime: "+TimeToStr(Time[nBar],TIME_DATE|TIME_MINUTES)+
                   CharToStr(13)+"StopLoss: "+mOrders[0][3];
      SendMail("Attention! Stop Loss  Buy!",Mail.Message);
      break;
    //--------------------------------------------------------- 3 --
    case 20:
      Mail.Message="Sell signal!"+CharToStr(13)+"Symbol: "+Symbol()+CharToStr(13)+
                   "Timeframe: "+GetNameTF()+CharToStr(13)+"DateTime: "+mOrders[1][1]+CharToStr(13)+
                   "Price: "+mOrders[1][2]+CharToStr(13)+"StopLoss: "+mOrders[1][3];
      SendMail("Sell signal!",Mail.Message);
      break;
    //--------------------------------------------------------- 4 --
    case 21:
      Mail.Message="Attention! Stop Loss  Sell!"+CharToStr(13)+"Symbol: "+Symbol()+CharToStr(13)+
                   "Timeframe: "+GetNameTF()+CharToStr(13)+"DateTime: "+TimeToStr(Time[nBar],TIME_DATE|TIME_MINUTES)+
                   CharToStr(13)+"StopLoss: "+mOrders[1][3];
      SendMail("Attention! Stop Loss  Sell! ",Mail.Message);
      break;
  }
  return;
}

//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 01.09.2005                                                     |
//|  Описание : Возвращает наименование таймфрейма                             |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    TimeFrame - таймфрейм (количество секунд)      (0 - текущий ТФ)         |
//+----------------------------------------------------------------------------+
string GetNameTF(int TimeFrame=0) {
  if (TimeFrame==0) TimeFrame=Period();
  switch (TimeFrame) {
    case PERIOD_M1:  return("M1");
    case PERIOD_M5:  return("M5");
    case PERIOD_M15: return("M15");
    case PERIOD_M30: return("M30");
    case PERIOD_H1:  return("H1");
    case PERIOD_H4:  return("H4");
    case PERIOD_D1:  return("Daily");
    case PERIOD_W1:  return("Weekly");
    case PERIOD_MN1: return("Monthly");
    default:         return("UnknownPeriod");
  }
}

//+---------------------------------------------------------------------------+
bool CheckParameters()  {     // Функция проверки внешних параметров индикатора
  if(nVilka.Upper<1 || nVilka.Lower<1)  {
    string  TextMessage="Неверные значения внешних параметров индикатора!"+
                        "Параметры nVilka.Upper и nVilka.Lower не могут быть <(меньше) 1";
    Alert(TextMessage);
    return(false);
  }
  return(true);
}

void OrderOp(int ord, string val, int TakeProfit, int StopLoss, double lot)
{
   double TP,SL,ticket, pAsk, pBid;
   bool res=false;
   while(!res)
   {
      pAsk = MarketInfo(val,MODE_ASK);
      pBid = MarketInfo(val,MODE_BID);
      TP=0; SL=0;
   
      if(ord==OP_BUY)
      {
         TP=pAsk+TakeProfit*Point; if(TakeProfit==0) TP=0;
         SL=pBid-StopLoss*Point;   if(StopLoss==0) SL=0;
         ticket=OrderSend(val,OP_BUY,lot,pAsk,3,SL,TP,"",MG,0);
      }
      if(ord==OP_SELL)
      {
         TP=pBid-TakeProfit*Point; if(TakeProfit==0) TP=0;
         SL=pAsk+StopLoss*Point;   if(StopLoss==0) SL=0;
         ticket=OrderSend(val,OP_SELL,lot,pBid,3,SL,TP,"",MG,0);
      }
      if(ticket>0) res = true;
   }      
}

//+------------------------------------------------------------------+
int colOrders(int oType)
{
   int cnt,ao=0;
   for(cnt=OrdersTotal();cnt>0;cnt--)
   {
      OrderSelect(cnt-1, SELECT_BY_POS, MODE_TRADES);
      if(OrderMagicNumber()==MG && OrderType() == oType) ao++;
   }
   return(ao);
}

//+------------------------------------------------------------------+
int OrderCl(int ord)
{
   int cnt;
   for(cnt=OrdersTotal();cnt>0;cnt--)
   {
      OrderSelect(cnt-1, SELECT_BY_POS, MODE_TRADES);
      if(OrderType()==OP_BUY  && ord==OP_BUY  && OrderMagicNumber()==MG) while (!OrderClose(OrderTicket(),OrderLots(),Bid,3)) { }
      if(OrderType()==OP_SELL && ord==OP_SELL && OrderMagicNumber()==MG) while (!OrderClose(OrderTicket(),OrderLots(),Ask,3)) { }
   }
}
//+------------------------------------------------------------------+



