Как копировать сигналы с помощью советника по своим правилам?

10 июня 2016, 12:02
Vladimir Karputov
20
4 752

Оглавление

 

Предупреждение о рисках

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

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

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

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

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

Представленный в данной статье советник-помощник по копированию торговых сигналов можно бесплатно загрузить из Маркета:


1. Подготовка

Перед началом работы просмотрите, пожалуйста, обучающие видеоролики:

  1. Выбор торгового сигнала
  2. Подписка на сигнал
  3. Аренда вирутального хостинга
  4. Миграция подписки и советника на виртуальный хостинг


1.1. Идея копировщика

Копировщик работает на виртуальном хостинге, на торговом счёте, который подписан на сигнал. Главная его задача — это увеличивать позиции, которые открывает сервис "Сигналы", в заданное количество раз. На рис. 1 представлена идея копировщика, который прикреплён к хеджевому счёту:


Рис. 1. Идея копировщика на хеджинговом счёте

Рис. 2 демонстрирует идею работы копировщика на торговом счёте с неттинговым учётом позиций:

 

Рис. 2 Идея копировщика на неттинговом счёте 

Таким образом, как только сервис "Сигналы" успешно совершает сделку на счёте подписчика, копировщик сразу же совершает сделку, объём которой определяется по формуле:

(объём сделки совершённой сервисом "Сигналы") * "Deal multiply by"

Параметр "Deal multiply by" отвечающий за то, во сколько именно раз необходимо увеличивать сделки, задаётся во входных параметрах:

inputs

Рис. 3. Входные параметры 

При работе на неттинговом торговом счёте в MetaTrader 5 действия копировщика приводят к увеличению объёма скопированной позиции. На хеджинговом торговом счёте в MetaTrader 5 действия копировщика приводят к открытию новой позиции с увеличенным объёмом. Ниже представлен пример работы копировщика для неттингового и хеджевого счетов MetaTrader 5 при выбранном параметре увеличения сделок "Deal multiply by" равном 5 :

Действия сервиса "Сигналы" Действие копировщика на
хеджевом счёте
Действие копировщика на
неттинговом счёте
Скопирована сделка BUY EURUSD 0.01 лот Открыта новая позиция BUY EURUSD 0.05 лот — таким образом, у подписчика две позиции BUY EURUSD 0.01 лот и BUY EURUSD 0.06 лот Открыта сделка BUY EURUSD 0.05 лот — таким образом, у подписчика позиция BUY EURUSD 0.06 лот

 

2. Особенности сервиса "Сигналы"

2.1. Свой — чужой

Так как копировщик отслеживает все сделки, которые проводит сервис "Сигналы", то нужно знать некоторые особенности работы сервиса "Сигналы". Например, этот сервис сопровождает только "свои" позиции — те, которые были скопированы через сервис.

Сервис "Сигналы", при удачном открытии позиции у подписчика, прописывает в комментарии к сделке название сигнала, который был скопирован, а в поле Magic Number сделки — уникальный идентификатор.

Впоследствии, при последующих синхронизациях подписки, именно по этому идентификатору и происходит распознание сделки, открытой через сервис "Сигналы".

Вот как выглядит комментарий для сделки BUY 0.01 EURUSD, которая была скопирована с сигнала "Test3443431", если во вкладке "История" окна "Инструменты"  навести мышку на скопированную сделку:

 subscriber tab history

Рис. 4. Комментарий скопированной сделки (вкладка "История")

Здесь на рисунке:

  1. "#69801797" — тикет сделки;
  2. "Test3443431" — название сигнала с которого была скопирована эта сделка;
  3. "361104976048745684" — Magic Number — идентификатор сделки.

Во вкладке "Торговля"  видно, что текущая позиция у подписчика имеет то же описание, только без тикета:

subscriber tab trade

Рис. 5. Комментарий скопированной сделки (вкладка "Торговля")

Иными словами, сервис "Сигналы" ведёт учёт позиций на стороне подписчика через поле Magic Number сделки. Учтённые позиции будут опознаны как "свои". И только над "своими" позициями сервис "Сигналы" может проводить подобные торговые действия: изменить объём позиции или закрыть позицию.

Неучтённые позиции будут опознаны как "чужие". Над такими позициями сервис "Сигналы" не властен.

2.2. Подменять Magic Number или не подменять?

В терминале MetaTrader 5 можно подключать и хеджевый, и неттинговый торговый счёт подписчика. В зависимости от типа подключённого счёта поведение копировщика в вопросе подмены Magic Number у скопированной позиции будет кардинально отличаться. Чтобы ответить на этот вопрос, рассмотрим следующий рисунок:


Рис. 6. Неттинговый счёт, без подмены Magic Number 

Как видно, на неттинговом счёте, копировщик увеличил позицию без подмены Magic Number — это привело к тому, что позиция стала "чужой" для сервиса "Сигналы". То есть,  работа копировщика на неттинговом счёте без подмены Magic Number — это ошибка. Значит, на неттинговом счёте копировщик при увеличении позиции должен всегда подменять Magic Number. А вот при работе на хеджевом счёте всё наоборот: с увеличением позиции копировщик должен подставлять свой Magic Number.

2.3. Что будет с "чужой" позицией, если провайдер закрывает позицию?

На примере хеджевого счёта: на торговый счёт подписчика была скопирована позиция BUY 0.01 EURUSD. Затем подписчик решил вмешаться в работу сервиса и открыл позицию BUY 0.01 EURUSD. Во время одной из ближайших синхронизаций сервис "Сигналы" выдал такую ошибку:

Signal  '3447880': local positions do not correspond to signal provider [#85639429 buy 0.04 EURUSD 1.11697]

То есть, позиция BUY 0.01 EURUSD, которую подписчик открыл вручную, была расценена сервисом "Сигналы" как "чужая". А теперь посмотрим, что будет, когда провайдер закроет свою позицию: сервис "Сигналы" также закроет "свою" позицию, а вот открытая вручную позиция BUY 0.01 EURUSD  так и останется в терминале. Кстати, о недопустимости ручного вмешательства в работу сервиса "Сигналы" прямо говорится в правилах:

IV. Подписка на Сигналы

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


3. Как выявить появление сделки

Выбор метода выявления возникновения сделки, с одной стороны, влияет на скорость реагирования копирования, а с другой — может привести к дополнительным финансовым расходам на оплату спреда при ошибочном открытии сделки с увеличенным объёмом.

Нужно помнить, что мы подписаны на сигнал, а это означает, что за торговыми событиями у провайдера сигнала следит сервис "Сигналы". В случае необходимости этот сервис откроет или закроет позицию/позиции. Любое открытие/закрытие позиции/позиций вызывает изменение торгового счёта подписчика. Именно это изменение мы и будем отслеживать, а проинформирует нас о нем событие OnTradeTransaction().

3.1. Отслеживание через OnTradeTransaction()

Почему выбор пал на OnTradeTransaction(), а не на OnTrade()? Потому что OnTradeTransaction() несёт в себе очень полезную информацию — тип торговой транзакции. Из всех возможных типов транзакций нас интересует только один:

TRADE_TRANSACTION_DEAL_ADD — добавление сделки в историю. Осуществляется в результате исполнения ордера или проведения операций с балансом счета.

То есть, копировщик ждёт момента, когда сделка будет добавлена в историю (а это гарантия совершения успешной торговой операции на счёте подписчика), и только потом начинает обрабатывать ситуацию. 


4. Когда подписка возможна, а когда нет

Подписка может быть успешной, только если оба счёта имеют одинаковую систему учёта:

Подписка Результат
Провайдер — неттинговый учет, подписчик — хеджинговый учёт

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

2016.05.11 11:15:07.086 Signal  '*******': subscribe to signal [*****] started
2016.05.11 11:15:07.141 Signal  '*******': subscription/renewal prohibited

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

Провайдер — хеджинговый  учет, подписчик — неттинговый учёт

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

2016.05.11 11:39:54.506 Signal  '*******': subscribe to signal [******] started
2016.05.11 11:39:54.560 Signal  '*******': subscription/renewal prohibited

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

Провайдер —  хеджинговый  учет, подписчик — хеджинговый  учёт Подписка удачная. 
Провайдер — неттинговый учет, подписчик — неттинговый учёт Подписка удачная. 

5. Храним информацию о копировании

Где лучше хранить информацию о проведённом копировании? И более глобальный вопрос — нужно ли вообще хранить такую информацию? В данной версии копировщика я решил хранить информацию о копировании в структуре. Объявление структуры:

//+------------------------------------------------------------------+
//| Structure of congruences of positions of the terminal and        |
//| positions of the copier                                          |
//+------------------------------------------------------------------+
struct correlation
  {
   long              POSITION_IDENTIFIER_terminal; // Position identifier (terminal)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   double            POSITION_VOLUME_terminal;     // Volume of the position opened by the Signals service
   long              POSITION_IDENTIFIER_copier;   // Position identifier (copier)
   //+------------------------------------------------------------------+
   //| Position identifier is a unique number that is assigned          |
   //| to every newly opened position and doesn't change during         |
   //| the entire lifetime of the position.                             |
   //| Position turnover doesn't change its identifier.                 |
   //+------------------------------------------------------------------+
   ulong             DEAL_ticket;                  // Deal ticket, if the deal is executed.
  };

В структуре всего четыре элемента:  

  1. "POSITION_IDENTIFIER_terminal" — в этом элементе хранится идентификатор позиции, которую открыл терминал (сервис "Сигналы")
  2. "POSITION_VOLUME_terminal" —  здесь хранится объём позиции, которую открыл терминал (сервис "Сигналы")
  3. "POSITION_IDENTIFIER_copier" — в этом элементе хранится идентификатор позиции, которую открыл копировщик
  4. "DEAL_ticket" — здесь записывается тикет сделки, которую открывает копировщик, если эта сделка закончилась удачей

Все действия копировщик проводит только из функции OnTradeTransaction, и только если тип торговой транзакции равен TRADE_TRANSACTION_DEAL_ADD. При выполнении этих условий мы всегда ищем сделку, которая породила данную транзакцию, и получаем ее параметры:

//+------------------------------------------------------------------+ 
//| TradeTransaction function                                        | 
//+------------------------------------------------------------------+ 
void OnTradeTransaction(const MqlTradeTransaction &trans,
                        const MqlTradeRequest &request,
                        const MqlTradeResult &result)
  {
//--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;
//--- if transaction is result of addition of the transaction in history
   if(type==TRADE_TRANSACTION_DEAL_ADD)
     {
      long     deal_entry        =0;
      double   deal_volume       =0;
      string   deal_symbol       ="";
      long     deal_type         =0;
      long     deal_magic        =0;
      long     deal_positions_id =0;
      string   deal_comment      ="";
      if(HistoryDealSelect(trans.deal))
        {
         deal_entry=HistoryDealGetInteger(trans.deal,DEAL_ENTRY);
         deal_volume=HistoryDealGetDouble(trans.deal,DEAL_VOLUME);
         deal_symbol=HistoryDealGetString(trans.deal,DEAL_SYMBOL);
         deal_type=HistoryDealGetInteger(trans.deal,DEAL_TYPE);
         deal_magic=HistoryDealGetInteger(trans.deal,DEAL_MAGIC);
         deal_positions_id=HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);
         deal_comment=HistoryDealGetString(trans.deal,DEAL_COMMENT);
         //if(deal_magic==0 && SignalInfoGetString(SIGNAL_INFO_NAME)!=HistoryDealGetString(trans.deal,DEAL_COMMENT))
         //   return;
        }
      else
         return;
...

В таблице, представленной ниже, показана логика работы копировщика на хеджевом и неттинговом счетах:

знак  означает, что в этот элемент структуры была сделана запись

знак  означает, что копировщик не вносил изменений в элементы структуры

Терминал POSITION_IDENTIFIER terminal POSITION_VOLUME terminal POSITION_IDENTIFIER copier deal_ticket
Хеджинг. Неттинг. DEAL_ENTRY_IN
Поиск по элементу структуры deal_ticket значения trans.deal.
Если совпадений нет: увеличиваем структуру на 1 ... 0 0 0 0
... и расцениваем как сделку сервиса — поэтому открываем позицию (DEAL_VOLUME * коэффициент), и еслиCTrade.ResultDeal() != 0, то записываем в элемент POSITION_IDENTIFIER_terminal значениеDEAL_POSITION_ID, значение CTrade.ResultDeal() записываем в элемент deal_ticket, а deal_volume — в POSITION_VOLUME_terminal. 0
Если находим – значит, это сделка, открытая копировщиком, поэтому записываем её DEAL_POSITOIN_ID в элемент POSITION_IDENTIFIER_copier.

Хеджинг. Неттинг. DEAL_ENTRY_OUT
Поиск DEAL_POSITION_ID в элементах структуры POSITION_IDENTIFIER_terminal и POSITION_IDENTIFIER_copier
Хеджинг.
... нашли DEAL_POSITION_ID...
... ... в элементе POSITION_IDENTIFIER_copier – ничего не делаем и выходим  ✔  ✔  ✔  ✔
... ... в элементе POSITION_IDENTIFIER_terminal –...  ✔  ✔  ✔  ✔
... ... ... эта позиция ещё существует? Если существует, то закрываем позицию, открытую копировщиком...  ✔  ✔  ✔  ✔
... ... ... ... открываем позицию (объём найденной позиции * коэффициент) и если CTrade.ResultDeal() != 0, то записываем значение CTrade.ResultDeal() в элемент deal_ticket.  ✔  ✔  ✔  ✔
... ... ... нет, эта позиция уже не существует. Закрываем позицию, открытую копировщиком.  ✔  ✔  ✔  ✔
Неттинг.
... нашли DEAL_POSITION_ID...
... ... в элементе POSITION_IDENTIFIER_terminal – (в структуре на данный момент, хранится прежний объём, открытый сервисом "Сигналы") рассчитываем новый объём и если CTrade.ResultDeal() != 0, то записываем значение CTrade.ResultDeal() в элемент deal_ticket.  ✔  ✔  ✔  ✔

Заключение

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

Внимание: файл копировщика "copier.mq5" и включаемый файл "languages.mqh" должны находиться в одной папке.


Прикрепленные файлы |
Languages.mqh (6.19 KB)
Copier.mq5 (38.06 KB)
Последние комментарии | Перейти к обсуждению на форуме трейдеров (20)
Aleksandr Volotko
Aleksandr Volotko | 9 май 2017 в 19:31
В Маркете исходник не отредактируешь..
Vladimir Karputov
Vladimir Karputov | 9 май 2017 в 19:39
Александр:
В Маркете исходник не отредактируешь..

Вы перепутали раздел - Вы сейчас в обсуждении статьи, где выложен открытый код. Внимательнее нужно быть.
Aleksandr Volotko
Aleksandr Volotko | 9 май 2017 в 20:06
А в Маркете советник, со ссылкой на статью, в ветке обсуждения которой мы сейчас находимся, работает по какому-то другому алгоритму что ли?
Vladimir Karputov
Vladimir Karputov | 9 май 2017 в 20:07
Александр:
А в Маркете советник, со ссылкой на статью, в ветке обсуждения которой мы сейчас находимся, работает по какому-то другому алгоритму что ли?

В Маркете есть ссылка на эту статью. Вы ползуете бесплатный продукт с открытым кодом. Какие у Вас претензии? Предлагаю Вам прекратить эти нападки.
Vladimir Karputov
Vladimir Karputov | 10 май 2017 в 10:26
Александр:
В Маркете исходник не отредактируешь..


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

А вот в Маркете, к сожалению, полный запрет ввести нельзя - продукт не пройдёт автовалидацию, поэтому в Маркете на неттинге будет только выскакивать предупреждающее сообщение (MessageBox).

Графические интерфейсы VII: Элементы "Таблицы" (Глава 1) Графические интерфейсы VII: Элементы "Таблицы" (Глава 1)

В седьмой части серии статей о графических интерфейсах в терминалах MetaTrader будут представлены три типа таблиц: таблица из текстовых меток, таблица из полей ввода и нарисованная таблица. Ещё один важный и часто используемый элемент управления — вкладки, с помощью которых можно скрывать и делать видимыми группы других элементов управления, что позволяет пользователю делать компактные графические интерфейсы в своих MQL-приложениях.

Создаем помощника в ручной торговле Создаем помощника в ручной торговле

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

Графические интерфейсы VII: Элементы "Вкладки" (Глава 2) Графические интерфейсы VII: Элементы "Вкладки" (Глава 2)

В первой главе седьмой части были представлены три класса элементов управления для создания таблиц: таблица из текстовых меток (CLabelsTable), таблица из полей ввода (CTable) и нарисованная таблица (CCanvasTable). В этой статье (второй главе) рассмотрим такой элемент интерфейса, как «Вкладки».

С чего начать при создании торгового робота для Московской биржи MOEX С чего начать при создании торгового робота для Московской биржи MOEX

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