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

 
Artyom Trishkin:


Спасибо, это важный и полезный труд....

 
Vladimir Pastushak:

Спасибо, это важный и полезный труд....

Пожалуйста

 
Здравствуйте, Артём - есть ли более простой способ получить номер тикета после размещения ордера или открытия позиции? Это кажется слишком сложным :-(
long CMySetup::PlaceOrder()
{
   bool order_ok;
   if (m_direction == POSITION_TYPE_BUY) {
      order_ok = m_engine.PlaceBuyLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, m_magic, m_comment, m_expiry);
   }
   else {
      order_ok = m_engine.PlaceSellLimit(m_lot_size, m_symbol, m_entry, m_hard_stop, m_ratio_target, m_magic, m_comment, m_expiry);
   }

   if (order_ok) {
      CArrayObj* list = m_engine.GetListHistoryOrders();
      if (list != NULL) {
         list.Sort(SORT_BY_ORDER_TIME_OPEN);
         COrder* order = list.At(list.Total() - 1);
         if (order != NULL) {
            m_ticket = order.Ticket();
         }
      }
   }
   return m_ticket;
}
 
Dima Diall :
Здравствуйте, Артём - есть ли более простой способ получить номер тикета после размещения ордера или открытия позиции? Это кажется слишком сложным :-(

Тестовые советники отображают все данные последнего выставленного ордера или открытой позиции. Это означает, что библиотека знает эти данные. В ней реализована событийная функциональность, и библиотека сообщает обо всех установленных событиях. Соответственно, вам нужно управлять этими событиями и получать объект последнего ордера или позиции, а из него брать тикет (и все остальные параметры ордера или позиции). Пока нет возможности привести какой-либо пример. Но я скоро вернусь и смогу помочь.
Вы можете сами посмотреть, где тестовые советники берут данные о событиях и выводят их в лог. Соответственно, вы можете обратиться к этой же точке из своей программы и взять данные из этих событий.

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

 
Artyom Trishkin:

Тестовые советники отображают все данные последнего размещенного ордера или открытой позиции. Это означает, что библиотека знает эти данные. В ней реализована событийная функциональность, и библиотека сообщает обо всех установленных событиях. Соответственно, нужно управлять этими событиями и получать объект последнего ордера или позиции, а из него брать тикет (и все остальные параметры ордера или позиции). Пока нет возможности привести какой-либо пример. Но я скоро вернусь и смогу помочь.
Вы можете сами посмотреть, где тестовые советники берут данные о событиях и выводят их в лог. Соответственно, вы можете обратиться к этой же точке из своей программы и взять данные из этих событий.

Да, я понимаю - я присматриваюсь и думаю, гарантирован ли мне немедленный вызов обработчика событий и, если было запрошено несколько ордеров/позиций, какой анализ мне нужно провести, чтобы правильно сопоставить события с каждым запросом... и все это только для того, чтобы узнать номер тикета, который для, например, отложенных ордеров библиотека получает в 'm_result' внутри CTradeObj::SetOrder().

#ifdef __MQL5__
   return(!this.m_async_mode ? ::OrderSend(this.m_request,this.m_result) : ::OrderSendAsync(this.m_request,this.m_result));
#else 
   ::ResetLastError();
   int ticket=::OrderSend(this.m_request.symbol,
                          this.m_request.type,
                          this.m_request.volume,
                          this.m_request.price,
                          (int)this.m_request.deviation,
                          this.m_request.sl,
                          this.m_request.tp,
                          this.m_request.comment,
                          (int)this.m_request.magic,
                          this.m_request.expiration,
                          clrNONE);
// ...
   if(ticket!=WRONG_VALUE)
     {
      this.m_result.order=ticket;
      this.m_result.price=(::OrderSelect(ticket,SELECT_BY_TICKET) ? ::OrderOpenPrice() : this.m_request.price);
      this.m_result.volume=(::OrderSelect(ticket,SELECT_BY_TICKET) ? ::OrderLots() : this.m_request.volume);
      return true;
     }
// ... 
#endif

Вот почему я думаю, что было бы полезнее, чтобы номер тикета (или -1 в случае неудачи) возвращался из CEngine::PlaceBuyLimit() и всех методов этого семейства, потому что когда вы выставляете ордер или открываете позицию, чаще всего вы сразу хотите записать номер тикета, чтобы потом к нему вернуться... Возможно, он даже мог бы возвращать указатель COrder* или NULL в случае неудачи. По моему скромному мнению, заставляя пользователя DoEasy реализовывать обработку событий для этого, библиотека кажется неоправданно сложной.

Вероятно, у вашего подхода есть веские причины, так что не уверен, что вы согласны; если нет, мне было бы очень интересно понять, чем обусловлено ваше дизайнерское решение ;-)

 
Dima Diall :

Да, я понимаю... Я присматриваюсь и думаю, гарантирован ли мне немедленный вызов обработчика событий, и, если было запрошено несколько ордеров/позиций, какой анализ мне нужно провести, чтобы правильно сопоставить события с каждым запросом... и все это только для того, чтобы узнать номер тикета, который для, например, отложенных ордеров библиотека получает в 'm_result' внутри CTradeObj::SetOrder().

Вот почему я думаю, что было бы полезнее, чтобы номер тикета (или -1 в случае неудачи) возвращался из CEngine::PlaceBuyLimit() и всех методов этого семейства , потому что когда вы выставляете ордер или открываете позицию, чаще всего вы сразу хотите записать номер тикета, чтобы потом к нему вернуться... Возможно, он даже мог бы возвращать указатель COrder* или NULL в случае неудачи. По моему скромному мнению, заставляя пользователя DoEasy реализовывать обработку событий для этого, библиотека кажется неоправданно сложной.

Вероятно, у вашего подхода есть веские причины, так что не уверен, что вы согласны; если нет, мне было бы очень интересно понять, чем обусловлено ваше дизайнерское решение ;-)

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

Всё очень просто. В MQL5 успешность отсылки торгового приказа на сервер не гарантирует его исполнения. Успешность отсылки - это просо проверка на корректность параметров в торговом приказе. Исполнение приказа лежит на стороне биржи. Мы можем лишь использовать факт изменения торгового окружения, и после обнаружения его изменений уже двигаться дальше. Именно по этой причине я не использую данные, полученные в ответе сервера.

 
Artyom Trishkin:

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

Хорошо, я пытаюсь реализовать этот подход в своем советнике, чтобы упростить управление, используя ваш TestDoEasyPart39.mq5 в качестве руководства, но у меня есть некоторые проблемы с пропущенными событиями - все еще исследую/отлаживаю (пока все в режиме тестера)... Я был бы признателен за другие примеры кода, как вы делаете это сами в других советниках, если вы можете поделиться некоторыми.

Я все еще использую версию библиотеки из части 39; это лучшая версия для использования на данный момент или вы рекомендуете перейти на более новую версию?

 
Dima Diall :

Хорошо, я пытаюсь реализовать этот подход в своем советнике, чтобы облегчить управление, используя ваш TestDoEasyPart39.mq5 в качестве руководства, но у меня есть некоторые проблемы с пропущенными событиями - все еще исследую/отлаживаю (пока все в режиме тестера)... Я был бы признателен за другие примеры кода, как вы делаете это сами в других советниках, если вы можете поделиться некоторыми.

Я все еще использую версию библиотеки из части 39; это лучшая версия для использования на данный момент или вы рекомендуете перейти на более новую версию?

Пока что все последующие версии посвящены созданию индикаторов.

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

Пока все последующие версии посвящены созданию индикаторов.

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

 
Artyom Trishkin:

Пока что все последующие версии посвящены созданию индикаторов.

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

Когда вы планируете снова начать работу над функциями для советников? В зависимости от вашего ответа мне, возможно, придется выбрать написание собственного мультиплатформенного класса/метода для упрощенного выставления ордеров, открытия позиций и т.д... по крайней мере, для моего текущего проекта.

При обработке торговых событий, таких как TRADE_EVENT_PENDING_ORDER_PLASED или TRADE_EVENT_POSITION_OPENED, как я могу убедиться, что данное событие соответствует конкретной торговой заявке, которую я отправил ранее? В настоящее время у меня есть только один ордер/позиция на символ, поэтому легко проверить, что символ события соответствует моему запросу... Однако позже мой советник должен иметь возможность открывать несколько ордеров/позиций на одном и том же символе (используя одно магическое число), надеюсь, не нужно будет сравнивать цену входа, SL, TP и т.д... Я думал, может быть, использовать разные магические числа или функцию, которая объединяет группу #1 и #2 в магическое число.

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

Library for easy and quick development of MetaTrader programs (part XXVI): Working with pending trading requests - first implementation (opening positions)
Library for easy and quick development of MetaTrader programs (part XXVI): Working with pending trading requests - first implementation (opening positions)
  • www.mql5.com
I have already mentioned the concept of a pending request in a number of previous articles. In this article, we are going to figure out what it is and why we need it, as well as start implementing pending requests. When receiving and handling a trade server error, we sometimes need to wait and repeat the request. In the simplest case, waiting...
 
Dima Diall :

Когда вы планируете снова начать работу над функциями для советников? В зависимости от вашего ответа мне, возможно, придется выбрать написание собственного мультиплатформенного класса/метода для упрощенного размещения ордеров, открытия позиций и т.д... по крайней мере, для моего текущего проекта.

При обработке торговых событий, таких как TRADE_EVENT_PENDING_ORDER_PLASED или TRADE_EVENT_POSITION_OPENED, как я могу убедиться, что данное событие соответствует конкретной торговой заявке, которую я подал ранее? В настоящее время у меня есть только один ордер/позиция на символ, поэтому легко проверить, что символ события соответствует моему запросу... Однако позже мой советник должен иметь возможность открывать несколько ордеров/позиций на одном и том же символе (используя одно магическое число), надеюсь, не нужно будет сравнивать цену входа, SL, TP и т.д... Я думал, может быть, использовать разные магические числа, или ту функцию, которая упаковывает группу #1 & #2 в магическое число.

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

Если вам нужно сопоставить торговую заявку и позицию, то самый простой способ - установить идентификатор позиции (не волшебный). У каждой заявки есть свой идентификатор. Магию советника можно оставить одной для всех позиций. Тогда по идентификатору (он прописан в магии позиции или ордера и никогда не потеряется) вы сможете в любой момент точно сопоставить заявку и позицию/ордер.