Мастер MQL5: Как написать свой модуль сопровождения открытых позиций

MetaQuotes | 20 января, 2011


Введение

В MetaTrader 5 имеется достаточно мощный инструмент для быстрой проверки торговых идей. Это генератор торговых стратегий Мастера MQL5. Использование Мастера MQL5 для автоматического создания кода советников рассмотрено в статье "Мастер MQL5: Создание эксперта без программирования". Открытость системы генерации кода позволяет добавлять к стандартным свои собственные классы торговых сигналов, системы управления капиталом и модули трейлинга.

В данной статье рассмотрены принципы написания модулей сопровождения открытых позиций для их последующего использования при создании экспертов Мастером MQL5.

Эксперт, который создается Мастером MQL5, стоит на четырех столпах - четырех базовых классах:

Рисунок 1. Структура базового класса CExpert

Рисунок 1. Структура базового класса CExpert


Класс CExpert (или его наследник) является главным "двигателем"  торгового робота. Экземпляр класса CExpert содержит в себе по одному экземпляру классов CExpertSignal, CExpertMoney и CExpertTrailing (или их наследников):

  1. CExpertSignal  - является основой генератора торговых сигналов. Экземпляр наследника класса CExpertSignal, включенный в состав класса CExpert, основываясь на встроенных алгоритмах, предоставляет эксперту информацию о возможности входа в рынок, уровнях входа и установки защитных ордеров. Окончательно решение по совершению торговых операций принимает эксперт. О том, как написать модуль торговых сигналов, рассказано в статье "Мастер MQL5: Как написать свой модуль торговых сигналов".
  2. CExpertMoney - является основой системы управления капиталом и рисками. Экземпляр наследника класса CExpertMoney вычисляет объемы для открытия позиций и установки отложенных ордеров. Окончательное решение по объемам принимает эксперт. Принципы разработки модулей управления капиталом и рисками описаны в статье "Мастер MQL5: Как написать свой модуль управления капиталом и рисками".
  3. CExpertTrailing - является основой модуля сопровождения открытых позиций. Экземпляр наследника класса CExpertTrailing сообщает эксперту о необходимости модификации защитных ордеров позиции. Окончательное решение по модификации ордеров принимает эксперт.

Кроме того, членами класса CExpert являются экземпляры классов:

Далее по тексту, говоря "эксперт", мы будем подразумевать экземпляр класса CExpert или его наследника.

Более подробно класс CExpert и работа с ним будут рассмотрены в отдельной статье.


1. Базовый класс CExpertTrailing

Класс CExpertTrailing является основой модуля сопровождения открытых позиций. Для связи с "внешним миром" класс CExpertTrailing имеет набор публичных виртуальных методов:

Инициализация

 Описание

virtual Init

Инициализация экземпляра класса обеспечивает синхронизацию данных модуля с данными эксперта

virtual ValidationSettings

Проверка корректности установленных параметров

virtual InitIndicators

Создание и инициализация всех индикаторов и таймсерий, необходимых для работы генератора торговых сигналов

Сигналы модификации позиций

 

virtual CheckTrailingStopLong

Генерация сигнала модификации длинной позиции, с определением новой цены Stop-ордера

virtual CheckTrailingStopShort

Генерация сигнала модификации короткой позиции, с определением новой цены Stop-ордера


Описание методов

1.1. Методы инициализации

1.1.1 Init

Метод Init() автоматически вызывается сразу после присоединения экземпляра класса к эксперту. Переопределения метода не требуется.

virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);

1.1.2 ValidationSettings

Метод ValidationSettings()  вызывается из эксперта после установки всех параметров. Необходимо переопределить метод в случае наличия параметров настройки.

virtual bool ValidationSettings();

Переопределенный метод должен возвращать true, если все параметры корректны (пригодны для использования). Если хотя бы один из параметров неверный, метод должен возвращать false (дальнейшая работа невозможна).

Базовый класс CExpertTrailing не имеет устанавливаемых параметров, соответственно, метод базового класса, не выполняя никаких проверок, всегда возвращает true.

1.1.3 InitIndicators

Метод InitIndicators() осуществляет создание и инициализацию всех необходимых индикаторов и таймсерий. Вызывается из эксперта после установки всех параметров и успешной проверки их корректности. Необходимо переопределить метод в том случае, если генератор торговых сигналов использует в работе хотя бы один индикатор или таймсерию.

virtual bool InitIndicators(CIndicators* indicators);

Индикаторы и/или таймсерии должны использоваться через соответствующие классы Стандартной библиотеки. Указатели всех индикаторов и/или таймсерий должны быть добавлены в коллекцию индикаторов эксперта (указатель на которую передается в качестве параметра).

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

Базовый класс CExpertTrailing не использует индикаторов и таймсерий, соответственно, метод базового класса всегда возвращает true, не выполняя никаких действий.


1.2. Методы проверки сигнала модификации позиций

1.2.1 CheckTrailingStopLong

Метод CheckTrailingStopLong() производит генерацию сигнала модификации длинной позиции с определением новой цены ордера Stop Loss (а в случае необходимости и ордера Take Profit). Вызывается экспертом для определения необходимости модификации длинной позиции. Необходимо переопределить метод в случае, если предполагается генерация сигнала модификации длинной позиции.

virtual bool CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)

Метод должен реализовывать алгоритм проверки условия модификации длинной позиции. Если условие выполнилось, переменной sl (а в случае необходимости и переменной tp) должно быть присвоено соответствующее значение и метод должен вернуть true. Ссылки на переменные sl и tp передаются в качестве параметров. Если условие не выполнилось, метод должен вернуть false.

Базовый класс CExpertTrailing не имеет встроенного алгоритма генерации сигнала модификации длинной позиции, поэтому метод базового класса всегда возвращает false.

1.2.2 CheckTrailingStopShort

Метод CheckTrailingStopShort() производит генерацию сигнала модификации короткой позиции с определением новой цены ордера Stop Loss (а в случае необходимости и ордера Take Profit). Вызывается экспертом для определения необходимости модификации короткой позиции. Необходимо переопределить метод в случае, если предполагается генерация сигнала модификации короткой позиции.

virtual bool CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)

Метод должен реализовывать алгоритм проверки условия модификации короткой позиции. Если условие выполнилось, переменной sl (а в случае необходимости и переменной tp) должно быть присвоено соответствующее значение и метод должен вернуть true. Ссылки на переменные sl и tp передаются в качестве параметров. Если условие не выполнилось, метод должен вернуть false.

Базовый класс CExpertTrailing не имеет встроенного алгоритма генерации сигнала модификации короткой позиции, поэтому метод базового класса всегда возвращает false.


2. Пишем свой модуль сопровождения открытых позиций

Теперь, когда мы рассмотрели структуру базового класса CExpertTrailing, можно приступать к созданию собственного модуля сопровождения открытых позиций.

Как уже говорилось выше, класс CExpertTrailing представляет собой набор публичных виртуальных "веревочек" - методов, "подергав" за которые эксперт может узнать мнение модуля сопровождения открытых позиций по поводу необходимости модификации защитных ордеров.

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

Вторая наша задача (не менее важная) - сделать так, чтобы наш класс "увидел" Мастер MQL5. Но, обо всем по порядку.

2.1. Создание класса генератора торговых сигналов

Приступим.

Для начала создадим (например, при помощи того же Мастера MQL5) включаемый файл с расширением mqh.

Выберем в меню Файл пункт "Создать" (или комбинацией клавиш Ctrl+N) и укажем создание включаемого файла:


Рисунок 2. Создаем включаемый файл Мастером MQL5.

Следует отметить, что для того чтобы этот файл был потом "обнаружен" Мастером MQL5 как модуль сопровождения открытых позиций, его следует создать в папке Include\Expert\.

Для того чтобы не "мусорить" в Стандартной библиотеке, создадим свою папку Include\Expert\Trailing\MyTrailing а в ней файл SampleTrailing.mqh, указав эти параметры в Мастере МQL5:

Рисунок 3. Настройка расположения включаемого файла

Рисунок 3. Настройка расположения включаемого файла

В результате работы Мастера MQL5 получился шаблон:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2010
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

Далее следует исключительно "ручная" работа. Уберем лишнее и добавим необходимое (включаемый файл ExpertTrailing.mqh Стандартной библиотеки и пока пустое описание класса).

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Класс CSampleTrailing.                                           |
//| Назначение: Класс сопровождения открытых позиций.                |
//|             Является производным от класса CExpertTrailing.      |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
  };
//+------------------------------------------------------------------+

Теперь, необходимо определиться с алгоритмами.

За основу нашего модуля сопровождения открытых позиций возьмем следующий алгоритм: переносим Stop-ордер в безубыток если цена прошла в нужную сторону на указанное расстояние. Отразим это в нашем файле.

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Класс CSampleTrailing.                                           |
//| Назначение: Класс сопровождения открытых позиций                 |
//|             переносом Stop-ордера "в безубыток".                 |
//|             Является производным от класса CExpertTrailing.      |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
  };
//+------------------------------------------------------------------+

Определим, какие данные понадобятся для принятия решений о модификации защитных ордеров. В нашем случае, это прибыль модифицируемой позиции в пунктах.

Определим список параметров настройки нашего модуля сопровождения открытых позиций. Нам понадобится два параметра:

  1. Количество пунктов прибыли позиции, при котором мы будем предлагать перенести Stop-ордер "в безубыток",
  2. Уровень "безубытка", то есть сколько пунктов прибыли мы зафиксируем перенесенным Stop-ордером.

Параметры настройки модуля будут храниться в защищенных членах-данных класса. Доступ к настройке будет осуществляться через соответствующие публичные методы.

Отразим эти изменения в нашем файле:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Класс CSampleTrailing.                                           |
//| Назначение: Класс сопровождения открытых позиций                 |
//|             переносом Stop-ордера "в безубыток".                 |
//|             Является производным от класса CExpertTrailing.      |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // уровень пороговой прибыли
   int                m_stop_level;         // уровень безубытка

public:
   //--- методы установки параметров настройки
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
  };
//+------------------------------------------------------------------+

Для инициализации параметров настройки значениями по умолчанию, нам необходимо добавить конструктор класса.

Для проверки правильности настройки переопределим виртуальный метод ValidationSettings (согласно описанию базового класса).

Описание класса:

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
//+------------------------------------------------------------------+
//| Класс CSampleTrailing.                                           |
//| Назначение: Класс сопровождения открытых позиций                 |
//|             переносом Stop-ордера "в безубыток".                 |
//|             Является производным от класса CExpertTrailing.      |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // уровень пороговой прибыли
   int                m_stop_level;         // уровень безубытка

public:
                      CSampleTrailing();
   //--- методы установки параметров настройки
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- метод проверки параметров настройки
   virtual bool        ValidationSettings();
  };
//+------------------------------------------------------------------+

Реализация метода ValidationSettings():

//+------------------------------------------------------------------+
//| Проверка параметров настройки.                                   |
//| INPUT:  нет.                                                     |
//| OUTPUT: true-если настройки правильные, иначе false.             |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
  {
   if(!CExpertTrailing::ValidationSettings())
      return(false);
//--- а вдруг не вызывался метод Init
   if(m_symbol==NULL) return(false);
//--- проверка параметров
   if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": уровень пороговой прибыли должен быть больше уровня установки ордеров");
      return(false);
     }
//--- ok
   return(true);
  }

Все подготовительные работы выполнены.

Рассмотрим наши алгоритмы еще раз, более подробно.

1. Сигнал для модификации длинной позиции возникает тогда, когда выполнились следующие условия:

При этом предложим модифицировать защитный Stop-ордер позиции согласно настройке. Для этого мы переопределим виртуальный метод CheckTrailingStopLong и наполним его соответствующим функционалом.

2. Сигнал для модификации короткой позиции возникает тогда, когда выполнились следующие условия:

При этом предложим модифицировать защитный Stop-ордер позиции согласно настройке. Для этого мы переопределим виртуальный метод CheckTrailingStopShort и наполним его соответствующим функционалом.

Описание класса:

class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // уровень пороговой прибыли
   int                m_stop_level;         // уровень безубытка

public:
                      CSampleTrailing();
   //--- методы установки параметров настройки
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- метод проверки параметров настройки
   virtual bool       ValidationSettings();
   //--- методы генерации сигналов модификации позиций
   virtual bool       CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };

Реализация методов CheckTrailingStopLong и CheckTrailingStopShort:

//+------------------------------------------------------------------+
//| Проверка для модификации защитных ордеров длинной позиции.       |
//| INPUT:  position - указатель на объект-позицию,                  |
//|         sl       - ссылка для новой цены stop-ордера,            |
//|         tp       - ссылка для новой цены take-ордера.            |
//| OUTPUT: true-если условие выполнено, иначе false.                |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)
  {
//--- проверка указателя
   if(position==NULL) return(false);
//--- проверка параметра
   if(m_profit==0.0)  return(false);
//--- уже в безубытке?
   double open=position.PriceOpen();
   if(position.StopLoss()>=open) return(false);
//--- проверка прибыли
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+
//| Проверка для модификации защитных ордеров короткой позиции.      |
//| INPUT:  position - указатель на объект-позицию,                  |
//|         sl       - ссылка для новой цены stop-ордера,            |
//|         tp       - ссылка для новой цены take-ордера.            |
//| OUTPUT: true-если условие выполнено, иначе false.                |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)
  {
//--- проверка указателя
   if(position==NULL) return(false);
//--- проверка параметра
   if(m_profit==0.0)  return(false);
//--- уже в безубытке?
   double open=position.PriceOpen();
   if(position.StopLoss()<=open) return(false);
//--- проверка прибыли
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }

2.2. Создание описания созданного класса торговых сигналов для Мастера MQL5

Теперь перейдем к решению второй задачи. Наш модуль сопровождения открытых позиций должен "опознаваться" генератором торговых стратегий Мастера MQL5.

Первое необходимое условие мы выполнили: разместили файл там, где его "обнаружит" Мастер MQL5. Но этого мало. Мастер MQL5 должен не только "обнаружить" файл, но и "опознать" его. Для этого нам нужно добавить в исходный текст описатель класса для Мастера MQL5.

Описатель класса - это блок комментариев, составленный по определенным правилам.

Рассмотрим эти правила.

1. Блок комментариев должен начинаться строками:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |

2. Следующая строка - это текстовый описатель (то, что мы увидим в Мастере MQL5 при выборе сигнала) в формате "//| Title=<Текст> |". Если текст великоват для одной строки, следом за ней можно добавить еще одну (но не более). 

В нашем случае получится:

//| Title=Сигнал по пересечению цены и скользящей средней            |
//| со входом на откате                                              |

3. Дальше следует строка с указанием типа класса в формате "//| Type=<Тип> |". Поле <Тип> должно иметь значение Signal (кроме сигналов Мастер MQL5 знает и другие типы классов).

Пишем:

//| Type=Trailing                                                    |

4. Следующая строка в формате "//| Name=<Имя> |" - короткое имя сигнала (используется Мастером MQL5 для генерации уникальных имен глобальных переменных эксперта).

У нас будет:

//| Name=BreakEven                                                   |

5. Имя класса - важный элемент описания. В строке с форматом "//| Class=<ИмяКласса> |", параметр <ИмяКласса> должен совпадать с именем нашего класса:

//| Class=CSampleTrailing                                            |

6. Эта строка нами не заполняется, но присутствовать обязана (это ссылка на раздел справки):

//| Page=                                                    &nbsp;       |

7. Далее идут описания параметров настройки модуля.

Это набор строк (количество строк совпадает с количеством параметров настройки).

Формат каждой строки "//| Parameter=<ИмяМетода>,<ТипПараметра>,<ЗначениеПоУмолчанию> |".

Наш набор параметров будет выглядеть так:

//| Parameter=Profit,int,20                                          |
//| Parameter=StopLevel,int,0                                        |

8. Блок комментариев должен заканчиваться строками:

//+------------------------------------------------------------------+
// wizard description end

Добавим описатель в исходный код.

//+------------------------------------------------------------------+
//|                                               SampleTrailing.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| включаемые файлы                                                 |
//+------------------------------------------------------------------+
#include <Expert\ExpertTrailing.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Вывод позиции в безубыток                                  |
//| Type=Trailing                                                    |
//| Name=BreakEven                                                   |
//| Class=CSampleTrailing                                            |
//| Page=                                                            |
//| Parameter=Profit,int,20                                          |
//| Parameter=StopLevel,int,0                                        |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Класс CSampleTrailing.                                           |
//| Назначение: Класс сопровождения открытых позиций                 |
//|             переносом Stop-ордера "в безубыток".                 |
//|             Является производным от класса CExpertTrailing.      |
//+------------------------------------------------------------------+
class CSampleTrailing : public CExpertTrailing
  {
protected:
   int                m_profit;             // уровень пороговой прибыли
   int                m_stop_level;         // уровень безубытка

public:
                      CSampleTrailing();
   //--- методы установки параметров настройки
   void               Profit(int value)       { m_profit=value;     }
   void               StopLevel(int value)    { m_stop_level=value; }
   //--- метод проверки параметров настройки
   virtual bool       ValidationSettings();
   //--- методы генерации сигналов модификации позиций
   virtual bool       CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp);
   virtual bool       CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp);
  };
//+------------------------------------------------------------------+
//| Конструктор CSampleTrailing.                                     |
//| INPUT:  нет.                                                     |
//| OUTPUT: нет.                                                     |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
void CSampleTrailing::CSampleTrailing()
  {
//--- установка значений по умолчанию
   m_profit    =20;
   m_stop_level=0;
  }
//+------------------------------------------------------------------+
//| Проверка параметров настройки.                                   |
//| INPUT:  нет.                                                     |
//| OUTPUT: true-если настройки правильные, иначе false.             |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::ValidationSettings()
  {
   if(!CExpertTrailing::ValidationSettings())
      return(false);
//--- а вдруг не вызывался метод Init
   if(m_symbol==NULL) return(false);
//--- проверка параметров
   if((m_profit-m_stop_level)*m_adjusted_point<=m_symbol.StopsLevel()*m_symbol.Point() && m_profit!=0.0)
     {
      printf(__FUNCTION__+": уровень пороговой прибыли должен быть больше уровня установки ордеров");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+
//| Проверка для модификации защитных ордеров длинной позиции.       |
//| INPUT:  position - указатель на объект-позицию,                  |
//|         sl       - ссылка для новой цены stop-ордера,            |
//|         tp       - ссылка для новой цены take-ордера.            |
//| OUTPUT: true-если условие выполнено, иначе false.                |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopLong(CPositionInfo* position,double& sl,double& tp)
  {
//--- проверка указателя
   if(position==NULL) return(false);
//--- проверка параметра
   if(m_profit==0.0)  return(false);
//--- уже в безубытке?
   double open=position.PriceOpen();
   if(position.StopLoss()>=open) return(false);
//--- проверка прибыли
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(m_symbol.Bid()-open>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open+m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+
//| Проверка для модификации защитных ордеров короткой позиции.      |
//| INPUT:  position - указатель на объект-позицию,                  |
//|         sl       - ссылка для новой цены stop-ордера,            |
//|         tp       - ссылка для новой цены take-ордера.            |
//| OUTPUT: true-если условие выполнено, иначе false.                |
//| REMARK: нет.                                                     |
//+------------------------------------------------------------------+
bool CSampleTrailing::CheckTrailingStopShort(CPositionInfo* position,double& sl,double& tp)
  {
//--- проверка указателя
   if(position==NULL) return(false);
//--- проверка параметра
   if(m_profit==0.0)  return(false);
//--- уже в безубытке?
   double open=position.PriceOpen();
   if(position.StopLoss()<=open) return(false);
//--- проверка прибыли
   sl=EMPTY_VALUE;
   tp=EMPTY_VALUE;
   if(open-m_symbol.Ask()>m_profit*m_adjusted_point)
      sl=m_symbol.NormalizePrice(open-m_stop_level*m_adjusted_point);
//---
   return(sl!=EMPTY_VALUE);
  }
//+------------------------------------------------------------------+

Ну, вот и все. Модуль трейлинга готов к использованию.

Для того чтобы генератор торговых стратегий Мастера MQL5 смог использовать наш модуль, нужно перезапустить MetaEditor (Мастер MQL5 сканирует папку Include\Expert только при загрузке).

После перезапуска MetaEditor созданный модуль управления открытыми позициями можно использовать в Мастере MQL5:

Рисунок 5. Созданный модуль управления открытыми позициями в Мастере MQL5

Рисунок 5. Созданный модуль управления открытыми позициями в Мастере MQL5

Входные параметры, указанные в разделе описания параметров модуля управления открытыми позициями стали доступными:

Рисунок 6. Входные параметры созданного модуля управления открытыми позициями в Мастере MQL5

Рисунок 6. Входные параметры созданного модуля управления открытыми позициями в Мастере MQL5

Наилучшие значения входных параметров реализованной торговой стратегии могут быть найдены при помощи Тестера стратегий терминала MetaTrader 5.


Заключение

Генератор торговых стратегий Мастера MQL5 значительно упрощает проверку торговых идей. В основе кода сгенерированного эксперта лежат классы торговых стратегий Стандартной библиотеки, на базе которых строятся конкретные реализации классов торговых сигналов, классов управления капиталом и рисками и классов сопровождения позиций. 

В статье рассказывается о том, как написать и подключить в генератор торговых стратегий Мастера MQL5 свой собственный класс модуля  управления открытыми позициями, устанавливающего уровень Stop Loss в безубыток при движении цены в направлении позициии, что позволяет уменьшить просадки при торговле, рассматривается структура и формат описания созданного класса для Мастера MQL5.