ObjectGetValueByTime(...) - эта функция работает неправильно...

 

Вот такой код для проверки:

1. рисуется канал OBJ_CHANNEL, через точки 1-2 проводится линия 0 , через точку 3 проводится линия 1 параллельно линии 0

2. с помощью этой функции вычисляются значения обоих линий в момент времени Time[1]

   

double d_line_0_12 = ObjectGetValueByTime(0,"Channel",Time[1],0);                                        

double d_line_1_33 = ObjectGetValueByTime(0,"Channel",Time[1],1); 

 

значение линии 0 правильное, для линии 1 получаем какую-то чепуху.

Программу для проверки прикрепляю... 

Файлы:
Test.mq4  4 kb
 

Не стремитесь получать значение в OnInit() - так как это подготовительная функция. В OnInit() создайте канал. А значения получайте уже в OnTick(). Всё получится.

 
Karputov Vladimir:

Не стремитесь получать значение в OnInit() - так как это подготовительная функция. В OnInit() создайте канал. А значения получайте уже в OnTick(). Всё получится.

Да, друг, ты прав !

Спасибо !

Так и сделал, все работает:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
   CreateChannel();
   EventSetTimer(60);
      
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();
}      

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
   ObjectGetValueByTimeTest();   
}
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
{
   
}
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   
}
//+------------------------------------------------------------------+
struct k_Point
{
   datetime dt_Time;
   double   d_Price;
};
//+------------------------------------------------------------------+
void ObjectGetValueByTimeTest()
{
                                        
   double d_line_0_12 = ObjectGetValueByTime(0,"Channel",Time[1],0);                                        
   double d_line_1_33 = ObjectGetValueByTime(0,"Channel",Time[1],1); 
   
   Print(" d_line_0_12=",d_line_0_12);                                      
   Print(" d_line_1_33=",d_line_1_33);                                      
}
//+------------------------------------------------------------------+
void CreateChannel()
{
   ObjectsDeleteAll();
   k_Point kPoint_1;
   k_Point kPoint_2;
   k_Point kPoint_3;
   
   kPoint_1.dt_Time = Time[5];
   kPoint_1.d_Price = Low[5];
   
   kPoint_2.dt_Time = Time[1];
   kPoint_2.d_Price = High[1];
   
   kPoint_3.dt_Time = Time[5];
   kPoint_3.d_Price = High[5];
   
   ObjectCreate("Channel",OBJ_CHANNEL,0,
                                        kPoint_1.dt_Time,kPoint_1.d_Price,
                                        kPoint_2.dt_Time,kPoint_2.d_Price,
                                        kPoint_3.dt_Time,kPoint_3.d_Price);
}
//+------------------------------------------------------------------+
 
Karputov Vladimir:

Не стремитесь получать значение в OnInit() - так как это подготовительная функция. В OnInit() создайте канал. А значения получайте уже в OnTick(). Всё получится.

проблема собственно не в OnInit(), а в том что после создания объекта необходимо подождать немного,

например 1 сек, только после этого  функция ObjectGetValueByTime(...) дает нормальные значения,

но в Тестере и это не помогает.... 

эта функция  ChartRedraw()  тоже не помагает,

одно только средство нашел - рисовать объект на одном тике, а обращаться за значениями линий этого  объекта на следующем тике ...

 
DenisSergeev:

1.  проблема собственно не в OnInit(), а в том что после создания объекта необходимо подождать немного,

например 1 сек, только после этого  функция ObjectGetValueByTime(...) дает нормальные значения,

2. но в Тестере и это не помогает.... 

эта функция  ChartRedraw()  тоже не помагает,

одно только средство нашел - рисовать объект на одном тике, а обращаться за значениями линий этого  объекта на следующем тике ...

1. Скорее всего дело в том, что появились новые бары и нарисовался нормальный канал.

2. В тестере не будет работать.

 
Dmitry Fedoseev:

1. Скорее всего дело в том, что появились новые бары и нарисовался нормальный канал.

2. В тестере не будет работать.

все работает отлично, в том числе и в тестере.

фишка заключается в том, что чтение  значений линий этой функцией  ObjectGetValueByTime  на том же тике, на котором канал создается, 

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

вот тестовая прога:

 

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
struct k_Point
{
   datetime dt_Time;
   double   d_Price;
};
//+------------------------------------------------------------------+
struct k_Channel
{
   string   sw_Name;
   datetime dt_ChanID;
   k_Point  kLine_0_Points[2];
   k_Point  kLine_1_Point;
};
//+------------------------------------------------------------------+
k_Channel gkChan;
datetime gdt_ChanID;
//+------------------------------------------------------------------+

int OnInit()
{
   gkChan.sw_Name   = "Channel";
   gkChan.dt_ChanID = 0;
   
   gkChan.kLine_0_Points[0].dt_Time = Time[5];
   gkChan.kLine_0_Points[0].d_Price = Low[5];
   gkChan.kLine_0_Points[1].dt_Time = Time[1];
   gkChan.kLine_0_Points[1].d_Price = High[1];
   
   gkChan.kLine_1_Point.dt_Time = Time[5];
   gkChan.kLine_1_Point.d_Price = High[5];
   
   EventSetTimer(60);
      
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(gkChan.sw_Name);
   EventKillTimer();
}      
//+------------------------------------------------------------------+
void OnTick()
{
   gdt_ChanID = Time[1];
   if (gkChan.dt_ChanID != gdt_ChanID)
   {
      ObjectDelete(gkChan.sw_Name);
      
      gkChan.dt_ChanID = gdt_ChanID;
      gkChan.kLine_0_Points[0].dt_Time = Time[5];
      gkChan.kLine_0_Points[0].d_Price = Low[5];
      gkChan.kLine_0_Points[1].dt_Time = Time[1];
      gkChan.kLine_0_Points[1].d_Price = High[1];
   
      gkChan.kLine_1_Point.dt_Time = Time[5];
      gkChan.kLine_1_Point.d_Price = High[5];
      ObjectCreate(gkChan.sw_Name,OBJ_CHANNEL,0,gkChan.kLine_0_Points[0].dt_Time,
                                                gkChan.kLine_0_Points[0].d_Price,
                                                gkChan.kLine_0_Points[1].dt_Time,
                                                gkChan.kLine_0_Points[1].d_Price, 
                                                gkChan.kLine_1_Point.dt_Time,
                                                gkChan.kLine_1_Point.d_Price);
      return;                                                
   }
   double d_line_0 = ObjectGetValueByTime(0,gkChan.sw_Name,Time[1],0);                                        
   double d_line_1 = ObjectGetValueByTime(0,gkChan.sw_Name,Time[1],1); 
   
   Print(" d_line_0=",d_line_0);                                      
   Print(" d_line_1=",d_line_1);                                      
}
//+------------------------------------------------------------------+
void OnTimer()
{
   
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   
}
//+------------------------------------------------------------------+
 

Чудеса конечно, но у меня все нормально работает, значения доступны сразу после создания на этом же тике.

Вы создаете канал не глядя по неизвестно каким данным,  поэтому одна линия здесь, вторая неизвестно где. Попробуйте создавать канал по данным дающим заведомо нормальное расположение канала.

В тестере при оптимизации графические объекты не работают.

 
Dmitry Fedoseev:

Чудеса конечно, но у меня все нормально работает, значения доступны сразу после создания на этом же тике.

Вы создаете канал не глядя по неизвестно каким данным,  поэтому одна линия здесь, вторая неизвестно где. Попробуйте создавать канал по данным дающим заведомо нормальное расположение канала.

В тестере при оптимизации графические объекты не работают.

дима, слушай, ты говоришь "значения доступны сразу после создания на этом же тике.", если не затруднит,

кинь эту прогу, или какую-нибудь демо вырезку  из нее.

а канал у меня нормальный получается, можешь посмотреть:

 
DenisSergeev:

дима, слушай, ты говоришь "значения доступны сразу после создания на этом же тике.", если не затруднит,

кинь эту прогу, или какую-нибудь демо вырезку  из нее.

а канал у меня нормальный получается, можешь посмотреть:


   if(ObjectFind(0,"ch")==0){
      
      ObjectDelete(0,"ch");
      return;
   }      
   
   ObjectCreate(0,"ch",OBJ_CHANNEL,0,0,0);
   ObjectMove(0,"ch",0,StringToTime("2014.12.31 18:55"),1.211641);
   ObjectMove(0,"ch",1,StringToTime("2014.12.31 19:55" ),1.211641);   
   ObjectMove(0,"ch",2,StringToTime("2014.12.31 18:55"),1.212641);   
   
  
   double d_line_0 = ObjectGetValueByTime(0,"ch",TimeCurrent(),0);                                        
   double d_line_1 = ObjectGetValueByTime(0,"ch",TimeCurrent(),1); 
   
   Comment(GetTickCount()+" "+d_line_0+" "+d_line_1);
   
   ChartRedraw();
   
   GlobalVariableSet("v0",d_line_0);
   GlobalVariableSet("v1",d_line_1);

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

Запускаю в визуальном режиме и смотрю комментарий на графике. 

В конце глобальные переменные для проверки при не визуальном тестировании и оптимизации.

 
Dmitry Fedoseev:


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

Запускаю в визуальном режиме и смотрю комментарий на графике. 

В конце глобальные переменные для проверки при не визуальном тестировании и оптимизации.

странно, вот я поменял свою прогу так, чтобы чтение значений линий происходило на том же тике,

на котором  создается канал, посмотри, при чтение на том же тике, значение линии, построенной

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

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
struct k_Point
{
   datetime dt_Time;
   double   d_Price;
};
//+------------------------------------------------------------------+
struct k_Channel
{
   string   sw_Name;
   datetime dt_ChanID;
   k_Point  kLine_0_Points[2];
   k_Point  kLine_1_Point;
};
//+------------------------------------------------------------------+
k_Channel gkChan;
datetime gdt_ChanID;
//+------------------------------------------------------------------+

int OnInit()
{
   gkChan.sw_Name   = "Channel";
   gkChan.dt_ChanID = 0;
   
   gkChan.kLine_0_Points[0].dt_Time = Time[5];
   gkChan.kLine_0_Points[0].d_Price = Low[5];
   gkChan.kLine_0_Points[1].dt_Time = Time[1];
   gkChan.kLine_0_Points[1].d_Price = High[1];
   
   gkChan.kLine_1_Point.dt_Time = Time[5];
   gkChan.kLine_1_Point.d_Price = High[5];
   
   EventSetTimer(60);
      
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   ObjectDelete(gkChan.sw_Name);
   EventKillTimer();
}      
//+------------------------------------------------------------------+
void OnTick()
{
   gdt_ChanID = Time[1];
   if (gkChan.dt_ChanID != gdt_ChanID)
   {
      ObjectDelete(gkChan.sw_Name);
      
      gkChan.dt_ChanID = gdt_ChanID;
      gkChan.kLine_0_Points[0].dt_Time = Time[5];
      gkChan.kLine_0_Points[0].d_Price = Low[5];
      gkChan.kLine_0_Points[1].dt_Time = Time[1];
      gkChan.kLine_0_Points[1].d_Price = High[1];
   
      gkChan.kLine_1_Point.dt_Time = Time[5];
      gkChan.kLine_1_Point.d_Price = High[5];
      ObjectCreate(gkChan.sw_Name,OBJ_CHANNEL,0,gkChan.kLine_0_Points[0].dt_Time,
                                                gkChan.kLine_0_Points[0].d_Price,
                                                gkChan.kLine_0_Points[1].dt_Time,
                                                gkChan.kLine_0_Points[1].d_Price, 
                                                gkChan.kLine_1_Point.dt_Time,
                                                gkChan.kLine_1_Point.d_Price);
//      return;                                                
   }
   double d_line_0 = ObjectGetValueByTime(0,gkChan.sw_Name,Time[1],0);                                        
   double d_line_1 = ObjectGetValueByTime(0,gkChan.sw_Name,Time[1],1); 
   
   Print(" d_line_0=",d_line_0);                                      
   Print(" d_line_1=",d_line_1);                                      
}
//+------------------------------------------------------------------+
void OnTimer()
{
   
}
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
   
}
//+------------------------------------------------------------------+
 
DenisSergeev:

странно, вот я поменял свою прогу так, чтобы чтение значений линий происходило на том же тике,

на котором  создается канал, посмотри, при чтение на том же тике, значение линии, построенной

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

Ага. Есть такое. Надо попробовать на обычный график повесить и посмотреть, что будет на открытии нового бара. Может подразумевается, что в тестере вообще не стоит использовать графические объекты. Их на самом деле нет смысла использовать, оптимизироваться не будет. Если на обычном графике будет тоже самое, тогда точно баг.
Причина обращения: