Обсуждение статьи "Ордерa, позиции и сделки в MetaTrader 5" - страница 4

 

Скажите пожалуйста, если функция OrderSend вернула true и result.order иметь тикет ордера (result.order!=0), гарантирует ли это что ордер принят брокером и он находится во вкладке торговля или на этом этапе запрос принят только сервером брокера но не биржей?

И второй вопрос, может ли быть ситуация когда OrderSend вернула true, а result.order==0 ?

 
Aleksey Gunin:

Скажите пожалуйста, если функция OrderSend вернула true и result.order иметь тикет ордера (result.order!=0), гарантирует ли это что ордер принят брокером и он находится во вкладке торговля или на этом этапе запрос принят только сервером брокера но не биржей?

Гарантирует.

И второй вопрос, может ли быть ситуация когда OrderSend вернула true, а result.order==0 ?

Нет.

 
fxsaber:

Гарантирует.

Нет.

Только на днях добавили уточнение для функции OrderSend, посмотрите онлайн справку.

 
Rashid Umarov:

Только на днях добавили уточнение для функции OrderSend, посмотрите онлайн справку.

Разве это касается маркет-ордеров?

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

  • истечение срока действия,
  • появление встречного запроса,
  • срабатывание ордера при поступлении цены исполнения,
  • поступление запроса на отмену ордера.
Отсутствует уточнение, что сам Терминал всегда вызывает OrderCheck перед OrderSendAsync, а OrderSend - это надстройка над OrderSendAsync

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Типичные ошибки и способы их устранения при работе с торговым окружением

fxsaber, 2018.02.20 12:23

Условная схема реализации штатной OrderSend (без таймаута)
static MqlTradeResult LastResult = {0};

void OnTradeTransaction( const MqlTradeTransaction&, const MqlTradeRequest&, const MqlTradeResult &Result )
{ 
  LastResult = Result;
}

// Условный алгоритм реализации штатной OrderSend
bool OrderSend( const MqlTradeRequest &Request, MqlTradeResult &Result )
{  
  bool Res = OrderSendAsync(Request, Result);
  
  if (Res)
  {
    while (LastResult.request_id != Result.request_id)
      OnTradeTransaction(); // условно-схематичный вызов
          
    Result = LastResult;    
    Res = (Result.retcode == TRADE_RETCODE_PLACED) ||
          (Result.retcode == TRADE_RETCODE_DONE) ||
          (Result.retcode == TRADE_RETCODE_DONE_PARTIAL);

    LastResult.request_id = 0;
  }
    
  return(Res);
}


Из этой схемы хорошо видно, что при выставлении маркет-ордера через OrderSendAsync на том же MetaQuotes-Demo невозможно гарантированно поймать событие выставления соответствующего ордера до момента, пока ордер не будет исполнен или отклонен. Т.е. в MT5 нет никаких простых механизмов оценивания промежуточных результатов своего OrderSendAsync.


OrderSend выполняется до тех пор, пока в OnTradeTransaction не придет Result.request_id равный этом же значению у OrderSendAsync. Либо же завершается аварийно по таймауту. Поэтому результат OrderSend зависит только от типа сообщения в OnTradeTransaction с соответствующим request_id.

Было бы полезно услышать про формирование самого request_id. Если правильно понимаю, то это счетчик отправленных на торговый сервер приказов с момента запуска/коннекта Терминала/Счета. Сам Терминал анализирует приходы сообщений от торгового сервера и либо только одному присваивает нужный request_id (что сомнительно), либо обнуляет request_id до определенного сообщения (вероятнее всего). Такое поведение позволило некоторое время назад добиться соответствия Истории торгов с выходом из OrderSend. Но из-за того, что только одно сообщение в OnTradeTransaction видно с нужным request_id, возникает неприятная ситуация в асинхронном режиме, приведенная в цитате выше.

 

Доброе время суток, обнаружил несоответствия для MqlTradeResult.deal и MqlTradeResult.order

1) Описание (Справочник MQL5)


2) Торговля в реальном времени

Ставлю рыночные ордера (TRADE_ACTION_DEAL). Вывожу функцией Print значения MqlTradeResult:


при этом в журнале deal фигурирует:

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


3) Тестер Стратегий

Здесь заполняются все поля:



Чем вызваны такие различия?

 
Konstantin Kulikov:

Доброе время суток, обнаружил несоответствия для MqlTradeResult.deal и MqlTradeResult.order




https://www.mql5.com/ru/docs/trading/ordersend

При отправке рыночного ордера (MqlTradeRequest.action=TRADE_ACTION_DEAL) успешный результат функции OrderSend() не означает, что ордер был выполнен (исполнены соответствующие сделки): true в этом случае означает только то, что ордер был успешно размещен в торговой системе для дальнейшего выполнения. Торговый сервер может в возвращаемой структуре результата result заполнить значения полей deal или order, если эти данные будут ему известны в момент формирования ответа на вызов OrderSend(). В общем случае событие или события исполнения сделок, соответствующих ордеру, могут произойти уже после того, как будет отправлен ответ на вызов OrderSend(). Поэтому для любого типа торгового запроса при получении результата выполнения OrderSend() необходимо в первую очередь проверять код возврата торгового сервера retcode и код ответа внешней торговой системы retcode_external (при необходимости), которые доступны в возвращаемой структуре результатаresult.


Документация по MQL5: Торговые функции / OrderSend
Документация по MQL5: Торговые функции / OrderSend
  • www.mql5.com
Торговый запрос проходит несколько стадий проверок на торговом сервере. В первую очередь проверяется корректность заполнения всех необходимых полей параметра , и при отсутствии ошибок сервер принимает ордер для дальнейшей обработки. При успешном принятии ордера торговым сервером функция OrderSend() возвращает значение true. Рекомендуется...
 

Спасибо за столь информативную статью. @MetaQuotes

Запросы: Как можно коллективно перебрать все открытые ордера и открытые позиции в одном цикле for() (аналогично тому, как мы перебираем все ордера в MQL4, а затем проверяем, является ли ордер уже исполненным или отложенным)?

 
Rahul Dhangar :

Спасибо за столь информативную статью. @MetaQuotes

Запросы: Как можно коллективно перебрать все открытые ордера и открытые позиции в одном цикле for() (аналогично тому, как мы перебираем все ордера в MQL4, а затем проверяем, является ли ордер уже исполненным или отложенным)?

Для вычисления ПОЗИЦИЙ и ОТЛОЖЕННЫХ ОРДЕРОВ необходимо использовать два независимых цикла. Один цикл перечисляет ПОЗИЦИИ, а второй - ОТЛОЖЕННЫЕ ОРДЕРЫ. Пример: вычисление позиций и отложенных ордеров

How to start with MQL5
How to start with MQL5
  • 2020.12.19
  • www.mql5.com
This thread discusses MQL5 code examples. There will be examples of how to get data from indicators, how to program advisors...
 

Я знаю, что вы не особо беспокоитесь о тех, кто только начинает изучать язык mql5, учитывая, что у вас сильное сообщество, несмотря на многочисленные критические замечания, вот еще одно:

Перевод и сама формулировка текста мешают пониманию... Я вспотел, мне пришлось далеко идти, чтобы выяснить, кто должен быть первым, так как документация сама противоречит себе, в тексте:

  • История заказов

    Чтобы получить информацию о заказе из истории, сначала нужно создать кэш истории заказов с помощью одной из трех функций: HistorySelect(start, end), HistorySelectByPosition() или HistoryOrderSelect(ticket). При успешном выполнении в кэше будет храниться количество заказов, возвращаемое функциейHistoryOrdersTotal(). Доступ к свойствам этих заказов осуществляется по каждому из элементов тикета с помощью соответствующей функции:

    1. HistoryOrderGetDouble(ticket_order, type_property)
    2. HistoryOrderGetInteger(ticket_order, type_property)
    3. HistoryOrderGetString(ticket_order, type_property)


В отличие от: https: //www.mql5.com/pt/docs/trading/historyorderstotal, транскрибированного ниже.



HistoryOrdersTotal

Возвращает количество ордеров в истории. Перед вызовом HistoryOrdersTotal() необходимо сначала получить историю сделок и ордеров с помощью функцииHistorySelect() или HistorySelectByPosition().

int HistoryOrdersTotal();

Возвращаемое значение

Значение типаdouble.

Примечание

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

Также см.


Первый отрывок противоречит сам себе, ему не нужна помощь, но тут появляется второй и доводит дело до осложнений....: в конце концов, кто стоит на первом месте, HistoryOrdersTotal или одна из трех функций HistorySelect (start, end) HistorySelectByPosition() или HistoryOrderSelect(ticket), или даже HistorySelectByPosition(), упомянутая во втором тексте.

Это было сложно, можно было бы и проще... но я думаю, что первое, что приходит на ум, это одна из трех функций HistorySelect(start, end) HistorySelectByPosition () или HistoryOrderSelect(ticket), или даже HistorySelectByPosition(), упомянутых во втором тексте...

Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
Documentação sobre MQL5: Funções de Negociação / HistoryOrdersTotal
  • www.mql5.com
HistoryOrdersTotal - Funções de Negociação - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 

Добрый день,
вопрос к разработчикам:  можете дать примерную инфу, какой объем памяти занимает кэш истории? приблизительно кбайт на одну сделку и на один ордер.

Я запустил в терминале с небольшой историей скрипт и получил такой результат:

void OnStart()
  {
   Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
   if(HistorySelect(0, INT_MAX))
     {
      Print("TerminalInfoInteger(TERMINAL_MEMORY_USED) = ", TerminalInfoInteger(TERMINAL_MEMORY_USED));
      Print("HistoryDealsTotal  = ", HistoryDealsTotal());
      Print("HistoryOrdersTotal = ", HistoryOrdersTotal());
     }
  }

2021.05.14 14:46:41.265	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 488
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	TerminalInfoInteger(TERMINAL_MEMORY_USED) = 489
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryDealsTotal  = 1928
2021.05.14 14:46:41.285	TestCashSize (Si-6.21,H1)	HistoryOrdersTotal = 1116

Это значит, что при истории в пару миллионов сделок и миллион ордеров кэш займет порядка гигабайта?

И так для каждой mql программы?