Проект
AutoGraf 4

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

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

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

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

Пример 1 (код функции AG_AT() для управления инструментами 1, 2, 6 и 7).

   

 

В примере рассматривается программный код функции AG_AT() для управления инструментами:

- Подтяжка вверх (1),

- Подтяжка вниз (2),

- Подтяжка не выше (6),

- Подтяжка не ниже (7).

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

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

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

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

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

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

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

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

 
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж
// AG_AT.mq4                                             Пример 1 (инструменты 1,2,6,7))
// Пользовательская функция Автоматической Торговли.
// Используется при построении функции автоматической торговли для приложения 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 "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%) суммы баланса
      Slip  = 1;        
      SL    = 100;      
      TP    = 25;       
      Ds    = 20;       
      St    = 3;        
/*
      Lot   = 2.5;            // Если количество лотов Lot (Tuning[1]) больше нуля, ..
      Per   = 0;              // .. то значение % (Tuning[2]) в приложении AutoGraf .. 
      Per   = 12;             // .. не принимается во внимание и будет пересчитано .. 
                              // .. независимо от значения переменной 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 ==
   int Crit = AG_Trade_Criterion_1(); // Вызов функции вычисления торговых критериев
   if (OrdersTotal()==0 && Crit == 10)// Открытых ордеров нет +сработал критерий откр Buy
      {
      AG_Message(Message, "АТ: сработал критерий открытия Buy.");// Пример сообщения
      MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)
                              // Открытие ордера Buy:
      Ticket = OrderSend( Symbol(),OP_BUY,Lot,Ask,2,Bid-SL*Point,Bid+TP*Point,Comm,MN); 
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
   if (OrdersTotal()==0 && Crit == 20)// Открытых ордеров нет+сработал критерий откр Sell
      {
      AG_Message(Message, "АТ: сработал критерий открытия Sell.");// Пример сообщения
      MN = AG_Magic_Number(); // Вычисление MagicNumber (рекомендуется)
                              // Открытие ордера Sell
      Ticket = OrderSend( Symbol(),OP_SELL,Lot,Bid,2,Ask+SL*Point,Ask-TP*Point,Comm,MN); 
      return(1);              // Открылись и отдаём управление AG для учёта ордеров
      }
//---------------------------------------------------------------------------------- 7 --
                              // Пример использования инструментов 1 и 2
                              // Если тип ордера Buy и критерий откр.Buy значим  
   if (NormalizeDouble(Order[1][6],0) == 0 && Crit == 10 && Ticket > 0) 
      {                       // .. и ордер только что установлен
                              // Если инстр. Подтяжка_Вверх на StopLoss не установлен
      if( NormalizeDouble(Instrument[1][2][1][0],0)==0.0 )
         // 1  = индекс ордера
         // 2  = индекс ордерной линии (SL)
         // 1  = индекс инструмента Подтяжка_Вверх
         // 0  = признак установки инструмента
         // 0.0= инструмент не установлен (1.0 = установлен)
         {
         AG_Set_Instr(Manager, 1, 15, 0, 78, 3, 0, 0, Ticket, 2);// Устанавливаем Инстр.1
         // 1  = индекс инструмента
         // 15 = индекс бара
         // 0  = параметр отсутствует
         // 78 = дистанция преследования
         // 3  = шаг модификации
         // 0  = параметр отсутствует
         // 0  = параметр отсутствует
         // Ticket  = номер ордера
         // 2  = индекс ордерной линии (SL=2)
         AG_Message(Message, "На StopLoss Buy " + Ticket+ " ");// Сообщение(макс.62 симв)
         AG_Message(Message, "устанавливается инструмент Подтяжка_Вверх.");// Сообщение
                              // Устанавливаем Инструмент 6 на тот же SL
         AG_Set_Instr(Manager, 6, 18, Order[1][2]+ 50*Point, 0, 0, 0, 0, Ticket, 2);
         // 6  = индекс инструмента
         // 18 = индекс бара (ну, понравился нам 18, а можно на любом, в т.ч. и -5 и -25)
         // Order[1][2]+ 50*Point  = на 50 пунктов выше заявленной цены StopLoss. 
         //                   Когда SL достигнет цели, инстр 1 и 6 авт. удаляются.
         // 0  = параметр отсутствует
         // 0  = параметр отсутствует
         // 0  = параметр отсутствует
         // 0  = параметр отсутствует
         // Ticket  = номер ордера
         // 2  = индекс ордерной линии (SL=2)
         Ticket = 0;    // Простой технический приём (чтоб не ставить инстр. многократно)
         }
      }
        // Если тип ордера Sell и критерий откр.Sell значим и ордер только что установлен
   if (NormalizeDouble(Order[1][6],0) == 1 && Crit == 20 && Ticket > 0) 
      {  
                        // Если Инстр. Подтяжка_Вниз на StopLoss не установлен
      if( NormalizeDouble(Instrument[1][2][2][0],0)==0.0 )
         {
         AG_Set_Instr(Manager, 2, 13, 0, 84, 3, 0, 0, Ticket, 2);// Устанавливаем Инстр 2
         AG_Message(Message, "На StopLoss Sell " + Ticket+ " ");//Сообщение(макс.62 симв)
         AG_Message(Message, "устанавливается инструмент Подтяжка_Вниз.");// Сообщение 
                        // Устанавливаем Инструмент 7 на тот же SL
         AG_Set_Instr(Manager, 7, 18, Order[1][2]- 50*Point, 0, 0, 0, 0, Ticket, 2);
         Ticket = 0;    // Простой технический приём (чтоб не ставить инстр. многократно)
         }
      }      
//---------------------------------------------------------------------------------- 8 --
   int TT = TimeCurrent();                // Текущее время
   int Tm_Cls = StrToTime("23:10");       // Абсолютное время удаления инструмента

   if (TT >= Tm_Cls)                      // Если сработало условие удаления инструмента
      {
      bool Sell = false;                  // Пока считаем, что ордеров Sell в окне нет
      int My_Ord = NormalizeDouble(Order[0][0],0); // Количество ордеров в нашем окне
      for (int i=1; i<=My_Ord; i++)                // По списку ордеров
         {
         if (NormalizeDouble(Order[i][6],0) == 1.0)// Попался ордер Sell
            Sell = true;
            break;                                 // Выносим индекс ордера i
         }
                                     // Если Sell есть и инстр.2 на StopLoss установлен:
      if(Sell == true && NormalizeDouble(Instrument[i][2][2][0],0)==1.0)
         // i  = индекс ордера
         // 2  = индекс ордерной линии (SL)
         // 2  = индекс инструмента Подтяжка_Вниз
         // 0  = признак установки инструмента
         // 1.0= инструмент установлен (0.0 = не установлен)
         {
         Ticket = Order[i][4];
         AG_Delete_Instr(Manager, 2, Ticket, 2);//Удаляем Инстр.2 со StopLoss ордера Sell
         // 2  = индекс инструмента             Для всех ордерных инструментов аналогично
         // Ticket  = номер ордера              При удалении инструментов 1,2,3,9,10 и 11  
         // 2  = индекс ордерной линии (SL=2)   автомат удаляются сопряжённые инстр 6 и 7
         AG_Message(Message, "Удаление инструмента Подтяжка_Вниз ");// Сообщение
         AG_Message(Message, "со StopLoss ордера Sell "+Ticket+".");// Сообщение
         Ticket = 0;    // Простой технический приём (чтоб не ставить инстр. многократно)
         }
      }
//================================================================================== 9 ==
   return(1);
   }
//жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж Конец модуля жжжжжжжжжжжжжжжжжжжжжжжжжжжжжжж 10 жж
 

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

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

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

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

Блок 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(). Подробнее о выводе сообщений:

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

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

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

Блок 7-8. Согласно принятой стратегии на StopLoss каждого рыночного ордера необходимо установить инструмент Подтяжка вверх (на Buy) или Подтяжка вниз (на Sell) с заданными параметрами дистанции Ds и шага модификации St.

В общем случае необходимо вычислить условия, при которых инструмент устанавливается на ордерную линию. В данном примере приняты простые условия - инструмент Подтяжка вверх устанавливается на StopLoss Buy, если тип ордера Buy, работает критерий открытия Buy, только что успешно закончилась торговая операция и на StopLoss данного ордера ещё не установлен инструмент Подтяжка вверх.

Тип ордера определяется  по значению элемента массива Order [1][6]. 1 - это номер ордера в общем списке ордеров массива Order [][]. В данном примере это всегда 1й ордер, т.к. здесь не допускается более одного ордера. В общем случае необходимо определить нужный ордер, анализируя значения элементов массива Order [][]. 6 - индекс массива, определяющий тип ордера.

В строке:

 
      if( NormalizeDouble(Instrument[1][2][1][0],0)==0.0 )
 

вычисляется факт установки инструмента Подтяжка вверх на StopLoss ордера Buy. Индексирование параметров инструментов подробно писано в разделе:

Массив Instrument [][][][].

Если инструмент Подтяжка вверх на StopLoss ордера Buy не установлен, то исполняется функция AG_Set_Instr(). Эта функция записывает параметры устанавливаемого инструмента в массив Manager[][]. По окончании исполнения функции AG_AT() этот массив будет прочитан в приложении AutoGraf 4 для установки инструментов.

Для вывода сообщения об установке инструмента Подтяжка вверх выводятся две строки сообщений.

Согласно принятой стратегии на ту же ордерную линию должен быть установлен инструмент Подтяжка не выше. Условия установки этого инструмента совпадают с условиями установки предыдущего инструмента, поэтому ещё раз вычислять условия нет необходимости.

По условиям установки инструмента Подтяжка не выше требуется, чтобы на этой же ордерной линии уже была установлена однонаправленная подтяжка.  Чтобы устанавливать инструмент Подтяжка не выше, инструмент Подтяжка вверх должен быть ранее установлен (любым способом).

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

В данном случае инструмент Подтяжка не выше устанавливается после установки инструмента Подтяжка вверх, поэтому в момент установки инструмента Подтяжка не выше инструмент Подтяжка вверх уже будет установлен. Для записи операции установки инструмента Подтяжка не выше в массив Manager[][] используется функция AG_Set_Instr().

Для правильного понимания соответствия значений параметров инструментов и индексов, используемых в массиве Manager[][], следует обратиться к описанию параметров инструментов в массивах Instrument [][][][] и Manager[][]:

Блок 8-9. Эта часть кода отвечает за удаление инструментов. Сначала необходимо вычислить условия, при которых это будет происходить. В данном примере вычисляется условие удаления всех инструментов Подтяжка вниз с ордера типа Sell.

Согласно принятой стратегии удаление инструментов выполняется при наступлении определённого времени. Если текущее время больше заданного (для примера задано 23:10), то выполняется необходимый анализ ордеров. Анализ ордеров необходим для того, чтобы определить, во-первых, существует ли ордер Sell, и во-вторых, для определения его индекса в массиве Order[][].

При составлении алгоритма пользовательской функции AG_AT() нет необходимости в написании кода для анализа ордеров. Весь необходимый набор данных содержится в массиве Order[][]. В общем случае может быть открыто несколько ордеров, поэтому необходимо опросить все ордера (а именно, проанализировать данные в мссиве Order[][]), чтобы найти ордер типа Sell. Общее количество ордеров учтено в элементе массива Order[0][0]. Вычисление индекса ордера типа Sell выполняется в цикле с количеством итераций, равным Order[0][0]. В этом цикле анализируется значение элемента Order[i][6], соответствующее типу ордера.

Как только ордер типа Sell найден (Order[i][6] == 1.0), цикл прерывается. Если ордер типа Sell найден и на StopLoss этого ордера установлен инструмент Подтяжка вниз, то управление передаётся на вызов функции AG_Delete_Instr(). При исполнении этой функции в массив Manager[][] записываются данные об удаляемом инструменте - номер инструмента, номер ордера и номер ордерной линии, на которой инструмент установлен. Этих данных достаточно, чтобы удалить конкретный инструмент.

Удаление инструмента сопровождается двумя строками сообщений.

Блок 9-10.

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

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

Если же функция AG_AT() возвращает значение 0, то это является указанием для приложения AutoGraf 4 отключить автоматический режим исполнения (управляющий значок AT будет переведен вниз). Это значит, что функция AG_AT() больше не будет вызываться для исполнения приложением AutoGraf 4 до тех пор, пока пользователь не установит автоматический режим (значок АТ вверх).

 

 

Copyright © SK 2006 - 2011