OnTradeTransaction вызывается по несколько раз на операцию с разными значениями параметров.

 

У меня стоит задача: в момент открытия \ закрытия  \ обновления (sl, tp) позиции и отправлять по http (тут заменено на печать для упрощения) отчет. Для получения данных об изменении в списке позиций и их состоянии я использую OnTradeTransaction.

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result) {

    ulong ticket = trans.position;

    if(PositionSelectByTicket(ticket)) {

        string symbol = PositionGetString(POSITION_SYMBOL);

        string type = PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY ? "BUY" : "SELL";

        datetime openAt = (datetime) PositionGetInteger(POSITION_TIME_MSC);

        double volume = PositionGetDouble(POSITION_VOLUME);

        double stopLoss = PositionGetDouble(POSITION_SL);

        double takeProfit = PositionGetDouble(POSITION_TP);

        string comment = PositionGetString(POSITION_COMMENT);

        Print("symbol: ", symbol, " type: ", type, " openAt: ", openAt, " volume: ", volume);

    } else if(HistorySelectByPosition(ticket)) {

        ulong dealTicket = HistoryDealGetTicket(HistoryDealsTotal() - 1);

        double profit = HistoryDealGetDouble(dealTicket, DEAL_PROFIT);

        Print("profit: " + (string) profit);

    }

}

Проблема 1

При открытии так и при закрытии позиции вызов происходит много раз подряд. Бомбардировать сервер по 10 запросов на каждый вызов  OnTradeTransaction не хорошая идея.

Проблема 2

При закрытии ордера 

else if(HistorySelectByPosition(ticket)) { ...

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


Может я выбрал не верный путь для решения этой задачи или как-то можно ограничить кол-во вызовов. Мне нужен один вызов на событие открытия позиции, один вызов на  любое обновление стопов, и один на закрытие с профитом и временем закрытия. Причем получить эти данные не тогда когда они будут в History а сразу в моменте. С какой стороны лучше зайти на эту задачу?

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Функции обработки событий - Функции - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Внимательно ознакомьтесь со структурой MqlTradeTransaction 

и в особенности с типом торговой транзакции type

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торговой транзакции
  • www.mql5.com
Структура торговой транзакции - Структуры данных - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 

Не забыть, что один ордер может породить несколько сделок.

А так же то, что ордера может уже не быть в активных и ещё не быть в истории.

 
Alexey Viktorov #:
Внимательно ознакомьтесь со структурой MqlTradeTransaction 

и в особенности с типом торговой транзакции type

А зачем читать?

 
prostotrader #:

А зачем читать?

Не знаю. Может потому, что я читал? Да и вы наверное тоже…

 
Alexey Viktorov #:

Не знаю. Может потому, что я читал? Да и вы наверное тоже…

Читал конечно.

 
Alexey Viktorov #:
Внимательно ознакомьтесь со структурой MqlTradeTransaction 

и в особенности с типом торговой транзакции type

Посмотрел на первый взгляд кажется что все логично, при проверке:

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result) {

    ulong ticket = trans.position;

    if(trans.type == TRADE_TRANSACTION_ORDER_ADD) { // Приходит при открытии ордера 1 раз и при закрытии 1 раз

        Print("TRADE_TRANSACTION_ORDER_ADD");

    }

    if (trans.type == TRADE_TRANSACTION_ORDER_UPDATE) { // Приходит при открытии ордера 2 раза и при закрытии 1 раз

        Print("TRADE_TRANSACTION_ORDER_UPDATE");

    }

    if (trans.type == TRADE_TRANSACTION_ORDER_DELETE) { // Приходит при открытии ордера 1 раз и при закрытии 1 раз  

        Print("TRADE_TRANSACTION_ORDER_DELETE");

    }

    if (trans.type == TRADE_TRANSACTION_DEAL_ADD) { // Приходит при открытии ордера 1 раз и при закрытии 1 раз

        Print("TRADE_TRANSACTION_DEAL_ADD");

    }

    if (trans.type == TRADE_TRANSACTION_DEAL_UPDATE) {

        Print("TRADE_TRANSACTION_DEAL_UPDATE");

    }

    if (trans.type == TRADE_TRANSACTION_DEAL_DELETE) {

        Print("TRADE_TRANSACTION_DEAL_DELETE");

    }

    if (trans.type == TRADE_TRANSACTION_HISTORY_ADD) { // Приходит при открытии ордера 1 раз и при закрытии 1 раз

        Print("TRADE_TRANSACTION_HISTORY_ADD");

    }

    if (trans.type == TRADE_TRANSACTION_HISTORY_UPDATE) {

        Print("TRADE_TRANSACTION_HISTORY_UPDATE");

    }

    if (trans.type == TRADE_TRANSACTION_HISTORY_DELETE) {

        Print("TRADE_TRANSACTION_HISTORY_DELETE");

    }

    if (trans.type == TRADE_TRANSACTION_POSITION) {

        Print("TRADE_TRANSACTION_POSITION");

    }

    if (trans.type == TRADE_TRANSACTION_REQUEST) { // Приходит при открытии ордера 2 раза и при закрытии 1 раз

        Print("TRADE_TRANSACTION_REQUEST");

    }

}
Не понятно как при таком раскладе отличить открытие от закрытия.
 
Павел Раввич #:

Посмотрел на первый взгляд кажется что все логично, при проверке:

Не понятно как при таком раскладе отличить открытие от закрытия.

Проблема известная - с этой структурой событий  OnTradeTransaction команда разработчиков MQ давно кошмарит все сообщество алго-трейдеров.

Причем если разобраться по сути, проблема даже не в количестве передаваемых событий, а в том что событие TRADE_TRANSACTION_HISTORY_ADD НЕ СОДЕРЖИТ всей полноты информации по позиции т.е. не заполнено большое количество нужных и важных полей(Тип, Магик, Комментарий и пр.), которые в реальности затем отражаются в закладке "History" - хотя  было бы вполне логично и удобно видеть там 1:1 соответствие информации.

Предлагаю прокачать эту тему и потребовать от разработчиков MQ включить в следующий релиз необходимые доработки и обеспечить передачу в событии TRADE_TRANSACTION_HISTORY_ADD всей полноты информации.

OnTradeTransaction - Используйте отложенные ордера.
OnTradeTransaction - Используйте отложенные ордера.
  • 2016.12.04
  • www.mql5.com
Используются ли другие ордера во время жизни позиции. Вот поэтому-то я и рекомендовал использовать отложенные ордера. торговое окружение может не соответствовать реальности. при исполнении отложенного ордера на несколько миллисекунд его может нигде не быть
 
Павел Раввич #:

Посмотрел на первый взгляд кажется что все логично, при проверке:

Не понятно как при таком раскладе отличить открытие от закрытия.
if (trans.type == TRADE_TRANSACTION_DEAL_ADD) { // Приходит при открытии ордера 1 раз и при закрытии 1 раз

Такой тип транзакции проходит не при открытии ордера, а при совершении сделки. При совершении сделки на открытие позиции и при совершении сделки на закрытие позиции…

Дальше можно проверить есть-ли позиция среди открытых. Или просто среди сделок прочесть направление сделки.

Опять приходится читать документацию. Не переписывать-же её сюда…

 
prostotrader #:

Читал конечно.

Я сегодня прочёл две темы, названия начинаются [Предложение] и понял, что не всем можно читать документацию. В некоторых случаях это чтение сводит с ума.

 
Alexey Viktorov #:

Я сегодня прочёл две темы, названия начинаются [Предложение] и понял, что не всем можно читать документацию. В некоторых случаях это чтение сводит с ума.

:))
Причина обращения: