2. Тестирование стратегий


Приложение AutoGraf 4 исполняется в тестере MetаTrader 4 в режиме визуализации.

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

Пример простой пользовательской функции автоматической торговли AG_AT().

 

//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// AG_AT.mq4                                             Пример 0 (инструментов нет)
// Пользовательская функция Автоматической Торговли.
// Используется при построении функции автоматической торговли для приложения 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[]
#import "AG_Trade_Criterion.ex4"
   int AG_Trade_Criterion_1();                     // Ф-ия определен. торгов. критериев 1
   int AG_Trade_Criterion_2();                     // Ф-ия определен. торгов. критериев 2
#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%) суммы баланса
      Ds    = 20;       
      St    = 3;        
*/
      Slip  = 1;        
      SL    = 100;      
      TP    = 25;       

      Lot   = 0.1;            // Если количество лотов Lot (Tuning[1]) больше нуля, ..
      Per   = 0;              // .. то значение % (Tuning[2]) в приложении AutoGraf .. 
                              // .. не принимается во внимание и будет пересчитано .. 
                              // .. независимо от значения переменной Per (Tuning[2]).
/*
      Lot   = 0.0;            // Если количество лотов Lot (Tuning[1]) в приложении ..
      Per   = 7;              // .. AutoGraf требуется вычислять на основе  ..
                              // .. заданного значения % (Tuning[2]),.. 
                              // .. то значение Lot (Tuning[1]) необходимо обнулить. 
*/
//---------------------------------------------------------------------------------- 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 ==
                                       // Пример 1. Используются Lot, SL и ТР из AutoGraf
   int Crit = AG_Trade_Criterion_1();  // Вызов функции вычисления торговых критериев
   if (OrdersTotal()==0 && Crit == 10) // Открытых ордеров нет + есть критерий откр. Buy
      {
      AG_Message(Message, "АТ: сработал критерий открытия Buy.");//Сообщение(макс.62симв)
      MN = AG_Magic_Number();          // Вычисление MagicNumber (рекомендуется)
                                       // Открытие ордера Buy:
      OrderSend( Symbol(), OP_BUY, Lot, Ask, 2, Bid-SL*Point, Bid+TP*Point, Comm, MN); 
      }
   if (OrdersTotal()==0 && Crit == 20) // Открытых ордеров нет + есть критерий откр. Sell
      {
      AG_Message(Message, "АТ: сработал критерий открытия Sell.");//Сообщение(макс62симв)
      AG_Message(Message, "АТ: пример второго сообщения подряд.");//Сообщение(макс62симв)
      MN = AG_Magic_Number();          // Вычисление MagicNumber (рекомендуется)
                                       // Открытие ордера Sell:
      OrderSend( Symbol(), OP_SELL, Lot, Bid, 2, Ask+SL*Point, Ask-TP*Point, Comm, MN); 
      }
//================================================================================== 7 ==
/*
                                       // Cнять блок комментариев с Примера 2
                                       // и закомментировать Пример 1
                                       // Пример 2. Открытие и закрытие рыночных ордеров.
   int Crit = AG_Trade_Criterion_2();  // Вызов функции вычисления торговых критериев
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   if (OrdersTotal()==0)               // Если нет ордеров, то интересуемся ..
      {                                // .. критериями открытия
      switch(Crit)                     // В этом блоке рассматриваются критерии открытия
         { 
         case 10:                      // Торговый критерий = Открыть_Buy
            MN = AG_Magic_Number();    // Вычисление MagicNumber (рекомендуется)
                                       // Открытие ордера Buy:
            OrderSend(Symbol(),OP_BUY, 0.1,Ask,2,Bid-100*Point,Bid+40*Point,Comm,MN); 
            break;
         case 20:                      // Торговый критерий = Открыть_Sell
            MN = AG_Magic_Number();    // Вычисление MagicNumber (рекомендуется)
                                       // Открытие ордера Sell:
            OrderSend(Symbol(),OP_SELL,0.1,Bid,2,Ask+100*Point,Ask-40*Point,Comm,MN);
         }
      }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
   if (OrdersTotal()==1)               // По стратегии возможен только 1 рыночный ордер
      {
      switch(Crit)                     // В этом блоке рассматриваются критерии закрытия
         {
         case 11:                      // Торговый критерий = Закрыть_Buy
            if (NormalizeDouble(Order[1][6],0) == 0.0)            // Если тип ордера Buy
               {                                      
               int _Ord_Ticket = NormalizeDouble(Order[1][4],0);  // Номер ордера
               double _Ord_Lots = NormalizeDouble(Order[1][5],2); // Полное закрытие
               OrderClose(_Ord_Ticket, _Ord_Lots, Bid, 2);        // Закрыть ордер Buy
               }
            break;
         case 21:                      // Торговый критерий = Закрыть_Sell
            if (NormalizeDouble(Order[1][6],0) == 1.0)      // Если тип ордера Sell
               {
               _Ord_Ticket = NormalizeDouble(Order[1][4],0);// Номер ордера
               _Ord_Lots = NormalizeDouble(Order[1][5],2);  // Будем закр.ордер полностью
               OrderClose(_Ord_Ticket, _Ord_Lots, Ask, 2);  // Закрыть ордер Sell
               }
         }
      }
*/
//================================================================================== 8 ==
   return(1);
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж Конец модуля жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 10 жж

 
 

В коде используются импортируемые функции, содержащиеся в файлах AG_Lib.ex4 и AG_Trade_Criterion.ex4.

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

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

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

Файл AG_Trade_Criterion.ex4 содержит пользовательские функции AG_Trade_Criterion_1() и AG_Trade_Criterion_2(), применяемые для определения критериев открытия, закрытия и модификации ордеров. Решение об использовании этих функций полностью зависит программиста. В случае, если торговые критерии определяются непосредственно в коде функции AG_AT(), то от использования этих функций можно отказаться.

Описание входных и выходных переменных функции AG_AT(), а также блок 2-3 подробно описаны в разделе:

В блоке 3-6 указаны новые значение настроечных параметров приложения AutoGraf 4. Подробно об этом здесь:

В блоке 4-5 указано значение количества лотов 0.1. Тестирование проводится при постоянном количестве лотов.

Основной код, реализующий торговую стратегию, указан в блоках 6-8.

Представленная функция автоматической торговли AG_AT() содержит два независимых примера, основанных на разных торговых критериях (соответственно, блоки 6-7 и 7-8). Тестирование следует проводить для одного из примеров, для этого необходимо закомментировать один из двух блоков (6-7 или 7-8), а другой оставить.

Пример 1. Блок 6-7.  Согласно стратегии приняты торговые критерии двух видов - на открытие ордера Buy и открытие ордера Sell. Критерии на закрытие и модификацию ордеров не вычисляются. Для вычисления торговых критериев используется вызов импортированной функции AG_Trade_Criterion_1().

Стратегия, реализованная в рассматриваемом примере, допускает одновременно только один рыночный ордер. В блоке 6-7 имеется две похожих группы операторов, в каждой из которых вычисляется условие для открытия ордера. Ордер Buy открывается при условии, что открытых ордеров нет и критерий открытия Buy является значимым. Во второй группе операторов выполняются аналогичные вычисления для открытия Sell.

Если условие открытия ордера сработало, то формируется торговый приказ на открытие ордера соответствующего типа. Перед исполнением функции открытия ордера вычисляется его MagicNumber. Замечания по вычислению MagicNumber смотрите здесь:

Обратите внимание, в торговом приказе заданы не численные значения StopLoss и TakeProfit, а значения переменных SL и ТР. Один раз в начале работы (при первом включении функции АТ) настроечные параметры SL и ТР были установлены в приложении AutoGraf  4 из функции AG_AT(). В ходе дальнейшей работы при каждом вызове на исполнение в функцию AG_AT() в массиве Tuning[] передаются текущие (последние известные) значения настроечных параметров. Эти значения считываются из массива Tuning[] (блок 5-6) и используются при открытии ордеров. Если пользователь изменит значения настроечных параметров в приложении AutoGraf 4, то изменятся и значения этих параметров в торговых приказах.

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

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

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

Пример 2. Блок 7-8. Аналогичные вычисления выполняются и в блоке 7-8. Разница состоит лишь в том, что кроме критериев открытия здесь используются критерии для закрытия ордеров, а сами торговые критерии вычисляются в разных функциях (на основе различных исходных данных).

Запуск приложения на тестирование выполняется обычным способом. В тестере стратегий необходимо указать название тестируемого советника (в данном случае AG_exp.ex4), выбрать финансовый инструмент и модель, используемую для тестирования:

Некоторые настройки тестера перед тестированием функции AG_AT() приложения AutoGraf 4.
 

Результаты тестов Примера 1 и Примера 2 показаны ниже. В данном случае не ставилась задача представить алгоритм прибыльной стратегии. Здесь преследовалась цель показать, что технически осуществимо тестирование стратегий, закодированных на языке MQL 4 в пользовательскую функцию автоматической торговли приложения AutoGraf 4.

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

 

График баланса, полученный в результате тестирования Примера 1.

График баланса, полученный в результате тестирования Примера 2.