//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// AG_Srtategy_Channal_Inside.mq4                                     Пример стратегии 1. 
// Отложенные ордера BuyLimit и SellLimit по границам канала. 
// Профитное движение вовнутрь канала (отскок). 
// Используется при построении функции автоматической торговли для приложения AutoGraf 4
// Сергей Ковалёв, Днепропетровск, sk@autograf.dp.ua, ICQ 64015987, http://autograf.dp.ua
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 0 жж
#property library   
 
#import "AG_Lib.ex4" 
   int AG_Magic_Number();                          // Вычисление MN  
   int AG_Message(string& Message[], string _Text);// Запись сообщений в массив Message[]
                          // Запись управляющих воздействий ф-ии АТ в массив Manager[][]:
   int AG_Set_Instr(double& Manager[][], int ii, double v1, double v2, double v3,
                    double v4, double v5, double v6, int io , int ih); 
   int AG_Delete_Instr(double&Manager[][], int ii, int io,int ih);//Удаление инструментов
#import
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 1 жж
int AG_Srtategy_Channal_Inside(int Parol_S, double Order[][], string Object[], 
                               double Instrument[][][][], int Ddraw_Object[][], 
                               double& Tuning[], double& Manager[][], string& Message[])
   {    
//================================================================================== 2 ==
/*
   if (!IsDemo())                                  // Для демо без ограничений
      {
      if(Parol_S != AccountNumber() + 1)           // Если введен неправильный пароль
         {                                         // Пример сообщения (макс. 62 симв)
         int Strategy = NormalizeDouble(Instrument[0][0][0][0],0);
         AG_Message(Message, "Введен неправильный пароль для стратегии ");// Сообщение
         AG_Message(Message, "AG_Srtategy_Channal_Inside ("+Strategy+").");// Сообщение
         return(0);                                // Выход из функции AT
         }                                         // AutoGraf автоматически отключит АТ
      }   
*/
//================================================================================== 3 ==
   int MN;                // MagicNumber рекомендуется вычислять в ф-ии AG_Magic_Number()
   int Ticket;                                     // Номер ордера
   string Comm = "AG_AT";                          // Комментарий (рекомендуется "AG_AT")
   static string My_Chan_Name="AT_Channal_Inside"; // Имя создаваемого канала
   int With = 180;                                 // Ширина канала в минутах(в барах М1)
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   double Lot= NormalizeDouble(Tuning[1],2);       // Значение лотов
   int Slip  = NormalizeDouble(Tuning[3],0);       // Проскальзывание (пунктов)
//================================================================================== 4 ==
   bool Channal   = false;                         // Искомого объекта заданного типа нет
   bool Manage_12 = false;                         // Объект заданного типа не назначен ..
                                                   // ..под управление инстр12
   if (ObjectFind(My_Chan_Name)>-1)                // Если объект есть ..
      {
      if(ObjectType(My_Chan_Name)==OBJ_STDDEVCHANNEL)// Если объект ожидаемого типа
         {         
         Channal = true;                           // .. запомним этот факт
         int Obj_Total_AG =StrToInteger(Object[0]);// Колич. объектов, рассматр. AG 4
         for(int k=1; k<=Obj_Total_AG; k++)        // Пройдёмся по рассматриваемым объек.
            {                                       
            if (Object[k] == My_Chan_Name)         // Попался объект с искомым именем
               {                                   
               for(int i=1; i<=Ddraw_Object[0][0]; i++)// По массиву объектов, ..               
                  {                                // .. управляемых инструментом 12
                  if(Ddraw_Object[i][0] == k)      // Если объект уже назначен ..
                     {                             // .. под управл. инструмента 12
                     Manage_12 = true;             // Этот объект уже под управл. инстр 12
                     break;                        // Объект найден
                     }
                  }
               break;                              // Выходим (выносим индекс k)
               }
            }
         }
//---------------------------------------------------------------------------------- 5 --
      else                                         // Если тип у него не тот, подищем..
         {                                         // .. создаваемому объ. подходящее имя
         for (int pref=2; ;pref++)                 // Начиная с префикса 2
            {
            string New_Name = My_Chan_Name + pref; // Попробуем примерить такое имя
            if (ObjectFind(New_Name) == -1)        // Если это имя не занято..
               {
               My_Chan_Name = New_Name;
               break;                              // .. значит незанятое имя найдено
               }
            }
         } 
      }
//================================================================================== 6 ==
   if (Channal == false)                           // Если объекта заданного типа нет
      {
      ObjectCreate (My_Chan_Name, OBJ_STDDEVCHANNEL,0,0,0); // Создаём его.. 
      int Сoor_X2 = Time[0];                                // 1я точка СПРАВА, 2я СЛЕВА
      int Сoor_X1 = Сoor_X2 - With*60;                      // Канал длиной 3 часа
      ObjectSet(My_Chan_Name, OBJPROP_TIME1, Сoor_X1);      // Устанавливаем координаты
      ObjectSet(My_Chan_Name, OBJPROP_TIME2, Сoor_X2);      // Устанавливаем координаты 
      ObjectSet(My_Chan_Name, OBJPROP_COLOR, Orange);       // Устанавливаем координаты 
      AG_Message(Message, "АТ: Устанавливаем объект OBJ_STDDEVCHANNEL.");// Сообщение
      return(1);                 // Это необходимо, чтоб установл. канал был учтён AG 4
      }
//---------------------------------------------------------------------------------- 7 --
   if (Manage_12 == false)       // Объект есть, но не назначен под управление инстр 12
      {                          // Устанавливаем Инструмент 12 Тянуть_Объект на канал
      AG_Set_Instr(Manager, 12, 0, 0, 0, 0, 0, 0, k, 0); 
      AG_Message(Message, "АТ: Устанавливаем инструмент Тянуть объект."); // Сообщение
      }
//================================================================================== 8 ==
   int Total_Ord = NormalizeDouble(Order[0][0],0);          // Количество ордеров в окне
   
   bool BLim = true; // Пока считаем, что никаких Buy в окне нет,  поэтому BuyLimit  нужен
   bool SLim = true; // Пока считаем, что никаких Sell в окне нет, поэтому SellLimit нужен
   for (i=1; i<=Total_Ord; i++)
      {
      int Tip_Ord = NormalizeDouble(Order[i][6],0);         // Тип текущего ордера
      if (Tip_Ord==0 || Tip_Ord==2 || Tip_Ord==4)           // При любых баях считаем, ..
         BLim = false;                                      // ..что BuyLimit нам не нужен
      if (Tip_Ord==1 || Tip_Ord==3 || Tip_Ord==5)           // При любых селах считаем,..
         SLim = false;                                      //..что SellLimit нам не нужен
      }
//================================================================================== 9 ==
   int StopLevel = MarketInfo( Symbol(), MODE_STOPLEVEL);
   int STD = iStdDev(NULL,0,With,0,MODE_SMA,PRICE_CLOSE,0)/Point;
   int SL = 2*STD;
   if (SL < StopLevel)
      SL = StopLevel;
   int TP = 1.2*STD;
   if (TP < StopLevel)
      TP = StopLevel;
   double Price_Right = ObjectGet(My_Chan_Name, OBJPROP_PRICE2);// Правая коорд. канала
//--------------------------------------------------------------------------------- 10 --
   if (BLim == true)                                        //  BuyLimit
      {
      double Price = NormalizeDouble(Price_Right-STD*Point,Digits);// Цена ордера
      if (Price > Ask - StopLevel*Point)                    // Проверка цены
         Price = Ask - StopLevel*Point;
      double SL_BL = NormalizeDouble(Price-SL*Point,Digits);// Проверка SL
      double TP_BL = NormalizeDouble(Price+TP*Point,Digits);// Проверка ТР
      MN = AG_Magic_Number();                               // Вычисл. MN (рекомендуется)
      OrderSend(Symbol(),OP_BUYLIMIT,Lot,Price,Slip,SL_BL,TP_BL,Comm,MN);//  BuyLimit
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
   if (SLim == true)                                        // SellLimit
      {
      Price = NormalizeDouble(Price_Right+STD*Point,Digits);// Цена ордера
      if (Price < Bid + StopLevel*Point)                    // Проверка цены
         Price = Bid + StopLevel*Point;
      double SL_SL = NormalizeDouble(Price+SL*Point,Digits);// Проверка SL
      double TP_SL = NormalizeDouble(Price-TP*Point,Digits);// Проверка ТР
      MN = AG_Magic_Number();                               // Вычисл. MN (рекомендуется)
      OrderSend(Symbol(),OP_SELLLIMIT,Lot,Price,Slip,SL_SL,TP_SL,Comm,MN);// SellLimit
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
//================================================================================= 11 ==
   for (i=1; i<=Total_Ord; i++)
      {
      if (NormalizeDouble(Order[i][6],0) == 2)// Если тип ордера BuyLimit
         {                                                                 
                        // Если инстр. Следование_За_Объектом на BuyLimit не установлен
         if( NormalizeDouble(Instrument[i][1][11][0],1)< 1.0 )
            // i  = индекс ордера
            // 1  = индекс ордерной линии (OR)
            // 11 = индекс инструмента Следование_За_Объектом
            // 0  = признак установки инструмента
            // 1.0= инструмент установлен (0.5=подготовлен для настройки на линию, 
            //                             0.0 = не установлен)(Нормализация до 1 знака)
            {
            int Tm = 0; // Смещение по времени
                        // (смещение считается от текущего времени, поэтому инструмент..
                        // ..может "самопроизвольно" смещаться вправо в момент,..
                        // ..не совпадающий со временем образования 0 бара;это нормально)
            Ticket = NormalizeDouble(Order[i][4],0);
                        // Устанавливаем Инструмент 11, Следование_За_Объектом
            AG_Set_Instr(Manager, 11, Tm, 0, 0, 3, k, 1, Ticket, 1);
            // 11 = индекс инструмента
            // Tm = время смещения от настоящего момента, сек
            // 0  = параметр отсутствует
            // 0 = дистанция преследования 
            // 3  = шаг модификации
            // k  = индекс объекта в массиве Object[0] 
            // 1  = индекс линии объекта (RegLine = 32, UpLine=0, DnLine=1)
            // Ticket  = номер ордера
            // 1  = индекс ордерной линии (OR=1)
            AG_Message(Message, "На BuyLimit " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }
//--------------------------------------------------------------------------------- 12 --
      if (NormalizeDouble(Order[i][6],0) == 3)// Если тип ордера SellLimit
         {                                                                 
                        // Если инстр. Следование_За_Объектом на SellLimit не установлен
         if( NormalizeDouble(Instrument[i][1][11][0],1)< 1.0 )
            {
            Tm = 0;     // Смещение по времени
            Ticket = NormalizeDouble(Order[i][4],0);
                        // Устанавливаем Инструмент 11, Следование_За_Объектом
            AG_Set_Instr(Manager, 11, Tm, 0, 0, 3, k, 0,  Ticket, 1);    
            AG_Message(Message, "На SellLimit " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }      
      }
//================================================================================= 13 ==
   return(1);           // Нормальный выход
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж Конец модуля жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 14 жж