Тестер: ошибка моделирования тиков на всех таймфреймах на модели все тики

 

Терминал: http://www.alpari.org/files/mt4setup.exe - 207 build (17 july 2007)

PeriodConverter: 'period converter ALL'

1. Поставил терминал.

2. Открыл демо-счет

3. Меню->Сервис->Настройки->Макс. баров в истории и окне == 2147483647

4. Импортировал USDJPY-котировки.

5. На оффлайн-графике USDJPY запустил PeriodConverter.

6. Прогнал в тестере по всем тикам на всех таймфреймах TestTicks.mq4:

extern string FileName = "TestTicks.txt";
 
int handle;
double tOpen, tHigh, tLow, tClose;
int CountErrors;
 
int PrevTime;
 
 
int init()
{
  PrevTime = Time[0];
  tOpen = Bid;
  tHigh = Bid;
  tLow = Bid;
  tClose = Bid;
  CountErrors = 0;
 
  handle=FileOpen(FileName,FILE_READ|FILE_WRITE, "	");
  FileSeek(handle, 0, SEEK_END);
 
  return(0);
}
 
int deinit()
{
  string Str;
  
  Str = "Bar Errors = " + DoubleToStr(100.0 * CountErrors / Bars, 2) + "%";
  
  Print(Str);
  FileWrite(handle, Str);
  
  FileClose(handle);
  
  return(0);
}
 
int start()
{
  string Str;
  
  if (PrevTime == Time[0])
  {
    if (Bid > tHigh)
      tHigh = Bid;
    else if (Bid < tLow)
      tLow = Bid;
  }
  else
  {
    PrevTime = Time[0];
    
    if ((NormalizeDouble(tOpen - Open[1], Digits) != 0) ||
        (NormalizeDouble(tHigh - High[1], Digits) != 0) ||
        (NormalizeDouble(tLow - Low[1], Digits) != 0) ||
        (NormalizeDouble(tClose - Close[1], Digits) != 0))
    {
      Str = TimeToStr(Time[1]);
      Print(Str);
      FileWrite(handle, Str);
      CountErrors++;
    }
        
    tOpen = Bid;
    tHigh = Bid;
    tLow = Bid;
  }
 
  tClose = Bid;
 
  return(0);
}

7. Обнаружились несоответствия между историческими и моделируемыми котировками.

В приложенном файле указаны все бары с несоответствиями.

На M1 все ошибочные бары имеют объем либо 2, либо 3.

Файлы:
errors-log.zip  14 kb
 
Прочитайте вот эту ветку 'Ошибка моделирования тиков на М5' до конца и многое проясниться

С уважением, Артем
 

Ошибка в тестере при моделировании тиков есть на ВСЕХ ТАЙМФРЕЙМАХ.

 

В 207 билде от 25-го июля на периоде H4 баров с ошибкой моделирования тиков стало больше 20%!

Подробности в прилагаемом файле.

Файлы:
 
Я немного подпраил Вашего советника:

//+------------------------------------------------------------------+
//|                                              CheckHighAndLow.mq4 |
//|                      Copyright © 2007, MetaQuotes Software Corp. |
//|                                        https://www.metaquotes.net/ru/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2007, MetaQuotes Software Corp."
#property link      "https://www.metaquotes.net/ru/"
 
extern string FileName = "TestTicks.txt";
 
int handle;
double tOpen, tHigh, tLow, tClose;
int CountErrors;
 
int PrevTime;
 
 
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
  PrevTime = Time[0];
  tOpen = Bid;
  tHigh = Bid;
  tLow = Bid;
  tClose = Bid;
  CountErrors = 0;
 
  handle=FileOpen(FileName,FILE_READ|FILE_WRITE, "\t");
  FileSeek(handle, 0, SEEK_END);
 
  return(0);
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
  string Str;
  
  Str = "Bar Errors = " + DoubleToStr(100.0 * CountErrors / Bars, 2) + "%";
  
  Print(Str);
  FileWrite(handle, Str);
  
  FileClose(handle);
   
//----
   return(0);
  }
 
//+------------------------------------------------------------------+
//| right comparison of 2 doubles                                    |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2, int Dig,double accuracy)
  {
   if(NormalizeDouble(MathAbs(number1-number2),Dig)>accuracy) return(true);
   else return(false);
  }
 
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
  string Str;
  
  if (PrevTime == Time[0])
  {
    if (Bid > tHigh)
      tHigh = Bid;
    else if (Bid < tLow)
      tLow = Bid;
  }
  else
  {
    PrevTime = Time[0];
    
    if (CompareDoubles(tOpen,Open[1], Digits,Point) ||
        CompareDoubles(tHigh,High[1], Digits,Point) ||
        CompareDoubles(tLow,Low[1], Digits,Point) ||
        CompareDoubles(tClose,Close[1], Digits,Point))
      {
        Str = TimeToStr(Time[1]) + ", Volume = " + DoubleToStr(Volume[1], 0);
        Print(Str);
        FileWrite(handle, Str);
        CountErrors++;
      }
        
    tOpen = Bid;
    tHigh = Bid;
    tLow = Bid;
  }
 
  tClose = Bid;
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

И прогнал на EURUSD по всем таймфреймам:

2007.07.27 12:20:23 2007.07.27 10:19 CheckHighAndLow EURUSD, M1: Bar Errors = 0. 00%
2007.07.27 12:20:12 CheckHighAndLow started for testing
2007.07.27 12:19:24 2007.07.27 10:19 CheckHighAndLow EURUSD, M5: Bar Errors = 0. 00%
2007.07.27 12:19:16 CheckHighAndLow started for testing
2007.07.27 12:17:38 2007.07.23 16:29 CheckHighAndLow EURUSD, M15: Bar Errors = 0. 00%
2007.07.27 12:17:30 CheckHighAndLow started for testing
2007.07.27 12:16:52 2007.07.23 16:29 CheckHighAndLow EURUSD, M30: Bar Errors = 0. 00%
2007.07.27 12:16:52 2007.07.23 14:00 CheckHighAndLow EURUSD, M30: 2007. 07. 23 13:30, Volume = 107
2007.07.27 12:16:45 CheckHighAndLow started for testing
2007.07.27 12:15:05 2007.07.23 16:59 CheckHighAndLow EURUSD, H1: Bar Errors = 0. 00%
2007.07.27 12:15:05 2007.07.23 14:00 CheckHighAndLow EURUSD, H1: 2007. 07. 23 13:00, Volume = 281
2007.07.27 12:14:46 CheckHighAndLow started for testing
2007.07.27 12:13:44 2007.07.25 15:59 CheckHighAndLow EURUSD, H4: Bar Errors = 0. 01%
2007.07.27 12:13:44 2007.07.23 16:00 CheckHighAndLow EURUSD, H4: 2007. 07. 23 12:00, Volume = 1210
2007.07.27 12:13:44 2007.07.20 04:00 CheckHighAndLow EURUSD, H4: 2007. 07. 20 00:00, Volume = 477
2007.07.27 12:13:36 CheckHighAndLow started for testing
2007.07.27 12:12:39 2007.07.27 23:59 CheckHighAndLow EURUSD, Daily: Bar Errors = 0.04%
2007.07.27 12:12:39 2007.07.24 00:00 CheckHighAndLow EURUSD, Daily: 2007.07. 23 00:00, Volume = 4868
2007.07.27 12:12:31 CheckHighAndLow started for testing
 

Прилагаю файл ошибок, после прогона по всем таймфреймам вашей версии советника. Котировки и валютная пара указаны в первом посте.

Также хочу заметить, что ваша функция

//+------------------------------------------------------------------+
//| right comparison of 2 doubles                                    |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2, int Dig,double accuracy)
  {
   if(NormalizeDouble(MathAbs(number1-number2),Dig)>accuracy) return(true);
   else return(false);
  }
является ошибочной. Убедиться в этом можно, если распечатать значения несовпадающих double чисел по "моему" признаку.
Файлы:
 
Объясните.
 

Скрипт, показывающий ошибку вашей функции сравнения двух double:

#define MAX_NUM 10
 
//+------------------------------------------------------------------+
//| right comparison of 2 doubles                                    |
//+------------------------------------------------------------------+
bool CompareDoubles(double number1,double number2, int Dig,double accuracy)
  {
   if(NormalizeDouble(MathAbs(number1-number2),Dig)>accuracy) return(true);
   else return(false);
  }
 
int start()
{
  int i;
  double Num1, Num2;
  string Str;
  
  for (i = 0; i <= MAX_NUM; i++)
  {
    Num1 = i * Point;
    Num2 = Num1 + Point;
    
    if (!CompareDoubles(Num1, Num2, Digits, Point))
    {
      Str = "CompareDoubles: " + DoubleToStr(Num1, Digits) +
                        " == " + DoubleToStr(Num2, Digits);
      Print(Str);
    }
  }
  
  return(0);
}
 

Советник, показывающий (логи в файле) ошибки тестера:

#define MAX_NUM 4
 
extern string FileName = "TestTicks.txt";
 
int handle;
int CountErrors;
 
double TesterNum[MAX_NUM];
string Name[MAX_NUM][2] = {", TesterOpen = ", ", HistoryOpen = ",
                           ", TesterHigh = ", ", HistoryHigh = ",
                           ", TesterLow =  ", ", HistoryLow =  ",
                           ", TesterClose =", ", HistoryClose ="};
 
int PrevTime;
 
int init()
{
  PrevTime = Time[0];
  TesterNum[0] = Bid;
  TesterNum[1] = Bid;
  TesterNum[2] = Bid;
  TesterNum[3] = Bid;
  CountErrors = 0;
 
  handle = FileOpen(FileName, FILE_READ|FILE_WRITE, "\t");
  FileSeek(handle, 0, SEEK_END);
 
  return(0);
}
 
int deinit()
{
  string Str;
  
  Str = "Bar Errors = " + DoubleToStr(100.0 * CountErrors / Bars, 2) + "%";
  
  Print(Str);
  FileWrite(handle, Str);
  
  FileClose(handle);
  
  return(0);
}
 
double HistoryNum( int Index )
{
  switch(Index)
  {
   case 0:
     return(Open[1]);
   case 1:
     return(High[1]);
   case 2:
     return(Low[1]);
   default:
     return(Close[1]);
  }
}
 
int start()
{
  int i;
  string Str;
  
  if (PrevTime == Time[0])
  {
    if (Bid > TesterNum[1])
      TesterNum[1] = Bid;
    else if (Bid < TesterNum[2])
      TesterNum[2] = Bid;
  }
  else
  {
    PrevTime = Time[0];
    
    for (i = 0; i < MAX_NUM; i++)
      if (NormalizeDouble(TesterNum[i] - HistoryNum(i), Digits) != 0)
      {
        Str = TimeToStr(Time[1]) + ", Volume = " + DoubleToStr(Volume[1], 0) + Name[i][0] +
              DoubleToStr(TesterNum[i], Digits) + Name[i][1] + DoubleToStr(HistoryNum(i), Digits);
        Print(Str);
        FileWrite(handle, Str);
        CountErrors++;
      }
        
    TesterNum[0] = Bid;
    TesterNum[1] = Bid;
    TesterNum[2] = Bid;
  }
 
  TesterNum[3] = Bid;
 
  return(0);
}
Файлы:
 

Уважаемые разработчики, исправьте ошибки в тестере!

На H4 более 20% баров с ошибками, есть расхождения свыше 10 пунктов на бар.

 
getch:
является ошибочной. Убедиться в этом можно, если распечатать значения несовпадающих double чисел по "моему" признаку.

Действительно, надо accuracy брать не Point , а Point/2 , иначе соседние значения котировок не различимы.