Что не так с тиковой историей на MetaQuotes-Demo - страница 2

 
Сергей Таболин:

Я код подготовлю и выложу.

Могу предположить, что есть какие-то формулы  такого плана: (Close[i+1] - Close[i]) / Point  или (Open[i] - Bid) / Point.

Если выделенное цветом будет равно нулю, то Вы получите большое значение. Судя по всему, размер, которым Вы возмущены - 154203 - это и есть котировка фунта в 2015-м, 1,54203 деленная на Point. Сделайте проверку на нулевое значение и, возможно, проблема уйдет.

 

Написал скрипт для проверки.

//+------------------------------------------------------------------+
//|                                                       testNC.mq5 |
//|                                     Copyright 2021, Tabolin S.N. |
//|                           https://www.mql5.com/ru/users/vip.avos |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Tabolin S.N."
#property link      "https://www.mql5.com/ru/users/vip.avos"
#property version   "1.00"
#property script_show_inputs
//+------------------------------------------------------------------+
input int      max_dif        = 12000;          // Максимальный "разлёт" в пунктах
input datetime in_Start_Time  = D'2017.01.09';  // Дата начала проверки
//+------------------------------------------------------------------+
MqlTick  ticks[];
//+---------------------
int      t  = 0;
//+---------------------
datetime start_time     = TimeLocal();
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   datetime _Start_Time = in_Start_Time;
   uint     _Period_D1  = PeriodSeconds(PERIOD_W1);
   
   while(t > -10)
   {
      ResetLastError();
      ArrayFree(ticks);
      t = CopyTicksRange(Symbol(),ticks,COPY_TICKS_ALL,_Start_Time*1000,(_Start_Time+_Period_D1)*1000);
      if(t <= 0)  // Если скопированных тиков нет или ошибка
      {
         if(t < 0)   // Если ошибка
         {
            Print("LastError = ",GetLastError());
            //return(false);
         }
         else  Print(TimeToString(_Start_Time)," >>> Нет тиков...");
      }
      else        // Если тики есть
      {
         //Print(TimeToString(_Start_Time)," Тиков >>> ",t);
         //new_period = true;
         if(!bCT(t)) break;
      }
//+---------------------
      _Start_Time += _Period_D1;    // Следующий период
      if(_Start_Time > TimeCurrent()) break;
   }
   Print("<<< END >>> ", TimeToString(_Start_Time));
}
//+------------------------------------------------------------------+
bool  bCT(int ticks_size)
{
   MqlDateTime    tm;
   double         bid_prev = -10000.01;
   double         bid_last = -0.01;
   double         ask_prev = -10000.01;
   double         ask_last = -0.01;
   bool           err      = false;
   int            dif_bid, dif_ask;
   
   for(int i = 0; i < ticks_size; i++)
   {
      bid_last = ticks[i].bid;
      ask_last = ticks[i].ask;
      
      if(bid_prev != -10000.01)
      {
         dif_bid = int(MathAbs(bid_last - bid_prev) / Point());
         if(dif_bid > max_dif) err = true;
      }
      
      if(ask_prev != -10000.01)
      {
         dif_ask = int(MathAbs(ask_last - ask_prev) / Point());
         if(dif_ask > max_dif) err = true;
      }
      
      if(err)
      {
         Print("Скачок цены более допустимого: ", max_dif);
         Print(">>>>> ", bid_last, " :: ", bid_prev, " ::: ", dif_bid);
         Print(">>>>> ", ask_last, " :: ", ask_prev, " ::: ", dif_ask);
         TimeToStruct(ticks[i].time,tm);
         Print("День недели = ", tm.day_of_week, " >>> ", tm.hour, ":", tm.min, ":", tm.sec, " >>> ", tm.year, "-", tm.mon, "-", tm.day);
         Print("=========");
      }
      
      if(bid_last > 0.0) bid_prev = bid_last;
      if(ask_last > 0.0) ask_prev = ask_last;
      err      = false;
   }
   
   return(true);
}

Результат - весь 2017 год с плохими тиками. Далее всё ОК.

JO      0       12:23:19.552    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
EF      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.2157 ::: 121569
CN      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.21673 ::: 121673
LH      0       12:23:19.553    testNC (GBPUSD,H1)      День недели = 2 >>> 0:0:11 >>> 2017-1-10
JQ      0       12:23:19.553    testNC (GBPUSD,H1)      =========
KE      0       12:23:19.553    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
KS      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.2157 ::: 121569
QH      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.21673 ::: 121673
JO      0       12:23:19.553    testNC (GBPUSD,H1)      День недели = 2 >>> 0:0:19 >>> 2017-1-10
PJ      0       12:23:19.553    testNC (GBPUSD,H1)      =========
ER      0       12:23:19.553    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
II      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.2157 ::: 121569
GS      0       12:23:19.553    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.21673 ::: 121673
IR      0       12:23:19.553    testNC (GBPUSD,H1)      День недели = 2 >>> 0:0:21 >>> 2017-1-10
NG      0       12:23:19.553    testNC (GBPUSD,H1)      =========
.................
JS      0       12:23:24.416    testNC (GBPUSD,H1)      =========
KK      0       12:23:24.416    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
HQ      0       12:23:24.416    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.33259 ::: 133258
KI      0       12:23:24.416    testNC (GBPUSD,H1)      >>>>> 1.33267 :: 1.33266 ::: 1
IL      0       12:23:24.416    testNC (GBPUSD,H1)      День недели = 2 >>> 2:48:27 >>> 2017-11-28
HL      0       12:23:24.416    testNC (GBPUSD,H1)      =========
MP      0       12:23:24.416    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
ML      0       12:23:24.417    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.33259 ::: 133258
RF      0       12:23:24.417    testNC (GBPUSD,H1)      >>>>> 1.33266 :: 1.33267 ::: 1
HS      0       12:23:24.417    testNC (GBPUSD,H1)      День недели = 2 >>> 2:48:27 >>> 2017-11-28
MF      0       12:23:24.417    testNC (GBPUSD,H1)      =========
DN      0       12:23:24.420    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
PG      0       12:23:24.420    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.35016 ::: 135016
HS      0       12:23:24.420    testNC (GBPUSD,H1)      >>>>> 1.35014 :: 1.35023 ::: 8
OE      0       12:23:24.420    testNC (GBPUSD,H1)      День недели = 4 >>> 18:52:45 >>> 2017-11-30
QS      0       12:23:24.420    testNC (GBPUSD,H1)      =========
DK      0       12:23:24.420    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
PR      0       12:23:24.420    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.35016 ::: 135016
KH      0       12:23:24.420    testNC (GBPUSD,H1)      >>>>> 1.35016 :: 1.35023 ::: 7
ON      0       12:23:24.420    testNC (GBPUSD,H1)      День недели = 4 >>> 18:52:45 >>> 2017-11-30
QL      0       12:23:24.420    testNC (GBPUSD,H1)      =========
PP      0       12:23:24.695    testNC (GBPUSD,H1)      Скачок цены более допустимого: 12000
CM      0       12:23:24.695    testNC (GBPUSD,H1)      >>>>> 0.0 :: 1.33831 ::: 133830
HE      0       12:23:24.695    testNC (GBPUSD,H1)      >>>>> 1.33891 :: 1.33891 ::: 0
CP      0       12:23:24.695    testNC (GBPUSD,H1)      День недели = 5 >>> 0:19:17 >>> 2017-12-22
CI      0       12:23:24.695    testNC (GBPUSD,H1)      =========
CS      0       12:23:40.186    testNC (GBPUSD,H1)      <<< END >>> 2021.06.28 00:00


Пробовал запускать с 2011 года - до 14-го тиков не получил, а затем, до конца 17-го, такие же ошибки.

Так всё же что не так?

Файлы:
testNC.mq5  7 kb
20210621.log  1675 kb
 
Сергей Таболин:

Написал скрипт для проверки.

Результат - весь 2017 год с плохими тиками. Далее всё ОК.


Пробовал запускать с 2011 года - до 14-го тиков не получил, а затем, до конца 17-го, такие же ошибки.

Так всё же что не так?

Что сразу бросается в глаза

if(bid_prev != -10000.01)

В справке указано, что нельзя напрямую сравнивать два вещественных числа.

Документация по MQL5: Основы языка / Операции и выражения / Операции отношения
Документация по MQL5: Основы языка / Операции и выражения / Операции отношения
  • www.mql5.com
Операции отношения - Операции и выражения - Основы языка - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Vasiliy Pushkaryov:

Что сразу бросается в глаза

В справке указано, что нельзя напрямую сравнивать два вещественных числа.

Конечно нельзя, если разница может быть только в дробной части. А если сравнивать 1.005 и 150.006 то ничего не мешает написать if(1.005 != 150.006)

А с другой стороны, никаких сложностей и разницу сравнить с нулём…

 
Vasiliy Pushkaryov:

Что сразу бросается в глаза

В справке указано, что нельзя напрямую сравнивать два вещественных числа.

Какими бы добрыми советами, от каких бы то ни было добрых людей, не приходилось пользоваться, необходимо понимать суть вопроса. 

Переменная bid_prev при объявлении инициализируется значением = -10000.01. По этому проверять ее на равенство этому значению можно без каких либо хитростей с нормализацией. Смысл этой проверки в том, чтобы определить, присваивалось ли переменной реальное значение, или выполнение цикла только началось.

 

Читал и здесь и на хабре, что лучше такие сравнения не делать.



Не настолько подкован как вы, коллеги. Может с double будет все в порядке, в плане совпадений с точностью. Но я не рискую.

 

Спасибо, парни, за ответы, но! 

Вопрос то не в том, что не работает определение начала цикла, а в том, что не смотря на проверку > 0.0 цены тиков оказываются нулевыми! Я прекрасно понимаю, что если и в этом месте применить нормализацию, то, возможно, ошибок станет меньше. Тем не менее вопрос остаётся: почему в истории тиков значение может быть, например, 0.00000000001 ???

 

Значит, получаем массив с тиками, а в нем есть тики с нулевыми значениями цены. Стоит попробовать их отсеять, из оставшегося составить ряд, и его проверить на гэпы.

 
Dmitry Fedoseev:

Значит, получаем массив с тиками, а в нем есть тики с нулевыми значениями цены. Стоит попробовать их отсеять, из оставшегося составить ряд, и его проверить на гэпы.

Так ведь в том то и дело, что нулевой цены быть не должно! :

CopyTicksRange
Функция получает в массив ticks_array тики в формате MqlTick в указанном диапазоне дат.
Переменная типа MqlTick позволяет за один вызов функции SymbolInfoTick() получить значения Ask, Bid, Last и Volume.

У каждого тика всегда заполняются все параметры, независимо от того, изменились ли данные по сравнению с предыдущим тиком. 
Это позволяет всегда иметь актуальное состояние цен на любой момент времени без поиска предыдущих значений по тиковой истории. 
Например, с тиком могла измениться только цена бид, но в структуре помимо новой цены будут указаны и остальные параметры: предыдущая цена аск, объем и т.д.

Но даже её я пытаюсь отсеять и не получается. Почему? Очевидно - исторические тики несут в себе некорректную информацию.

 
Не должны, но не обязаны.
Причина обращения: