//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// AG_AT.mq4                                             Пример 11 (инструменты 12,11)
// Пользовательская функция Автоматической Торговли.
// Используется при построении функции автоматической торговли для приложения 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_AT(int Parol_AT, double Order[][], string Object[], double Instrument[][][][], 
          int Ddraw_Object[][], double& Tuning[], double& Manager[][], string& Message[])
   {    
//================================================================================== 2 ==
   if (!IsDemo())                                  // Для демо без ограничений
      {
      if(Parol_AT != AccountNumber() + 1)          // Если введен неправильный пароль
         {                                         // Пример сообщения (макс. 62 симв)
         AG_Message(Message, "Разработчик J.Smith, http://company.com ");  
         AG_Message(Message, "Введен неправильный пароль для функции АТ.");
         return(0);                                // Выход из функции AT
         }                                         // AutoGraf автоматически отключит АТ
      }   
//================================================================================== 3 ==
   static int Count = 0;                           // Счётчик 
   int MN;                // MagicNumber рекомендуется вычислять в ф-ии AG_Magic_Number()
   static int Ticket;                              // Номер ордера
   string Comm = "AG_AT";                          // Комментарий (рекомендуется "AG_AT")
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   double Lot= NormalizeDouble(Tuning[1],2);       // Значение лотов
   int Per   = NormalizeDouble(Tuning[2],0);       // Значение % (целое)
   int Slip  = NormalizeDouble(Tuning[3],0);       // Проскальзывание (пунктов)
   int SL    = NormalizeDouble(Tuning[4],0);       // StopLoss (пунктов)
   int TP    = NormalizeDouble(Tuning[5],0);       // TakeProfit (пунктов)
   int Ds    = NormalizeDouble(Tuning[6],0);       // Дистанция (пунктов)
   int St    = NormalizeDouble(Tuning[7],0);       // Шаг модификации (пунктов)
//---------------------------------------------------------------------------------- 4 --
   if (Count==0)              // Это можно делать один раз в начале 
      {                       // Пример сообщения (максимум 62 симв):
      AG_Message(Message, "Разработчик J.Smith, http://company.com"); 
      Count++;                // Количество посещений этого блока
                        
      Lot   = 0.0;            // 0.0 означает, что колич лотов высчитывается в AutoGraf..
      Per   = 7;              // .. на основе значения % (здесь 7%) суммы баланса
      Slip  = 2;        
      SL    = 91;      
      TP    = 35;       
      Ds    = 21;       
      St    = 3;        
//---------------------------------------------------------------------------------- 5 --
      Tuning[1] = Lot;        // Значение лотов
      Tuning[2] = Per;        // Значение % (целое)
      Tuning[3] = Slip;       // Проскальзывание (пунктов)
      Tuning[4] = SL;         // StopLoss (пунктов)
      Tuning[5] = TP;         // TakeProfit (пунктов)
      Tuning[6] = Ds;         // Дистанция (пунктов)
      Tuning[7] = St;         // Шаг модификации (пунктов)
      AG_Message(Message,"Изменение настроек из АТ.");// Пример сообщения (макс.62 симв.)
      return(1);              // Выход после перенастроек параметров
      }
                              // После того, как управление из AG_AT будет возвращено..
                              // .. в приложение AutoGraf, в окне индикатора AG_ind..
                              // .. можно наблюдать новые значения настроек.
//================================================================================== 6 ==
   bool Channal   = false;    // Объекта заданного типа нет
   bool Manage_12 = false;    // Объект заданного типа не назначен под управление инстр12
   
   int Obj_Total_AG = StrToInteger(Object[0]);// Колич. объектов, рассматриваемых AG 4
   for(int k=1; k<=Obj_Total_AG; k++)         // Пройдёмся по рассматриваемым объектам
      {                       // (для практич. использов. требуется более полный анализ)
      string His_Name = Object[k];            // Имя текущего объекта
      if (ObjectType(His_Name) == OBJ_STDDEVCHANNEL)// (можно также OBJ_REGRESSION)
         {
                                 // По массиву объектов, управляемых инструментом 12
         for(int i=1; i<=Ddraw_Object[0][0]; i++)
            {
            if(k == Ddraw_Object[i][0])// Если объект уже назначен под управл. инстр. 12
               {
               Manage_12 = true; // Факт, что этот объект уже под управлением инстр 12
               break;            // Объект найден, дальше искать нет необходимости 
               }
            }
         Channal = true;         // Факт, что объект такого типа уже имеется в окне
         break;                  // Выходим из цикла перебора объектов (выносим индекс k)
         }
      }
//================================================================================== 7 ==
   if (Channal == false)         // Если объекта заданного типа нет
      {
      string My_Chan_Name = "Channel_for_AT";               // Имя создаваемого канала
      ObjectCreate (My_Chan_Name, OBJ_STDDEVCHANNEL,0,0,0); // Создаём его.. 
      int Сoor_X2 = Time[0];                                // 1я точка СЛЕВА, 2я СПРАВА
      int Сoor_X1 = Сoor_X2 - 24*60*60;                     // Канал длиной сутки
                                 // Канал для практич. использов. расчиывать через бары
      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
      }
   if (DayOfWeek() < 5)                                     // В любой день кроме Пятницы
      { 
      if (Manage_12 == false)    // Объект есть, но не назначен под управление инстр 12
         {
                                 // Устанавливаем Инструмент 12 Тянуть_Объект на канал
         AG_Set_Instr(Manager, 12, 0, 0, 0, 0, 0, 0, k, 0); 
         AG_Message(Message, "АТ: Устанавливаем инструмент Тянуть объект."); // Сообщение
         }
      }   
   else                          // А по Пятницам удаляем инстр.12 Тянуть_Объект
      {                          
      for( i=1; i<=Ddraw_Object[0][0]; i++)// По массиву объектов, управляемых инстр-м 12
         {
         AG_Delete_Instr(Manager, 12, i, 0);//Удаляем инстр Тянуть_Объект с этого объекта
       AG_Message(Message,"АТ: Удаляем Тянуть_Объект с объекта " +Ddraw_Object[i][0]+".");
         }       // После возвращения управления в AG 4 массив Ddraw_Object[][]
      }          // .. будет почищен и сжат. На каждой новой итерации индексы объектов..
                 // .. в массиве Object[] могут быть иными (в результ. удаления объектов)
//================================================================================== 8 ==
   int Total_Ord = NormalizeDouble(Order[0][0],0);          // Количество ордеров в окне
   
   bool BS = true; // Пока считаем, что никаких Buy в окне нет,  поэтому BuyStop  нужен
   bool SS = true; // Пока считаем, что никаких Sell в окне нет, поэтому SellStop нужен
   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)           // При любых баях считаем, ..
         BS = false;                                        // ..что BuyStop нам не нужен
      if (Tip_Ord==1 || Tip_Ord==3 || Tip_Ord==5)           // При любых селах считаем,..
         SS = false;                                        //..что SellStop нам не нужен
      }
//---------------------------------------------------------------------------------- 9 --
   if (BS == true)// Это не торговый критерий (для примера используется BuyStop)
      {
      double Price = Ask+100*Point;
      MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)
                  // Устанавливаем BuyStop 
      OrderSend( Symbol(),OP_BUYSTOP,Lot,Price,2,Price-SL*Point,Price+TP*Point,Comm,MN);
      return(1);  // Открылись и отдаём управление AG для учёта ордеров
      }
   if (SS == true)// Это не торговый критерий (для примера используется SellStop)
      {
      Price = Bid-100*Point;
      MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)
                  // Устанавливаем SellStop 
      OrderSend( Symbol(),OP_SELLSTOP,Lot,Price,2,Price+SL*Point,Price-TP*Point,Comm,MN);
      return(1);  // Открылись и отдаём управление AG для учёта ордеров
      }
//================================================================================= 10 ==
   for (i=1; i<=Total_Ord; i++)
      {
      if (NormalizeDouble(Order[i][6],0) == 4)// Если тип ордера BuyStop
         {                                                                 
                        // Если инстр. Следование_За_Объектом на BuyStop не установлен
         if( NormalizeDouble(Instrument[i][1][11][0],1)< 1.0 )
            // i  = индекс ордера
            // 1  = индекс ордерной линии (OR)
            // 11 = индекс инструмента Следование_За_Объектом
            // 0  = признак установки инструмента
            // 1.0= инструмент установлен (0.5=подготовлен для настройки на линию, 
            //                             0.0 = не установлен)(Нормализация до 1 знака)
            {
            int Tm = 12*60*60;// Смещение по времени, здесь - время до середины канала
                        // (смещение считается от текущего времени, поэтому инструмент..
                        // ..может "самопроизвольно" смещаться вправо в момент,..
                        // ..не совпадающий со временем образования 0 бара;это нормально)
            Ticket = NormalizeDouble(Order[i][4],0);
                        // Устанавливаем Инструмент 11, Следование_За_Объектом
            AG_Set_Instr(Manager, 11, Tm, 0, 13, 5, k, 0, Ticket, 1);
            // 11 = индекс инструмента
            // Tm = время смещения от настоящего момента, сек
            // 0  = параметр отсутствует
            // 13 = дистанция преследования 
            // 5  = шаг модификации
            // k  = индекс объекта в массиве Object[0] 
            // 0  = индекс линии объекта (RegLine = 32, UpLine=0, DnLine=1)
            // Ticket  = номер ордера
            // 1  = индекс ордерной линии (OR=1)
            AG_Message(Message, "На BuyStop " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }
//--------------------------------------------------------------------------------- 11 --
      if (NormalizeDouble(Order[i][6],0) == 5)// Если тип ордера SellStop
         {                                                                 
                        // Если инстр. Следование_За_Объектом на SellStop не установлен
         if( NormalizeDouble(Instrument[i][1][11][0],1)< 1.0 )
            {
            Tm = 12*60*60;// Смещение по времени, здесь - время до середины канала
            Ticket = NormalizeDouble(Order[i][4],0);
                        // Устанавливаем Инструмент 11, Следование_За_Объектом
            AG_Set_Instr(Manager, 11, Tm, 0, -13, 5, k, 1,  Ticket, 1);    
            AG_Message(Message, "На SellStop " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }      
      }
//================================================================================= 12 ==
   return(1);           // Нормальный выход
// return(0);           // Функция АТ будет закрыта в приложении AutoGraf 4
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж Конец модуля жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 13 жж