Мультивалютные проблемы - страница 2

 

Interesting Ну понятное дело что надо проверять время каждого бара, например я это делал так:

#property indicator_separate_window
#property indicator_buffers 2
#property indicator_plots   2
//--- plot Label1
#property indicator_label1  "I1"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- plot Label2
#property indicator_label2  "I2"
#property indicator_type2   DRAW_LINE
#property indicator_color2  Green
#property indicator_style2  STYLE_SOLID
#property indicator_width2  1
//--- indicator buffers
double         I1Buffer[];
double         I2Buffer[];
int OnInit()
  {
   SetIndexBuffer(0,I1Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,I2Buffer,INDICATOR_DATA);
   return(0);
  }
int OnCalculate (const int rates_total,      // размер входных таймсерий
                 const int prev_calculated,  // обработано баров на предыдущем вызове
                 const datetime& time[],     // Time
                 const double& open[],       // Open
                 const double& high[],       // High
                 const double& low[],        // Low
                 const double& close[],      // Close
                 const long& tick_volume[],  // Tick Volume
                 const long& volume[],       // Real Volume
                 const int& spread[])        // Spread
  {
   string Symbol_1="EURUSD",Symbol_2="GBPUSD";
   if(rates_total<1) return(0);
   double Arr1[],Arr2[];
   int end,rez0,rez1,rez_0,rez_1;
   datetime ld1[],ld2[];
   end=MathMin((int)SeriesInfoInteger(Symbol_1,0,SERIES_BARS_COUNT)-1,(int)SeriesInfoInteger(Symbol_2,0,SERIES_BARS_COUNT)-1);
   end=MathMin(end,rates_total-prev_calculated+1);
   rez0=CopyClose(Symbol_1,PERIOD_CURRENT, 0,end, Arr1);
   rez_0=CopyTime(Symbol_1,PERIOD_CURRENT, 0,end, ld1);
   if(rez0==-1){Print("Ошибка копирования ",Symbol_1," ",GetLastError()); return(0);}
   if(rez0!=rez_0){Print("Не сходятся цены с временем",Symbol_1," ",GetLastError()); return(0);}
   rez1=CopyClose(Symbol_2,PERIOD_CURRENT, 0,end, Arr2);
   rez_1=CopyTime(Symbol_2,PERIOD_CURRENT, 0,end, ld2);
   if(rez1==-1){Print("Ошибка копирования ",Symbol_2," ",GetLastError()); return(0);}
   if(rez1!=rez_1){Print("Не сходятся цены с временем",Symbol_2," ",GetLastError()); return(0);}
   if(rez1!=rez0){Print("Ошибка Синхронизации"); return(0);}
  
   ArraySetAsSeries(Arr1,true);
   ArraySetAsSeries(Arr2,true);
   ArraySetAsSeries(ld1,true);
   ArraySetAsSeries(ld2,true);
    
   int li=rates_total-1;
   I1Buffer[li]=Arr1[0]+0.26;
   I2Buffer[li]=Arr2[0];
   li--;
  
   int shift1=0,shift2=0;  
   for(int i=1;i<end-MathMax(shift2,shift1);i++)
     {      
      if(time[li]==ld1[i+shift1])I1Buffer[li]=Arr1[i+shift1]+0.26;
      else if(time[li]>ld1[i+shift1]&&i!=0){shift1--;I1Buffer[li]=I1Buffer[li+1];}
      else if(time[li]<ld1[i+shift1]&&i!=0){shift1++;I1Buffer[li]=I1Buffer[li+1];}
            
      if(time[li]==ld2[i+shift2])I2Buffer[li]=Arr2[i+shift2];
      else if(time[li]>ld2[i+shift2]&&i!=0){shift2--;I2Buffer[li]=I2Buffer[li+1];}
      else if(time[li]<ld2[i+shift2]&&i!=0){shift2++;I2Buffer[li]=I2Buffer[li+1];}
      li--;
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+
Но здесь речь не о том, в тестере происходит чтото непонятное, особенно до часа ночи

 

 

 
Interesting:
Если так, то тут проблемы тестера. Но алгоритм кода все равно не очень подходит для выполнения поствленой задачи (ТИМХО)...
Это для того чтоб не загромождать, и сразу показать проблемму.
 
ddd06:
Это для того чтоб не загромождать, и сразу показать проблемму.

Я несколько видоизменил Ваш код

//+------------------------------------------------------------------+
//|                                                       Prover.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
int     bars1,bars2,i;
datetime time1[],time2[];
double   Arr1[],Arr2[];
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(i>100)return;
//---
   if(bars1==Bars("EURUSD",_Period) && bars2==Bars("GBPUSD",_Period)) return;
   bars1=Bars("EURUSD",_Period);
   bars2=Bars("GBPUSD",_Period);
   i++;
//---
   CopyTime("EURUSD",_Period,1,1,time1);
   CopyTime("GBPUSD",_Period,1,1,time2);
   CopyClose("EURUSD",_Period,1,1,Arr1);
   CopyClose("GBPUSD",_Period,1,1,Arr2);
   Print("Время EURUSD "+TimeToString(time1[0],TIME_DATE|TIME_MINUTES),
         "  Время GBPUSD "+TimeToString(time2[0],TIME_DATE|TIME_MINUTES),
         "    mas1(EURUSD)-",Arr1[0],"   mas2(GBPUSD)-",Arr2[0],
         "    bars1=",bars1,"   bars2=",bars2);
  }
//+------------------------------------------------------------------+
Проверка идёт сразу по двум парам. Теперь "отсутствие" минутного бара GBPUSD в 01:03 становится понятным. Все сгенерированные тики сортируются по времени и по идентификатору символа. Время 01:03:00 совпало у тиков по EURUSD и GBPUSD. Однако, в силу сортировки тик EURUSD пришёл раньше, то есть на этот момент соответствующий бар GBPUSD ещё не начал формироваться (в общем-то, как в жизни). Это место менять не будем.

 

А вот с явным отсутствием "чужих" баров в начале первых суток тестирования будем разбираться. Спасибо, что представили код, иллюстрирующий проблему.

 
stringo:
Все сгенерированные тики сортируются по времени и по идентификатору символа.

 А почему тогда некоторые совпадают? 

 
ddd06:

 А почему тогда некоторые совпадают? 

Я ошибся, сказав про сортировку по идентификатору символа. Её убрали ради повышения скорости генерации.

Поэтому порядок следования тиков с одним и тем же временем неопределён. 

 
stringo:

Я ошибся, сказав про сортировку по идентификатору символа. Её убрали ради повышения скорости генерации.

Поэтому порядок следования тиков с одним и тем же временем неопределён. 

Я проверил свой индикатор, вродебы стало совпадать.

Значит действительно надо проверять сформированность баров на всех инструментах.

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

 
Предлагаю рассмотреть каркас простого мультивалютного/мультипериодного эксперта, основанного на таймере
Файлы:
example.mq5  12 kb
 
Kos:
Предлагаю рассмотреть каркас простого мультивалютного/мультипериодного эксперта, основанного на таймере

Чтото я не очень уверен в слове "простого"

А что мы будем делать если по одному из инструментов тики не прийдут и соответственно бар не будет сформирован? 

 
ddd06:

Чтото я не очень уверен в слове "простого"

А что мы будем делать если по одному из инструментов тики не прийдут и соответственно бар не будет сформирован? 

Текущий вариант построен с учетом жесткого контроля новых баров на всех инструментах/таймфреймах.

В принципе, чтобы не ждать какой-то инструмент(это может быть например из-за разного торгового/котировочного времени), а продолжать работу, можно немного поправить код следующим образом:

if(Tics[i]>=NewBars[i][COUNT_PERIODS-1])   // появился новый бар на младшем TF
  {
   BarsMonitoring();                       // запускаем мониторинг появления новых баров на остальных TF
  }
 

Для получения времени открытия текущего (последнего бара) по символу/таймфрейму есть более короткий путь:

datetime lastBarOpenTime=(datetime)SeriesInfoInteger(Symbol(),Period(),SERIES_LASTBAR_DATE);

Смотрите Информация об исторических данных по инструменту