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

 
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. Рекомендуется...
 

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

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

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 программы?

 

Вот инфа от fxsaber по этому вопросу:https://www.mql5.com/ru/forum/366029/page3#comment_22547881  https://www.mql5.com/ru/forum/366029/page3#comment_22547881


@Rashid Umarov

прошу разработчиков откликнуться.

Библиотеки: TradesID
Библиотеки: TradesID
  • 2021.05.21
  • www.mql5.com
Статьи и техническая библиотека по автоматическому трейдингу: Библиотеки: TradesID
 

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

Возможно, есть механизм более экономного кеширования. Но допускать тормозов, конечно, нельзя.


ЗЫ Как быстрее всего работать с историей - комментариев нет. На данный момент 100% быстрым способом является везде вызов только такого HistorySelect.

HistorySelect(0, INT_MAX)
 
fxsaber:

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

Возможно, есть механизм более экономного кеширования. Но допускать тормозов, конечно, нельзя.


ЗЫ Как быстрее всего работать с историей - комментариев нет. На данный момент 100% быстрым способом является везде вызов только такого HistorySelect.

А почему не
HistorySelect(t, INT_MAX)

где t - произвольная не очень давняя и не меняющаяся от вызова к вызову дата (константа, единая для всей программы)?

 
mktr8591:
А почему не

где t - произвольная не очень давняя и не меняющаяся от вызова к вызову дата (константа, единая для всей программы)?

Не уверен, что от этого кеш уменьшится.

 
fxsaber:

Не уверен, что от этого кеш уменьшится.

Потребление уменьшается. Прописывал такое в начале.

bool HistorySelect2( const datetime From, const datetime To )
{
  static const datetime NewFrom = ::TimeCurrent() - 24 * 3600 & 30; // -Month.
  
  return(::HistorySelect(From ? From : NewFrom, To));
}

#define HistorySelect HistorySelect2

Но пришлось отказаться из-за серьезных проблем.

 
#define PRINT(A) Print(#A + " = " + (string)(A))

void OnStart()
{
  PRINT(TerminalInfoInteger(TERMINAL_MEMORY_USED));
  
  if (HistorySelect(0, INT_MAX))
  {
    PRINT(HistoryDealsTotal());
    PRINT(HistoryOrdersTotal());
    
    PRINT(MQLInfoInteger(MQL_MEMORY_USED));
    PRINT(TerminalInfoInteger(TERMINAL_MEMORY_USED));
  }
}

Результат запуска на Терминале, где один M1 чарт, 5000 баров, один символ, нет ресурсов и графических объектов.

TerminalInfoInteger(TERMINAL_MEMORY_USED) = 426
HistoryDealsTotal() = 134502
HistoryOrdersTotal() = 218740
MQLInfoInteger(MQL_MEMORY_USED) = 1
TerminalInfoInteger(TERMINAL_MEMORY_USED) = 789

Многовато. 10 синхронных (OrderSend) советников съедает 4 гига. Два варианта:

  1. Открыть новый счет, перекинуть на него средства и продолжить торговлю уже на нем. К сожалению, не всегда возможно.
  2. Объединить всех ботов в один через асинхронность (OrderSendAsync). Очень тяжелый вариант отловли багов при супер-активной торговле.
Во втором пункте еще надо писать менеджер (GUI и прочее) ботов, вшитых в единый советник.
 
fxsaber:



  1. Объединить всех ботов в один через асинхронность (OrderSendAsync). Очень тяжелый вариант отловли багов при супер-активной торговле.

По другому никак. (если конечно не отсекать старую историю и переделать полностью алгоритм работы с истрией, но это только если MQ не вернут старую сортировку).

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