Очерёдность приходящих транзакций - страница 3

 
Viktar Dzemikhau:
В общем, видел я эту асинхронность. Даже в тестере (в идеальных условиях) и то асинхронно. Это просто дичъ.

Асинхронность нужна в конкретных специфических случаях, а именно:

  • Когда нужно отправить два и более торговых приказа одновременно. Например в арбитражере, нужно один инструмент купить, а другой одновременно продать. При этом нет времени дожидаться когда сработает сначала один ордер, что бы вслед за ним отправить второй.
  • Когда пишем какую-нибудь панель/уведомлялку для пользователя, и при нажатии кнопки "отправить ордер", статус ордера в панели меняется на "отправлен" -> "принят", -> "исполнен". Эффектно и красиво получится. 

Также замечу, что даже при получении события "ордер размешен" с конкретным id ордера, обратится к нему в торговом окружении не получиться. Раньше по крайней мере было так. Т.е. получается засада: приходит событие ордер #1283745... размещен, но в OrderHistorySelect его еще нет. Вот и думайте, а нужно ли оно Вам.

p.s. по первому пункту замечу, что схема эта на самом деле так себе. Используют ее при условно неограниченной ликвидности, что на практике едва ли можно встретить. Обычно делают умнее: менее ликвидную ногу котируют лимитником, а вторую, более ликвидную бьют по маркету. Как только лимитный ордер зафилится, открывают вторую ногу по маркету. Но это совсем другая история. Просто я к тому, что значение асинхронных торговых операций в умах пользователей очень преувеличено. В реальности обычно все приходится делать более линейно и топорно.

 

Vasiliy Sokolov:

Также замечу, что даже при получении события "ордер размешен" с конкретным id ордера, обратится к нему в торговом окружении не получиться. Раньше по крайней мере было так. Т.е. получается засада: приходит событие ордер #1283745... размещен, но в OrderHistorySelect его еще нет. Вот и думайте, а нужно ли оно Вам.

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

 
Viktar Dzemikhau:

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

Почему не надёжно?

Если тип транзакции TRADE_TRANSACTION_DEAL_ADD и PositionSelectByTicket(trans.position) == true то позиция открылась.

Если тип транзакции TRADE_TRANSACTION_DEAL_ADD и PositionSelectByTicket(trans.position) == false то позиция закрылась.

void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
{
  if(trans.type == TRADE_TRANSACTION_DEAL_ADD && trans.symbol == _Symbol)
   {
    /******************** Если открылась позиция********************/
    if(PositionSelectByTicket(trans.position) && PositionGetInteger(POSITION_MAGIC) == magick)
      ifOpenedPosition(trans);
    /******************** Если закрылась позиция********************/
    if(!PositionSelectByTicket(trans.position))
     ifClosedPosition(trans);
   }
}/*******************************************************************/

Вот уже с тех пор как я выяснял это (ссылка выше) этот вариант работает без сбоев.

Барабашкин вариант тоже выглядит нормально, но я не проверял. Мне пока достаточно и этого. Я на только hadge пока работаю.

 
Viktar Dzemikhau:

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

Это достаточно надежно. Скажем надежность 99%. Но для оставшегося 1% нужно делать дополнительную проверку по состоянию, на тот случай, если даже если событие не пришло, эксперт все равно понял бы что ордер был исполнен или позиция закрылась. 

 
Vasiliy Sokolov:

Это достаточно надежно. Скажем надежность 99%. Но для оставшегося 1% нужно делать дополнительную проверку по состоянию, на тот случай, если даже если событие не пришло, эксперт все равно понял бы что ордер был исполнен или позиция закрылась. 

У меня это реализована не так. Есть отдельные функции в библиотеке. Например, если я хочу убедится, что позиция закрыта по тейку, вот связка:

//=======================================================================================================================================================================================================
// Возвращает true, если сделки с тикетом ticket 'своя', иначе false. ===================================================================================================================================
bool choiceDealPrimary(const string symbolName,        // Название торгового инструмента
                       const ulong magic,              // Magic number позиции
                       const ulong ticket) export {    // Тикет сделки
//---
  if (!HistoryDealSelect(ticket))
    return false;
  if (selectedHistoryDealSymbol(ticket) != symbolName)
    return false;
  if (selectedHistoryDealMagic(ticket) != magic)
    return false;
//---
  return true;
}
//=======================================================================================================================================================================================================
// Возвращает true, если позиция согласно данных в реализованной сделке закрылась по Take-Profit, иначе false. ==========================================================================================
bool isPositionAcquireTP(const MqlTradeTransaction& transaction,    // Транзакция
                         const SymbolInstance *ptrSymbol,           // Указатель на класс свойств торгового инструмента
                         const ulong magic) export {                // Magic number позиции
//---
  if (transaction.type == TRADE_TRANSACTION_DEAL_ADD) {
    if (!choiceDealPrimary(ptrSymbol.getName(), magic, transaction.deal))
      return false;
    if (selectedHistoryDealEntry(transaction.deal) == DEAL_ENTRY_OUT) {
      if (selectedHistoryDealReason(transaction.deal) == DEAL_REASON_TP)
        return true;
    }
  }
//---
  return false;
}

Всё компактно и читабельно. Остальное там и так понятно. Если нет.. могу показать.

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

Я на днях когда написал это свои реализации (всю библиотеку для работы с транзакциями) обрадовался. Подумал, вот ништяк. В отличие от 4-ки, это как-бы самое лучшее, что есть из новшеств в 5-ке. А через пару дней поштудировав темупришёл к выводу, что все мои первоначальные ожидания были не совсем корректны. Не всё так радужно, как хотелось бы..

 
Vasiliy Sokolov:

Это достаточно надежно. Скажем надежность 99%. Но для оставшегося 1% нужно делать дополнительную проверку по состоянию, на тот случай, если даже если событие не пришло, эксперт все равно понял бы что ордер был исполнен или позиция закрылась. 

Ну и кк это можно сделать? Дублировать проверку? Т.е. тоже самое, только как-то с другой стороны без транзакции писать и узнавать те же данные? Тогда зачем эот чудесный метод, если всё за него нужно перепроверять?
 
Viktar Dzemikhau:
Ну и кк это можно сделать? Дублировать проверку? Т.е. тоже самое, только как-то с другой стороны без транзакции писать и узнавать те же данные? Тогда зачем эот чудесный метод, если всё за него нужно перепроверять?

Так спроектировали - теперь уже ничего не изменить

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

 
A100:

Так спроектировали - теперь уже ничего не изменить

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

Я тоже пришёл к такому выводу. Погоняю в реале. Если будут косяки перепишу альтернативно.

Я для себя решил просто. Для тестов это удобно т.к. одной строкой из библиотеки можно проверить любое событие. А если подойти практично - хз. Чуть что, в ботов, которые будут ставить на реал можно переписать это уже на стабильный и провернный вариант с перепроверками. А для тестов, не хочется много писать, это не интересно.. ))

 
Viktar Dzemikhau:
Ну и кк это можно сделать? Дублировать проверку? Т.е. тоже самое, только как-то с другой стороны без транзакции писать и узнавать те же данные? Тогда зачем эот чудесный метод, если всё за него нужно перепроверять?

Да, совершенно точно. При работе с OnTradeTransaction нужно всегда писать две независимые логики: одну для OnTradeTranaction, другую альтернативную, например проверять состояние позиций и ордеров по таймеру. При том, если сработала логика для OnTradeTranaction делать так, что бы по OnTimer логика уже не срабатывала (исключить двойное срабатывание). Это серьезное усложнение алгоритма.

Единственное преимущество OnTradeTranaction в Вашем случае, на сколько я понимаю, это скорость. Вы по пришедшему событию узнаете о изменениях сразу, не дожидаясь нового тика или вызова таймера. Однако если делать логику по таймеру с временем 100 мсек., то в среднем Вы будете узнавать об изменениях на рынке на всего на 50 мсек позже, чем они фактически произойдут. И это без всяких усложнений логики. Выходит что топорный таймер делает тоже, почти также быстро и гораздо надежней. Как-то вот так получается.

 
Vasiliy Sokolov:

Да, совершенно точно. При работе с OnTradeTransaction нужно всегда писать две независимые логики: одну для OnTradeTranaction, другую альтернативную, например проверять состояние позиций и ордеров по таймеру. При том, если сработала логика для OnTradeTranaction делать так, что бы по OnTimer логика уже не срабатывала (исключить двойное срабатывание). Это серьезное усложнение алгоритма.

Единственное преимущество OnTradeTranaction в Вашем случае, на сколько я понимаю, это скорость. Вы по пришедшему событию узнаете о изменениях сразу, не дожидаясь нового тика или вызова таймера. Однако если делать логику по таймеру с временем 100 мсек., то в среднем Вы будете узнавать об изменениях на рынке на всего на 50 мсек позже, чем они фактически произойдут. И это без всяких усложнений логики. Выходит что топорный таймер делает тоже, почти также быстро и гораздо надежней. Как-то вот так получается.

Василий!

Уверяю Вас, что можно обойтись без таймера (всё зависит от конкретной задачи).

Viktar Dzemikhau:

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

МТ-5 - это приложение Клиент- Сервер и т.к ответы сервера приходят ассинхронно, то какие-то проверки торгового окружения - неизбежны.

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