Особенности языка mql5, тонкости и приёмы работы - страница 41

fxsaber
15765
fxsaber  
Slava:
Вы забыли указать, что начало замера в начале первого OnTick. Конец замера - в начале OnDeinit
Или же в начале OnTester, т.к.
// После окончания бэктеста сначала вызывается OnTester, затем OnDeinit

В тему

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

Ошибки, баги, вопросы

fxsaber, 2016.08.25 11:13

Лайфхак
// Возвращает true, если полностью выполнился OnTick() на последнее событие NewTick в тестере - окончание бэктеста. Иначе - false.
   static bool BACKTEST::IsEnding(void)
     {
      return(::TesterStatistics(STAT_BALANCEMIN) > 0);
     }
Slava
Модератор
12667
Slava  
fxsaber:
Или же в начале OnTester, т.к.


И результат замера вернуть в качестве кода возврата из OnTester
fxsaber
15765
fxsaber  
Slava:
И результат замера вернуть в качестве кода возврата из OnTester

Еще не проверял работу GetTickCount в тестере. Предполагал, что эта функция будет эмулироваться тестером, что в некоторых ситуациях может быть логичным.

Кстати, как в тестере понять текущее время с точностью до мс? Через SymbolInfoTick+Tick.time_msc получается узнать время вызова OnTick главного символа. И так даже проверять корректность работы режима проскальзывания тестера. Но другого способа, вроде, больше и нет.


Правда, хотел спросить о другом. Чтобы в оптимизаторе автоматизировать бенч с отбрасыванием первых и последних значений, нужно действовать через фреймы (для передачи OnTester-результата), или это исказит результат?

Slava
Модератор
12667
Slava  
GetTickCount в тестере работает штатно и не эмулируется, в отличие от Sleep
Slava
Модератор
12667
Slava  
fxsaber:

Правда, хотел спросить о другом. Чтобы в оптимизаторе автоматизировать бенч с отбрасыванием первых и последних значений, нужно действовать через фреймы (для передачи OnTester-результата), или это исказит результат?

Исказить не должен. Отсылается-то уже после замера. Попробуйте
fxsaber
15765
fxsaber  
Slava:
Для массовоых замеров не используйте микросекундный таймер. Используйте обычный миллисекундный GetTickCount.

GetMicrosecondCount тормозит тестер сильнее GetTickCount (или эмулируется)?

Или имелся в виду отказ от EventSetMillisecondTimer?

Slava
Модератор
12667
Slava  
fxsaber:

GetMicrosecondCount тормозит тестер сильнее GetTickCount (или эмулируется)?

Или имелся в виду отказ от EventSetMillisecondTimer?

Имеется в виду GetMicrosecondCount. Нельзя сказать определённо, тормозит ли он сервер. Он может оказать опосредованное влияние. Поэтому лучше использовать родной для системы GetTickCount

GetMicrosecondCount используется для замера коротких участков выполнения кода. Для замера выполнений большого множества OnTick лучше всё-таки GetTickCount

Попробуйте после получения стабильных результатов вместо GetTickCount использовать GetMicrosecondsCount. Потом расскажете здесь. Может быть я зря так волнуюсь

fxsaber
15765
fxsaber  
Есть две текущие исторические таблицы, данные которых доступны через History-функции - Orders-таблица и Deals-таблица.

На их содержимое возможно повлиять только через HistorySelect-функции. И происходит это следующим образом

  • HistorySelect и HistorySelectByPosition - влияют одновременно на обе таблицы.
  • HistoryDealSelect влияет ТОЛЬКО на Deals-таблицу (никак не влияет на текущую Orders-историческую таблицу).
  • HistoryOrderSelect влияет ТОЛЬКО на Orders-таблицу (никак не влияет на текущую Deals-историческую таблицу).

fxsaber
15765
fxsaber  
В ордерах возможно задание поля Request.expiration до LONG_MAX + 2 включительно. Его значение будет полноценно доступно через ORDER_TIME_EXPIRATION, если ордер является действующим (не в исторической таблице).
fxsaber
15765
fxsaber  
PositionIdentifier балансовых сделок равен нулю. Поэтому легко пишется, например, такая функция
// Возвращает сумму всех балансовых не торговых операций (начисления + списания)
double GetSumBalanceOperations( void )
{
  double Res = 0;
  
  if (HistorySelectByPosition(0))
    for (int i = HistoryDealsTotal() - 1; i >= 0; i--)
      Res += HistoryDealGetDouble(HistoryDealGetTicket(i), DEAL_PROFIT);
      
  return(Res);
}

DEAL_ENTRY таких сделок равен DEAL_ENTRY_IN (0).