Скачать MetaTrader 5

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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Denis Sartakov
939
Denis Sartakov  

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

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
Vladimir Karputov
Модератор
65071
Vladimir Karputov  

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

Denis Sartakov
939
Denis Sartakov  
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);
}
//+------------------------------------------------------------------+
Denis Sartakov
939
Denis Sartakov  
Karputov Vladimir:

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

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

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

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

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

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

Dmitry Fedoseev
46488
Dmitry Fedoseev  
DenisSergeev:

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

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

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

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

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

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

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

Denis Sartakov
939
Denis Sartakov  
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
46488
Dmitry Fedoseev  

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

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

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

Denis Sartakov
939
Denis Sartakov  
Dmitry Fedoseev:

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

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

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

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

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

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

Dmitry Fedoseev
46488
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);

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

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

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

Denis Sartakov
939
Denis Sartakov  
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)
{
   
}
//+------------------------------------------------------------------+
Alexander Laur
8144
Alexander Laur  
DenisSergeev:

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

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

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

Попробуйте перед чтением данных канала обновить график:

ChartRedraw();
12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий