Ошибки, баги, вопросы - страница 1861

 

HistoryDealGet* и HistoryOrderGet*-функции написаны очень странно, с точки зрения производительности.

Когда делаю HistorySelect, например, на 100К отдельных записей. То HistoryDealGet-функция требует первым аргументом не номер записи в исторической таблице, а тикет. При этом таблица отсортирована по времени, а не по тикету. Поэтому при выполнении, первое, что делает HistoryDealGet-функция, это бежит каждый раз по таблице и ищет подходящий Ticket.


Зачем столь нерациональное расходование ресурсов?! Получается, что самый первый тикет и самый последний будут выполняться с разными скоростями. И чтобы получить все характеристики последней сделки, HistoryDealGet-функции будут каждый раз пробегать всю таблицу.


Почему не сделать нормально?

long HistoryDealGetInteger( const int index, const ENUM_ORDER_PROPERTY_INTEGER  property_id ); // номер сделки, а не тикет


И как HFT-робота тестировать, если для того, чтобы узнать размер комиссии текущей позиции, нужно лезть каждый раз в тормозную историю через HistorySelect и ни в коем случае не через HistorySelectByPosition? Посмотреть проскальзывание отложенного ордера превращается в треш производительности!

 

ACCOUNT_PROFIT в тестере показывает ерунду.

Запускаем советник, который открывает и закрывает тут же позицию

#include <MT4Orders.mqh>

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

void OnTick()
{  
  static bool FirstRun = true;

  if (FirstRun && OrderSelect(OrderSend(_Symbol, OP_BUY, 1, 0, 0, 0, 0), SELECT_BY_TICKET))
  {
    PRINT(AccountInfoDouble(ACCOUNT_PROFIT))
    
    if (OrderClose(OrderTicket(), OrderLots(), 0, 0) && OrderSelect(OrdersHistoryTotal() - 1, SELECT_BY_POS, MODE_HISTORY))
      OrderPrint();
    
    FirstRun = false;          
  }
}

Результат

2017.04.19 23:24:50.317 RTS-6.17,M1 (MetaQuotes-Demo): generating based on real ticks
2017.04.19 23:24:50.317 RTS-6.17,M1: testing of Experts\fxsaber\Test2.ex5 from 2017.04.06 00:00 to 2017.04.08 00:00 started
2017.04.19 23:24:50.419 RTS-6.17 : real ticks begin from 2017.04.06 00:00:00
2017.04.19 23:24:50.419 2017.04.06 09:45:01   deal #2 buy 1.00 RTS-6.17 at 114250 done (based on order #2)
2017.04.19 23:24:50.419 2017.04.06 09:45:01   deal performed [#2 buy 1.00 RTS-6.17 at 114250]
2017.04.19 23:24:50.419 2017.04.06 09:45:01   order performed buy 1.00 at 114250 [#2 buy 1.00 RTS-6.17 at 114250]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   AccountInfoDouble(ACCOUNT_PROFIT) = 0.0
2017.04.19 23:24:50.421 2017.04.06 09:45:01   exchange sell 1.00 RTS-6.17 at 114200, close #2 (114200 / 114250)
2017.04.19 23:24:50.421 2017.04.06 09:45:01   deal #3 sell 1.00 RTS-6.17 at 114200 done (based on order #3)
2017.04.19 23:24:50.421 2017.04.06 09:45:01   deal performed [#3 sell 1.00 RTS-6.17 at 114200]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   order performed sell 1.00 at 114200 [#3 sell 1.00 RTS-6.17 at 114200]
2017.04.19 23:24:50.421 2017.04.06 09:45:01   #3 2017.04.06 09:45:01 buy 1.00 RTS-6.17 114250 0 0 2017.04.06 09:45:01 114200 0.00 0.00 -56.44 0
2017.04.19 23:24:50.629 RTS-6.17,M1: 582089 ticks, 1573 bars generated. Environment synchronized in 0:00:00.063. Test passed in 0:00:00.421 (including ticks preprocessing 0:00:00.078).

ACCOUNT_PROFIT показывает ноль, но на самом деле -56.44. Как следствие, неправильно оцениваются эквити, просадка и т.д.

PositionGetDouble(POSITION_PROFIT) - аналогично.

 
fxsaber:

И как HFT-робота тестировать, если для того, чтобы узнать размер комиссии текущей позиции, нужно лезть каждый раз в тормозную историю через HistorySelect и ни в коем случае не через HistorySelectByPosition? Посмотреть проскальзывание отложенного ордера превращается в треш производительности!

HistorySelect работает через двоичный поиск запрошенного интервала времени или нет? Т.е. O(N) или O(log(N))?
 
fxsaber:
HistorySelect работает через двоичный поиск запрошенного интервала времени или нет? Т.е. O(N) или O(log(N))?
Нет. В данном случае двоичный поиск неприменим
 
Slawa:
Нет. В данном случае двоичный поиск неприменим
Так внутриархитектурно обе истории (Orders и Deals) отсортированы по времени. Речь про HistorySelect, а не про совсем не оптимизируемую HistorySelectByPosition.
 
fxsaber:
Так внутриархитектурно обе истории (Orders и Deals) отсортированы по времени.

Извините, погорячился.

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

 
Slawa:

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

Последнюю запись разве не логично искать так же?

Очень напрягает организация работы с историей. HFT в тестере - почти нереально. Написал по этому поводу несколько постов на форуме и оформил в виде заявки в СД.


И еще, если в терминале и так есть история, то почему к ней обязываете обращаться через HistorySelect, а не по принципу MT4 - SELECT_BY_POS? И что совсем непонятно, зачем HistoryDealGet* реализован через тикет с соответствующей O(N), когда логично опять же через SELECT_BY_POS?


Очень интересные записи

HistoryDealGetInteger(DealTicket, DEAL_TICKET);
HistoryOrderGetInteger(OrderTicket, ORDER_TICKET);
 
fxsaber:

Последнюю запись разве не логично искать так же?


Зачем?

От времени до времени. Начальное время нашёл, а дальше идёт поэлементное копирование. До конечного времени.

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

 
Slawa:

Зачем?

От времени до времени. Начальное время нашёл, а дальше идёт поэлементное копирование. До конечного времени.

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

Для того, чтобы копировать кусками, а не поэлементно. Т.е. через двоичный поиск находим оба индекса, а дальше кусок первого блока, все блоки полностью до последнего и оставшийся кусок - последнего.
 
fxsaber:

Очень напрягает организация работы с историей. HFT в тестере - почти нереально.


Решается алгоритмичнски.

Для HFT не надо каждый раз лазить в историю. Подготовьте необходимую информацию в процессе инициализации и держите её наготове, чтобы очень быстро доступаться