Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXII): Торговые классы - Основной торговый класс, контроль ограничений"

 

Опубликована статья Библиотека для простого и быстрого создания программ для MetaTrader (Часть XXII): Торговые классы - Основной торговый класс, контроль ограничений:

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

Чтобы проверить работу методов проверки ограничений торговли, нужно их искуственно создать.
Для примера:

  1. отключим интернет (эмулируем разрыв связи с торговым сервером),
  2. в настройках советника запретим ему торговать (нажмём F7 и в открывшемся окне настроек советника во вкладке "Общие" снимем флажок "Разрешить советнику торговать"),
  3. запретим в терминале автоторговлю (отожмём кнопку "Автоторговля")

И попробуем нажать на кнопку открытия позиции на торговой панели советника. В итоге получим запись в журнале:

2019.09.26 15:07:55.582 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:07:55.582 1. There is no permission to conduct trading operations in the terminal (the "AutoTrading" button is disabled)
2019.09.26 15:07:55.582 2. No connection to the trading server
2019.09.26 15:07:55.582 3. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Поочерёдно устраним ограничения.

Включим интернет и при попытке открыть позицию получим:

2019.09.26 15:10:36.766 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:10:36.766 1. There is no permission to conduct trading operations in the terminal (the "AutoTrading" button is disabled)
2019.09.26 15:10:36.766 2. EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Разрешим в терминале автоторговлю нажав кнопку Авто-торговля, и при попытке открыть позицию получим:

2019.09.26 15:13:03.424 CTrading::OpenBuy: The request was rejected before being sent to the server due to:
2019.09.26 15:13:03.424 EA does not have permission to conduct trading operations (F7 --> Common --> "Allow Automatic Trading")

Нажмём F7 и в настройках советника разрешим ему торговать. При попытке открытия позиции получим открытую позицию:

2019.09.26 15:14:32.619 - Position is open: 2019.09.26 11:14:32.711 -
2019.09.26 15:14:32.619 EURUSD Opened 0.10 Buy #455179802 [0.10 Market-order Buy #455179802] at price 1.09441, Magic number 123
Остальные ограничения возможно проверить в тестере или на демо-счёте, создав ситуацию, при которой сработает одно из ограничений, например — ограничение по максимальному количеству отложенных ордеров на счёте.

Автор: Artyom Trishkin

 

Артём, мне надо получить свойства позиции в mql4 после её открытия или активации отложки. Индекс события нашёл как получить

ENUM_TRADE_EVENT engine.LastTradeEvent()

и вот в этот момент надо получить доступные свойства.

Даже enum нашёл, а как получить... что-то не нахожу.

 
Alexey Viktorov:

Артём, мне надо получить свойства позиции в mql4 после её открытия или активации отложки. Индекс события нашёл как получить

и вот в этот момент надо получить доступные свойства.

Даже enum нашёл, а как получить... что-то не нахожу.

Если последнее событие - открытие позиции? Нужно получить последнюю открытую позицию и доступ ко всем её свойствам? Верно?

Если так, то просто (без проверок результатов получения списка и объекта):


 
Спасибо, остальные глупые вопросы задам в личке, чтобы не пугать прохожих.)))
 

Чего-то стало получаться. Спасибо, очень полезная библиотека.

Следующий вопрос (не глупый): имеем два отложенных ордера. Получили событие по активации одного из них, потом активировался второй... И тут уже не происходит изменения события. Как сделать чтобы после получения события вернуть сторожа взад? Попробовал

last_event = WRONG_VALUE;
после обработки события, но получил ахинею...
 
Alexey Viktorov:

Чего-то стало получаться. Спасибо, очень полезная библиотека.

Следующий вопрос (не глупый): имеем два отложенных ордера. Получили событие по активации одного из них, потом активировался второй... И тут уже не происходит изменения события. Как сделать чтобы после получения события вернуть сторожа взад? Попробовал

после обработки события, но получил ахинею...

Тут неправильно у меня идёт контроль событий. Библиотека их все отлавливает, то в тестовом советнике проверяется отличие прошлого события с текущим. А у тебя два одинаковых события произошли.

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

Но у меня в планах уже давно записано, что торговые события нужно сделать так же, как и события символов или аккаунта - они просто возвращают флаг, что есть событие. А далее уже в программе смотрим что за событие. Уже для этого в советнике всё подготовлено, только для торговых событий стоит заглушка в функции советника OnDoEasyEvent(), потому что флаг ещё не возвращается - всё руки не дойдут:

//--- Обработка торговых событий
   else if(idx>TRADE_EVENT_NO_EVENT && idx<TRADE_EVENTS_NEXT_CODE)
     {
      event=EnumToString((ENUM_TRADE_EVENT)ushort(idx));
      int digits=(int)SymbolInfoInteger(sparam,SYMBOL_DIGITS);
     }
     
 
Artyom Trishkin:

Тут неправильно у меня идёт контроль событий. Библиотека их все отлавливает, то в тестовом советнике проверяется отличие прошлого события с текущим. А у тебя два одинаковых события произошли.

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

Но у меня в планах уже давно записано, что торговые события нужно сделать так же, как и события символов или аккаунта - они просто возвращают флаг, что есть событие. А далее уже в программе смотрим что за событие. Уже для этого в советнике всё подготовлено, только для торговых событий стоит заглушка в функции советника OnDoEasyEvent(), потому что флаг ещё не возвращается - всё руки не дойдут:

Вот уж точно, утро вечера мудренее... Если получено событие, в моём конкретном случае, то надо на него как-то отреагировать. В частности поставить ещё один отложенный ордер. Вот тебе и новое событие.

 
Нет, всё-таки надо сбрасывать флаг события.
 
Artyom Trishkin:

Тут неправильно у меня идёт контроль событий. Библиотека их все отлавливает, то в тестовом советнике проверяется отличие прошлого события с текущим. А у тебя два одинаковых события произошли.

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

Но у меня в планах уже давно записано, что торговые события нужно сделать так же, как и события символов или аккаунта - они просто возвращают флаг, что есть событие. А далее уже в программе смотрим что за событие. Уже для этого в советнике всё подготовлено, только для торговых событий стоит заглушка в функции советника OnDoEasyEvent(), потому что флаг ещё не возвращается - всё руки не дойдут:

Но ведь event это переменная доступная только в OnChartEvent, а в тестере она не обрабатывается.

Я хочу сделать что-то примерно так в OnTick():

//--- Если последнее торговое событие изменилось
 if(engine.LastTradeEvent() != last_event)
  {
   switch(last_event)
    {
     case TRADE_EVENT_PENDING_ORDER_PLASED :
      // вызвать соответствующую функцию
     break;
     case TRADE_EVENT_PENDING_ORDER_REMOVED :
      // вызвать соответствующую функцию
     break;
     case TRADE_EVENT_PENDING_ORDER_ACTIVATED :
      // вызвать соответствующую функцию
     break;
     case TRADE_EVENT_POSITION_OPENED :
      // вызвать соответствующую функцию
     break;
     case TRADE_EVENT_POSITION_CLOSED :
      // вызвать соответствующую функцию
     break;
     
     default :
      break;
    }
 
Alexey Viktorov:

Но ведь event это переменная доступная только в OnChartEvent, а в тестере она не обрабатывается.

Я хочу сделать что-то примерно так в OnTick():

Так вот после обработки события - в конце модуля проверки типа события, что у тебя в переменной last_event ? Вот её в советнике-то нужно сбрасывать. А не вызывать принудительно метод сброса последнего события библиотеки - она-то его как раз сама вызывает сразу же после отправки события на чарт и записи его в список событий.

 
Alexey Viktorov:

Но ведь event это переменная доступная только в OnChartEvent, а в тестере она не обрабатывается.

Я хочу сделать что-то примерно так в OnTick():

Обрати внимание на функцию тестового советника OnDoEasyEvent() - в ней идёт обработка всех событий библиотеки. И если хочется обрабатывать торговые события свитчем, то делай там.