Проект
AutoGraf 4

Краткая характеристика

Пуск и настройка
Сервисные функции
Управление ордерами
Инструменты
Настроечные параметры
Тестирование стратегий

История поддержки

Продукты
Распространение
Брокеры-партнёры
Для трейдеров
Ссылки
Форум

Пример 2. Стратегия AG_Strategy_Channal_Outside.

   

 

Данная стратегия предназначена для работы в канале стандартных отклонений на пробой.

Согласно стратегии ожидается, что рыночная цена пробивает границу канала стандартных отклонений. Профитным направлением движения цены считается направление от границы канала наружу.

Управляющие воздействия, реализуемые стратегией:
- установка канала стандартных отклонений;
- установка на канал инструмента 12 Тянуть_Объект;
- установка отложенных ордеров BuyStop и SellStop на верхнюю и нижнюю границы канала;
- установка на ордера инструментов 11 Следование_За_Объектом с целью поддержания ордеров вблизи границ канала.

 

Код стратегии.

Блок 0-1. В представленном примере стратегии используются импортируемые функции, содержащиеся в файле AG_Lib.ex4. Это функции, обслуживающие исполнение функции автоматической торговли AG_AT(). В общем случае использование этих функций не является обязательным, но настоятельно рекомендуется.

Библиотечные функции

Функция AG_Magic_Number() используется для вычисления MagicNumber. В приложении AutoGraf 4 принято правило, в соответствии с которым каждому ордеру может быть присвоено только уникальное значение MagicNumber. Это необходимо для успешной идентификации ордеров при переоткрытии и частичном закрытии.

Функция AG_Message() используется для записи текстов сообщений в массив Message[].

Функция AG_Set_Instr() используется для записи параметров устанавливаемых инструментов в массив Manager[][].

Функция AG_Delete_Instr() используется для записи удаляемых инструментов в массив Manager[][].

Блок 1-2. Заголовок функции AG_Srtategy_Channal_Outside содержит перечень параметров, через которые в тело функции передаются различные данные, характеризующие текущую ситуацию.

Входные и выходные параметры функции AG_AT( ).

Блок 2-3. При создании коммерческой версии стратегии исполнение основного кода выполняется в том случае, если пользователь правильно указал пароль к стратегии. Данный алгоритм обработки пароля предусматривает неограниченное использование стратегии на демо-счёте. В случае исполнения стратегии на реальном счёте выполняется анализ пароля. Здесь для примера представлен простой метод - правильным значением пароля является целое число, которое на 1 больше, чем номер реального счёта.

Если значение переменной Parol_S оказывается правильным, то управление передаётся в блок 3-4. Если же нет, то выводится сообщение о неправильном пароле и исполнение функции AG_Srtategy_Channal_Outside() заканчивается. При этом функция возвращает значение 0, которое воспринимается приложением AutoGraf 4 как указание на прекращение автоматического режима торговли.

Рассматриваемая стратегия распространяется бесплатно с открытым кодом, поэтому операторы этого блока закомментированы и управление всегда передаётся в блок 3-4, - начальный блок основного кода стратегии.

 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// AG_Srtategy_Channal_Outside.mq4                                    Пример стратегии 2. 
// Отложенные ордера BuyStop и SellStop по границам канала. 
// Профитное движение вовнутрь канала (пробой). 
// Используется при построении функции автоматической торговли для приложения 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_Outside(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_Outside ("+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 = Time[With/Period()];                    // Канал длиной 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 BStp = true; // Пока считаем, что никаких Buy в окне нет,  поэтому BuyStop  нужен
   bool SStp = 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)           // При любых баях считаем, ..
         BStp = false;                                      // ..что BuyStop нам не нужен
      if (Tip_Ord==1 || Tip_Ord==3 || Tip_Ord==5)           // При любых селах считаем,..
         SStp = false;                                      //..что SellStop нам не нужен
      }
//================================================================================== 9 ==
   int StopLevel = MarketInfo( Symbol(), MODE_STOPLEVEL);
   int STD = iStdDev(NULL,0,With,0,MODE_SMA,PRICE_CLOSE,0)/Point;
   int SL = 5*STD;
   if (SL < StopLevel)
      SL = StopLevel;
   int TP = 1*STD;
   if (TP < StopLevel)
      TP = StopLevel;
   double Price_Right = ObjectGet(My_Chan_Name, OBJPROP_PRICE2);// Правая коорд. канала
//--------------------------------------------------------------------------------- 10 --
   if (BStp == true && Ask < Price_Right+STD*Point)         //  BuyStop
      {
      double Price = NormalizeDouble(Price_Right+STD*Point,Digits);// Цена ордера
      if (Price < Ask + StopLevel*Point)                    // Проверка цены
         Price = Ask + StopLevel*Point;
      double SL_BS = NormalizeDouble(Price-SL*Point,Digits);// Проверка SL
      double TP_BS = NormalizeDouble(Price+TP*Point,Digits);// Проверка ТР
      MN = AG_Magic_Number();                               // Вычисл. MN (рекомендуется)
      OrderSend(Symbol(),OP_BUYSTOP,Lot,Price,Slip,SL_BS,TP_BS,Comm,MN);//  BuyStop
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
   if (SStp == true && Bid > Price_Right-STD*Point)         // SellStop
      {
      Price = NormalizeDouble(Price_Right-STD*Point,Digits);// Цена ордера
      if (Price > Bid - StopLevel*Point)                    // Проверка цены
         Price = Bid - StopLevel*Point;
      double SL_SS = NormalizeDouble(Price+SL*Point,Digits);// Проверка SL
      double TP_SS = NormalizeDouble(Price-TP*Point,Digits);// Проверка ТР
      MN = AG_Magic_Number();                               // Вычисл. MN (рекомендуется)
      OrderSend(Symbol(),OP_SELLSTOP,Lot,Price,Slip,SL_SS,TP_SS,Comm,MN);// SellStop
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
//================================================================================= 11 ==
   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 = 0; // Смещение по времени
                        // (смещение считается от текущего времени, поэтому инструмент..
                        // ..может "самопроизвольно" смещаться вправо в момент,..
                        // ..не совпадающий со временем образования 0 бара;это нормально)
            Ticket = NormalizeDouble(Order[i][4],0);
                        // Устанавливаем Инструмент 11, Следование_За_Объектом
            AG_Set_Instr(Manager, 11, Tm, 0, 0, 3, k, 0, Ticket, 1);
            // 11 = индекс инструмента
            // Tm = время смещения от настоящего момента, сек
            // 0  = параметр отсутствует
            // 0 = дистанция преследования 
            // 3  = шаг модификации
            // k  = индекс объекта в массиве Object[0] 
            // 1  = индекс линии объекта (RegLine = 32, UpLine=0, DnLine=1)
            // Ticket  = номер ордера
            // 1  = индекс ордерной линии (OR=1)
            AG_Message(Message, "На BuyStop " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }
//--------------------------------------------------------------------------------- 12 --
      if (NormalizeDouble(Order[i][6],0) == 5)// Если тип ордера SellStop
         {                                                                 
                        // Если инстр. Следование_За_Объектом на SellStop не установлен
         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, 1,  Ticket, 1);    
            AG_Message(Message, "На SellStop " + Ticket+ " ");//Сообщение(макс 62сим)
            AG_Message(Message, "устанавливается инструмент Следование_За_Объектом.");
            }
         }      
      }
//================================================================================= 13 ==
   return(1);           // Нормальный выход
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж Конец модуля жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 14 жж
 

В блоке 3-4 инициализированы некоторые переменные. Для удобства пользования значения настроечных параметров присвоены простым переменным с интуитивно понятными названиями (см. комментарии к коду). В данной стратегии используются два параметра из числа настраиваемых параметров приложения AutoGraf 4 - Lot и Slip.

В общем случае количество лотов для устанавливаемых ордеров может вычисляться и в коде стратегии. В данном случае полагается, что стратегия используется по усмотрению пользователя, который и должен установить количество лотов вручную в приложении AutoGraf 4 (количество лотов в приложении AutoGraf 4 может быть вычислено на основании собственно количества лотов, либо на основании значения %, по выбору пользователя). Значение Slip также устанавливается пользователем в приложении AutoGraf 4. Оба указанные параметра передаются в функцию AG_AT (), а затем в рассматриваемую функцию (реализующую стратегию) через массив Tuning[].
 

Блоки 4-8. Здесь указан код, предназначенный для установки канала стандартных отклонений. Согласно стратегии никакие ордера не могут быть установлены или модифицированы до тех пор, пока не установлен требуемый графический объект - канал стандартных отклонений. Поэтому алгоритм установки канала указан в коде раньше, чем алгоритм управления ордерами.

Блок 4-6. В подавляющем большинстве случаев на момент включения стратегии на ценовом графике нет канала, требуемого по стратегии, его необходимо установить. После того, как канал установлен, на него необходимо установить инструмент 12 Тянуть_Объект.

Блок 4-5. В первых строках блока переменным Channal и Manage_12 присваивается значение Ложь, т.е. изначально предполагается, что канал не установлен и инструмент не установлен. Далее выполняются следующие вычисления. Если объект с заданным именем есть и тип этого объекта - канал стандартных отклонений, то переменной Channal присваивается значение Истина. Это означает, что в дальнейшем программа не будет пытаться установить канал, т.к. он есть.

Далее нужно вычислить, установлен ли на канал инструмент 12. Для этого необходимо перебрать все объекты, учитываемые в приложении AutoGraf 4, найти среди них объект с заданным именем и проверить установлен ли на него инструмент. Общее количество объектов, рассматриваемых в приложении AutoGraf 4, передаётся в функцию (реализующую стратегию) через элемент массива Object[0].

Поиск объекта с заданным именем выполняется в цикле по количеству объектов, рассматриваемых в приложении AutoGraf 4. Массив Object[] - это список названий рассматриваемых объектов. Интересующий результат - индекс искомого объекта в массиве Object[]. Массив Ddraw_Object[][] - это массив координат объектов, на которые установлены инструменты 12 Тянуть_Объект. Если обнаруживается, что учётный индекс объекта в массиве Object[] совпадает с учётным индексом одного из объектов массива Ddraw_Object[][], значит интересующий нас объект уже находится под управлением инструмента 12. Иными словами, на этот объект инструмент 12 уже установлен.

Отдельно нужно заметить, что значительная часть практически исполняемых действий для реализации стратегии осуществляется в результате исполнения инструментов. Инструменты - это алгоритмические примитивы, предназначенные для осуществления строго определённых действий и представляющие сервисный набор приложения AutoGraf 4. Пользователю, составляющему код стратегии, не нужно программировать инструменты. Его задача сводится к тому, чтобы установить нужный инструмент на нужный объект или ордер. Факт установки инструментов (независимо от способа установки - вручную или программно) распознаётся в приложении AutoGraf 4. Все установленные инструменты будут исполняться согласно заложенным в них алгоритмам.

Блок 5-6. Если же объект с заданным именем есть, но его тип другой (например, пользователь установил трендовою линию с таким именем), то управление передаётся в блок 5-6. В этом блоке для канала вычисляется новое имя путём прибавления к имени вычисляемого префикса. Перебор имён выполняется до тех пор, пока не будет найден незанятое имя. Оно и является вычисленным, т.е. тем именем, которое будет присвоено вновь открываемому каналу стандартных отклонений.

Блок 6-8. В случае, если требуемый канал стандартных отклонений не установлен, он устанавливается в блоке 6-7. Правая координата канала устанавливается на нулевой бар, левая координата - на 180 минут левее правой координаты (длина канала 3 часа задаётся в переменной With). Факт установки канала сопровождается сообщением и звуком.

Важным моментом в данном месте кода является обязательный возврат управления в приложение AutoGraf 4.

При программировании стратегий важно принять во внимание принципиальное правило технологии AutoGraf 4 - перед вызовом пользовательской функции AG_AT() все массивы в приложении AutoGraf 4 упорядочиваются. Это значит, что если в процессе работы с объектами пользователь какие-то объекты удалил или какие-то установил, то индексы массивов Object[] и Ddraw_Object[][] могут измениться. Поэтому, учитывая объекты в функции AG_AT() ни в коем случае нельзя связывать вычисления с какими бы то ни было конкретными численными значениями индексов, а искомые индексы необходимо вычислять при каждом исполнении функции AG_AT().

После установки любого объекта, а именно до того, как на этот объект будет установлен инструмент Тянуть_Объект, необходимо вернуть управление приложению AutoGraf 4 для упорядочивания массивов. Если этого не сделать, то невозможно правильно установить инструмент, т.к. индексы массивов Object[] и Ddraw_Object[][] ещё не изменены (т.е. вновь установленный объект ещё не учтён). После упорядочивания массивов приложение AutoGraf 4 снова вызовет на исполнение функцию AG_AT(). И только на этом этапе на канал можно устанавливать инструмент Тянуть объект. В общем случае возвращать управление в приложение AutoGraf 4 следует всякий раз при установке любых объектов и ордеров, а именно до выполнения любых других действий, связанных с ордерами, объектами и инструментами.

Блок 7-8. При последующем исполнении функции AG_AT() установленный объект будет правильно учтён в массивах Object[] и Ddraw_Object[][]. Это значит, что возможно исполнять часть программного кода, реализующую установку инструмента Тянуть объект. Если ранее вычислено, что инструмент ещё не установлен, то вызывается для исполнения функция AG_Set_Instr(). Среди параметров этой функции указывается индекс k, однозначно определяющий на какой именно объект устанавливается инструмент 12 Тянуть_Объект.

Блок 8-9. Здесь вычисляется необходимость установки отложенных ордеров. Согласно стратегии отложенные ордера устанавливаются, если других однонаправленных ордеров в текущий момент нет. Переменные BStp и SStp инициализируются значениями Истина, т.е. изначально считается, что устанавливать ордера нужно.

Данные обо всех установленных и открытых ордерах содержатся в массиве Order[][]. Значение элемента массива Order[0][0] равно общему количеству рыночных и отложенных ордеров. В цикле по количеству имеющихся ордеров выполняется анализ типа каждого ордера. Если в процессе анализа выясняется, что в терминале имеются ордера, то это означает, что однонаправленные ордера не должны устанавливаться. В этом случае значение соответствующей переменной (BStp или SStp) устанавливается равной Ложь.

Блок 9-11. Это блок операторов, в котором рассчитываются параметры ордеров и устанавливаются ордера.

В блоке 9-10 выполняются вычисления, относящиеся к ордерам обоих типов:
StopLevel - минимальная ограничивающая дистанция в пунктах. Отложенный ордер не может быть установлен ближе к рыночному курсу, чем на указанную дистанцию. Стоп-приказы отложенных ордеров также не могут быть приближены к ордеру ближе, чем на величину минимальной дистанции. Расчёт StopLevel необходимо выполнять в каждой программе (не только в данной стратегии, но и вообще в любой программе, формирующей торговые приказы - в экспертах и скриптах).
STD - значение индикатора стандартного отклонения, используемое в данной стратегии для расчёта дистанции от линии регрессии канала до линии верхней или нижней границы, в пунктах.
SL и ТР - значения StopLoss и  TakeProfit ордеров в пунктах от заявленной цены ордера.  Для данной стратегии значения SL и ТР рассчитываются в зависимости от значения STD и равны, соответственно, 5*STD  и 1*STD.
Price_Right - координата цены правой части линии регрессии (средней линии) канала стандартных отклонений.

В блоке 10-11 выполняются окончательные расчёты параметров и формируются торговые приказы на установку ордеров. Расчёт и установка ордера каждого типа выполняется в том случае, если значение переменной BStp или SStp равно Истина, т.е. если есть необходимость устанавливать ордер соответствующего типа. Кроме того, для открытия ордера требуется, чтобы рыночная цена находилась внутри канала. Эти условия для ордера BuyStop реализованы в строке:

 
if (BStp == true && Ask < Price_Right+STD*Point)         //  BuyStop
 

Заявленная цена отложенного ордера BuyStop рассчитывается на основании цены Price_Right и значения STD. Полученное значение цены совпадает с ценовой координатой крайней правой точки верхней границы канала. В общем случае в момент расчёта рыночная цена может находиться вблизи или выше рассчитанного значения. Поэтому выполняется обязательная проверка и уточняется новая (окончательная расчётная) заявляемая цена отложенного ордера BuyStop. Проверка значений SL и ТР выполнена в блоке 9-10, поэтому перед открытием ордера повторять проверку нет необходимости.

В соответствии с правилами языка MQL4 допускается использование одинаковых значений MagicNumber для нескольких ордеров. В приложении AutoGraf 4 принято правило, в соответствии с которым каждому ордеру может быть присвоено только уникальное значение MagicNumber. Требование этого правила связано со спецификой перенумерации ордеров в банках, а также при частичном закрытии ордеров. Иными словами, в конце банковского дня и в результате частичного закрытия ордерам присваиваются (на сервере) новые номера.

В случае, если в терминале открыто одновременно несколько однотипных ордеров, то после их перенумерации нельзя однозначно идентифицировать каждый ордер, т.е. определить на каком именно из ордеров были установлены те или иные инструменты. Персональный MagicNumber позволяет решить эту задачу в полной мере - MagicNumber ордеров не изменяется. В случае, если в разрез с указанным правилом пользователь допускает одинаковые MagicNumber для различных ордеров, работоспособность приложения AutoGraf 4 не гарантируется. Для вычисления MagicNumber рекомендуется использовать библиотечную функцию AG_Magic_Number().

Для того, чтобы в дальнейшем коде правильно идентифицировать ордер (на который будет установлен инструмент 11), необходимо упорядочить массив Order [][]. Это можно выполнить только одним способом - закончить исполнение функции AG_AT() (и прежде всего функции, реализующей стратегию) и вернуть управление в приложение AutoGraf 4.

В общем случае торговая операция может завершиться неудачей, поэтому в коде стратегии, предназначенном для практической работы, следует проанализировать успешность выполнения торговой операции и возвращать управление в приложение AutoGraf 4 только в том случае, если операция закончилась успешно. При неудаче следует проанализировать ошибку возврата сервера и принять новое решение (в большинстве случаев повторить торговый приказ). В данном примере такая задача не ставилась, для простоты полагается, что торговый приказ будет исполнен безусловно.

После того, как в приложении AutoGraf 4 будет выполнено упорядочивание массивов, снова будет вызвана на исполнение пользовательская функция AG_AT(). В случае неудачи управление всё равно возвращается в AutoGraf 4, и на следующей итерации (AutoGraf 4 вызывает функцию AG_AT() для исполнения прибл. от 20 до 500 раз в сек.) торговый приказ будет повторён.

Вычисления, касающиеся установки отложенного ордера SellStop, выполняются аналогично (в нижней части блока 10-11).

Блок 11-13. Согласно стратегии на каждый отложенный ордер должен быть установлен инструмент Следание_За_Объектом. Исполнение этой части стратегии реализовано в блоках 11-12 и 12-13. В общем случае пользователь может вручную установить несколько однонаправленных отложенных ордеров, тогда указанные инструменты будут установлены на все ордера BuyStop и SellStop. Для этой цели установка инструмента выполняется в цикле по количеству ордеров (общее количество ордеров в приложении AutoGraf 4 ограничено 30-ю).

Блок 11-12.  Инструмент Следание_За_Объектом устанавливается на все ордера типа BuyStop. Для выявления ордеров этого типа производится анализ всех имеющихся ордеров в цикле по i (обратите внимание, общее количество ордеров определено на основании значения элемента массива Order[0][0]). Если тип анализируемого ордера 2 (в соответствии с типами ордеров, принятыми в MQL 4), то выполняется проверка факта установки инструмента Следание_За_Объектом на этот ордер.

В отличие от большинства других ордерных инструментов факт установки инструмент Следание_За_Объектом характеризуется одним из трёх значений (0.0 - инструмент не установлен, 0.5 - инструмент подготовлен для установки и 1.0 - инструмент установлен). Для определения факта установки инструмента необходимо проанализировать значение элемента массива Instrument [][][][]:

 
         if( NormalizeDouble(Instrument[i][1][11][0],1)< 1.0)// Нормализация до 1 знака
 

Нормализацию значения элемента массива следует выполнить до первого знака. В противном случае, если инструмент закреплён на ордерной линии, но не связан ни с каким объектом, (т.е подготовлен для настройки, 0.5) он может быть ошибочно оценён как установленный. Установка инструмента выполняется, если состояние установки ордера меньше 1.0, т.е. если инструмент не установлен вообще (0.0) или установлен не до конца (подготовлен, 0.5).

В данном примере по стратегии инструмент Следание_За_Объектом устанавливается на крайней правой координате верхней линии канала стандартных отклонений. В соответствии с принятой стратегией, правая координата канала  удерживается вблизи нулевого бара (может отличаться от времени открытия нулевого бара на время таймфрейма, например, для М1 отличие может составлять не более 1 минуты). Смещение по времени инструмента 11 Следание_За_Объектом относительно текущего времени устанавливается равным нулю Tm = 0.

Для установки инструмента Следание_За_Объектом вызывается для исполнения функция AG_Set_Instr(), в параметрах которой указывается значение Ticket, вычисленное на основании значения элемента массива Order[i][4], где i - индекс ордера в массиве, а 4 - индекс элемента массива, содержащий номер этого ордера. Т.е. инструмент Следание_За_Объектом устанавливается на ордер BuyStop с конкретным номером. Установка инструмента сопровождается выводом двух строк сообщений. Подробно о параметрах инструмента 11 можно прочесть в разделе Следание_За_Объектом.

В блоке 12-13 написан аналогичный код для установки инструмента 11 Следание_За_Объектом на отложенные ордера типа SellStop.

После исполнения этих блоков управление передаётся в блок 13-14 и функция AG_AT() заканчивает работу.

В общем случае та или иная пользовательская стратегия может содержать и другие специальные условия управления ордерами. Например, стратегия может содержать блок закрытия ордеров, алгоритм установки графических объектов, использовать данные индикаторов, а также выполнять любые другие вычисления в соответствии с правилами языка MQL 4.

Исполнение стратегии.

Ниже представлено видео исполнения стратегии в тестере. Канал стандартных отклонений постоянно подтягивается вправо вслед за нулевым баром в результате исполнения инструмента 12 Тянуть_Объект. Отложенные ордера открываются на границах канала и удерживаются в непосредственной близости от границ исполняющимися инструментами 11 Следование_За_Объектом.
 

 

1. Установлен канал стандартных отклонений.

2. На канал установлен инструмент 12 Тянуть_Объект.

3. На границах канала установлены отложенные ордера BuyStop и SellStop.

4. На ордера установлены инструменты 11 Следование_За_Объектом.

5. Преобразование ордера SellStop в ордер Sell.

6. Преобразование ордера BuyStop в ордер Buy.
7. Закрытие ордера Buy по TakeProfit.

8. Установка отложенного ордера ордера BuyStop.

9. Закрытие ордера Sell по TakeProfit.

10. Установка отложенного ордера SellStop.

11. Преобразование ордера SellStop в ордер Sell.

12. Все действия пользователя и программы, а также события (открытие, закрытие, модификация) комментируются в подокне приложения и сопровождаются однозначно идентифицируемыми звуками (здесь не показано ввиду небольшого размера окна видео).

 

 

 

Copyright © SK 2006 - 2011