Графическое перекрестие трендовых линий, функция ObjectGetValueByTime что с ней не так?

 

Привет программситам.

Столкнулся с проблемой передачи данных с разных графиков цены, с функции ObjectGetValueByTime не передает корректно данные в чем может быть проблема.

Создаю линию трендовую Rw2 недельную в функции PlotLinew

PlotLinew("Rw2["+shift+"]"+z,Rw2, Rw1,0,clrNONE);  // косая линия сверху вниз W1

далее, определяю бар функцией iBarShift недельный по дневной свече

ChartRedraw (); //Вызывает принудительную перерисовку указанного графика.
   Sleep (50);  
   
i = iBarShift(NULL,PERIOD_W1,timed1); // бар по времени дневной свечи на недельном периоде

Определяю цену трендовой линии недельной на координате "у" времени дневного бара.

Rw2_1  = ObjectGetValueByTime(0,"Rw2["+i+"]"+z,timed1,0);      Rw2_2  = ObjectGetValueByTime(0,"Rw2["+i+"]"+z,timed2,0);

вбиваю параметры для нахождения координат перекрестия двух линий, (где R1 и R2 являются координатами дневной трендовой линии, а Rw2_1 и Rw2_2 недельные) функциии  PriceY TimeX 

     //НАЙДЕМ ПЕРЕКРЕСТИЕ ДНЕВНЫХ И НЕДЕЛЬНЫХ ЛИНИЙ
     
     // Цена перекрестия
     pricy1 = PriceY(R1, R2, R2, R1, timed1,time_d2,timed1,time_d2);
     pricy2 = PriceY(R1, R2, Rw2_1, Rw2_2, timed1,time_d2,timed1,time_d2);
     
     // Время перекрестия
     timex1 = TimeX (R1, R2, R2, R1, timed1,time_d2,timed1,time_d2);
     timex2 = TimeX (R1, R2, Rw2_1, Rw2_2, timed1,time_d2,timed1,time_d2);

В итоге  по перекрестию дневных  линий R1, R2, R2, R1 - есть перекрестие, а по дневным и недельным данным R1, R2, Rw2_1, Rw2_2 идет разброс по графику.

время передается в функцию для двух линий одинаковое   timed1,  time_d2,  timed1,  time_d2

Сами функции перекрестия PriceY, TimeX

// ФУНКЦИЯ ПЕРЕКРЕСТИЯ КООРДИНАТ ДЛЯ ПОИСКА ЦЕНЫ 

double PriceY(double y1, double y2, double y3, double y4, double x1, double x2, double x3, double x4)
    { 
    //y1, y2, y3, y4; //цена  линий 
    //x1, x2, x3, x4; //время  линий      
    double k1, k3;
    double X,Y;
    
    k1=(y2-y1)/(x2-x1); 
    k3=(y4-y3)/(x4-x3);
    
    if(k1 != k3)
      {
      X = NormalizeDouble((y1 - y3 + k3*x3 - k1*x1)/(k3 - k1),0); // время перекрестия
      Y = NormalizeDouble( y1 + k1*(X - x1),_Digits);             // цена  перекрестия
      }
if(Y != 0) return(Y); else return(0);
}  
//+----------------------------------------------------------------------------+

// ФУНКЦИЯ ПЕРЕКРЕСТИЯ КООРДИНАТ ДЛЯ ПОИСКА ВРЕМЕНИ

datetime TimeX(double y1, double y2, double y3, double y4, double x1, double x2, double x3, double x4)
    {   
    //y1, y2, y3, y4; //цена  линий 
    //x1, x2, x3, x4; //время  линий          
    double k1, k3;
    double X,Y;
    
    k1=(y2-y1)/(x2-x1); 
    k3=(y4-y3)/(x4-x3);
    
    if(k1 != k3)
      {
      X = NormalizeDouble((y1 - y3 + k3*x3 - k1*x1)/(k3 - k1),0); // время перекрестия
      Y = NormalizeDouble( y1 + k1*(X - x1),_Digits);             // цена  перекрестия
      }
if(X != 0) return(X); else return(0);
}  
//+----------------------------------------------------------------------------+


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

Евра 

Код индикатора:

#property indicator_chart_window

input int   CountPeriods  = 2;
input int   Levels        = 10;     //(количество уровней)
input color clrD = clrGainsboro;
input color clrW = clrGainsboro;
//+------------------------+ 
int shift,i,z;    
//+------------------------+ 
   datetime ny_timed[],timed1,timed2,time_d2;
   double open;
   double high;
   double low;
   double closed,ranged;
   double P; 
   double R1,R2;
//+------------------------+     
   datetime ny_timew[],timew1,timew2,time_w2;
   double highw;
   double loww;
   double closew,rangew;
   double Pw;
   double Rw1,Rw2,RsW; 
   double Rw1_1,Rw1_2,Rw2_1,Rw2_2,Rw3_1,Rw3_2,Rsw_1,Rsw_2; 
//+------------------------+     
   datetime timex1,timex2;
   double   pricy1,pricy2;
//+------------------------------------------------------------------+        
int init(){ return(0);}
//+------------------------------------------------------------------+   
int deinit(){ObjDel(); Comment(""); return(0);}
//+------------------------------------------------------------------+  
int start()
  {
  ObjDel();
  ArrayResize(ny_timew,CountPeriods+1);  ArrayResize(ny_timed,CountPeriods+1);  
//+------------------------------------------------------------------+  
  for (shift=0;shift<=CountPeriods-1;shift++) {   
  
  //time недельный
  ny_timew[shift]=iTime(NULL,PERIOD_W1,shift);  ny_timed[shift]=iTime(NULL,PERIOD_D1,shift);
  timew1 = ny_timew[shift]+1440*60;
  
  //time дневной 
  if (shift==0) {timew2 = ny_timew[shift] + 8640*60;} else timew2 = ny_timew[shift-1]+1440*60;     
  timed1 = ny_timed[shift]+Period();
  
  if (shift==0) { timed2 = ny_timed[shift] + 24*3600+Period(); 
                  //вертикальная линия
                  PlotVLine("VL",timed2); }         
  
  else timed2 = ny_timed[shift-1] + Period();  
                  //вертикальная линия
                  PlotVLine("VL["+shift+"]",timed1); 
//+------------------------------------------------------------------+             
  // данные для расчета
  
  highw  = iHigh(NULL,PERIOD_W1,shift+1);  loww   = iLow(NULL,PERIOD_W1,shift+1);
  closew = iClose(NULL,PERIOD_W1,shift+1);
  rangew = (highw - loww);
  
  high  = iHigh(NULL,PERIOD_D1,shift+1);   low   = iLow(NULL,PERIOD_D1,shift+1); 
  closed = iClose(NULL,PERIOD_D1,shift+1); 
  ranged = high-low;

//+------------------------------------------------------------------+         

//+------------------------------------------------------------------+  
  for(z=1;z<Levels*4;z++) 
  {
  
  P =  (high+low+closed)/3.0   - ranged*Levels; //Pivot D1
  
  R1 =  P + ranged/2.0 * z;  
  R2 = (P - ranged/2.0) + ranged/2.0 * z;
  
  PlotLine("Rd1["+shift+"]"+z,R1,R1,0, clrD); // горизонтальная линия D1
  PlotLine("Rd2["+shift+"]"+z,R2,R1,2, clrD); // косая линия сверху вниз D1
  PlotLine("Rd3["+shift+"]"+z,R1,R2,2, clrD); // косая линия снизу вверх D1
 
 
  Pw = (highw+loww+closew)/3.0 - rangew*Levels; //Pivot W1
 
  Rw1 = Pw +  rangew/2.0 * z; Rw2 = (Pw - rangew/2.0) + rangew/2.0 * z;
  RsW = (Pw - rangew/4.0) +  rangew/2.0 * z;  
  
 
  PlotLinew("Rw1["+shift+"]"+z,Rw1, Rw1,0,clrNONE);  // горизонтальная линия W1 
  PlotLinew("Rw2["+shift+"]"+z,Rw2, Rw1,0,clrNONE);  // косая линия сверху вниз W1
  PlotLinew("Rw3["+shift+"]"+z,Rw1, Rw2,0,clrNONE);  // косая линия снизу вверх W1
  PlotLinew("RsW["+shift+"]"+z,RsW, RsW ,2,clrNONE); // средгяя линия W1
//+------------------------------------------------------------------+
   ChartRedraw (); //Вызывает принудительную перерисовку указанного графика.
   Sleep (50);  
   
   i = iBarShift(NULL,PERIOD_W1,timed1); // бар по времени дневной свечи на недельном периоде
   
   //извлечем цену недельных линий согласно времени дневной свечи
       
   Rw1_1  = ObjectGetValueByTime(0,"Rw1["+i+"]"+z,timed1,0);      Rw1_2  = ObjectGetValueByTime(0,"Rw1["+i+"]"+z,timed2,0); 
   Rw2_1  = ObjectGetValueByTime(0,"Rw2["+i+"]"+z,timed1,0);      Rw2_2  = ObjectGetValueByTime(0,"Rw2["+i+"]"+z,timed2,0);
   Rw3_1  = ObjectGetValueByTime(0,"Rw3["+i+"]"+z,timed1,0);      Rw3_2  = ObjectGetValueByTime(0,"Rw3["+i+"]"+z,timed2,0); 
   
   Rsw_1  = ObjectGetValueByTime(0,"RsW["+i+"]"+z,timed1,0);      Rsw_2  = ObjectGetValueByTime(0,"RsW["+i+"]"+z,timed2,0);   
 
//+------------------------------------------------------------------+                      
   // нарисуем в дневном промежутке недельные линии
   
   PlotLine("RW_1["+shift+"]"+z,Rw1_1,Rw1_2,0, clrW);    
   PlotLine("RW_2["+shift+"]"+z,Rw2_1,Rw2_2,0, clrW);
   PlotLine("RW_3["+shift+"]"+z,Rw3_1,Rw3_2,0, clrW);
   PlotLine("RW_S["+shift+"]"+z,Rsw_1,Rsw_2,0, clrW);    
  
//+------------------------------------------------------------------+          
  // введем условие по рассогласование времени в пятницу, и зимних праздников
   
     if ((TimeDayOfWeek(timed2)==1 && (TimeMonth(timed2)!=1 && TimeDay(timed2)!=2)) || (TimeDayOfWeek(timed2)==1 && (TimeMonth(timed2)!=12 && TimeDay(timed2)!=26)))   
        time_d2 = timed2-48*3600+Period(); else 
     if ((TimeDayOfWeek(timed2)!=1 && TimeMonth(timed2)==1 && TimeDay(timed2)==2) || (TimeDayOfWeek(timed2)!=1 && TimeMonth(timed2)==12 && TimeDay(timed2)==26))   
        time_d2 = timed2-24*3600+Period(); else time_d2 = timed2;
    
     //if (TimeDayOfWeek(timew2)==1)
     //time_w2 = timew2-48*3600+Period();
     
     //НАЙДЕМ ПЕРЕКРЕСТИЕ ДНЕВНЫХ И НЕДЕЛЬНЫХ ЛИНИЙ
     
     // Цена перекрестия
     pricy1 = PriceY(R1, R2, R2, R1, timed1,time_d2,timed1,time_d2);
     pricy2 = PriceY(R1, R2, Rw2_1, Rw2_2, timed1,time_d2,timed1,time_d2);
     
     // Время перекрестия
     timex1 = TimeX (R1, R2, R2, R1, timed1,time_d2,timed1,time_d2);
     timex2 = TimeX (R1, R2, Rw2_1, Rw2_2, timed1,time_d2,timed1,time_d2);
     //Alert((int)timex);
//----
     // нанесем аров метку перекрестия на график
     
     SetArrow("aX1["+shift+"]"+z, timex1, pricy1, clrYellowGreen);
     SetArrow("aX2["+shift+"]"+z, timex2, pricy2, clrRed);
    
 
//+----------------------------------------------------------------------------+
  }// for(z=1;z<Levels*4;z++)
//+-----+     
  }// for (shift=0;shift<=CountPeriods-1;shift++) 
//+-----+     
   return(0);
  }// start()
//+----------------------------------------------------------------------------+


// ФУНКЦИЯ ПЕРЕКРЕСТИЯ КООРДИНАТ ДЛЯ ПОИСКА ЦЕНЫ 

double PriceY(double y1, double y2, double y3, double y4, double x1, double x2, double x3, double x4)
    { 
    //y1, y2, y3, y4; //цена  линий 
    //x1, x2, x3, x4; //время  линий      
    double k1, k3;
    double X,Y;
    
    k1=(y2-y1)/(x2-x1); 
    k3=(y4-y3)/(x4-x3);
    
    if(k1 != k3)
      {
      X = NormalizeDouble((y1 - y3 + k3*x3 - k1*x1)/(k3 - k1),0); // время перекрестия
      Y = NormalizeDouble( y1 + k1*(X - x1),_Digits);             // цена  перекрестия
      }
if(Y != 0) return(Y); else return(0);
}  
//+----------------------------------------------------------------------------+

// ФУНКЦИЯ ПЕРЕКРЕСТИЯ КООРДИНАТ ДЛЯ ПОИСКА ВРЕМЕНИ

double TimeX(double y1, double y2, double y3, double y4, double x1, double x2, double x3, double x4)
    {   
    //y1, y2, y3, y4; //цена  линий 
    //x1, x2, x3, x4; //время  линий          
    double k1, k3;
    double X,Y;
    
    k1=(y2-y1)/(x2-x1); 
    k3=(y4-y3)/(x4-x3);
    
    if(k1 != k3)
      {
      X = NormalizeDouble((y1 - y3 + k3*x3 - k1*x1)/(k3 - k1),0); // время перекрестия
      Y = NormalizeDouble( y1 + k1*(X - x1),_Digits);             // цена  перекрестия
      }
if(X != 0) return(X); else return(0);
}  
//+----------------------------------------------------------------------------+

// ФУНКЦИЯ АРОВ МЕТКИ 

void SetArrow(string name, datetime t1, double value, color line_color)
{
   bool res = ObjectCreate(name,OBJ_ARROW,0,t1,value);
   ObjectSetInteger(0,name, OBJPROP_ARROWCODE, 3);
   ObjectSetInteger(0,name, OBJPROP_COLOR, line_color);
}
//+----------------------------------------------------------------------------+ 

// ФУНКЦИЯ УДАЛЕНИЯ ОБЪЕКТОВ

void ObjDel()
{
  for (int num=0;num<=CountPeriods;num++)
  {
  ObjectDelete("VL["+num+"]");  
    
  for(int g=0; g<Levels*4; g++)
     {       
       ObjectDelete("aX1["+num+"]"+g);   ObjectDelete("aX2["+num+"]"+g);

           
       ObjectDelete("Rd1["+num+"]"+g);   ObjectDelete("Rd2["+num+"]"+g); ObjectDelete("Rd3["+num+"]"+g);
       
       ObjectDelete("Rw1["+num+"]"+g);   ObjectDelete("Rw2["+num+"]"+g); ObjectDelete("Rw3["+num+"]"+g);      
       ObjectDelete("RsW["+num+"]"+g); 
       
       ObjectDelete("RW_1["+num+"]"+g);   ObjectDelete("RW_2["+num+"]"+g); ObjectDelete("RW_3["+num+"]"+g);   
       ObjectDelete("RW_S["+num+"]"+g);      
     } 
  }
  ObjectDelete("VL");
}
//+------------------------------------------------------------------+ 

// ФУГКЦИЯ ВЫСТАВЛЕНИЯ НЕДЕЛЬНЫХ ЛИНИЙ

void PlotLinew(string name,double value,double value1, int style_,color clr)
 {
  bool res = ObjectCreate(name, OBJ_TREND,0,timew1,value,timew2,value1);
  ObjectSetInteger ( 0 ,name, OBJPROP_STYLE ,style_);
  ObjectSetInteger ( 0 ,name, OBJPROP_WIDTH ,0);
  ObjectSetInteger ( 0 ,name, OBJPROP_RAY ,false);
  ObjectSetInteger ( 0 ,name, OBJPROP_BACK ,true );
  ObjectSetInteger ( 0 ,name, OBJPROP_COLOR ,clr);
  ObjectSetString  ( 0 ,name, OBJPROP_TEXT ,name+ "Channel");
 } 

//+------------------------------------------------------------------+  

// ФУГКЦИЯ ВЫСТАВЛЕНИЯ ДНЕВНЫХ ЛИНИЙ

void PlotLine(string name,double value,double value1,int style_,color line_color)
{
   bool res = ObjectCreate(name,OBJ_TREND,0,timed1,value,timed2,value1);
   ObjectSet(name, OBJPROP_WIDTH, 0);
   ObjectSet(name, OBJPROP_STYLE, style_);
   ObjectSet(name, OBJPROP_RAY, false);
   ObjectSet(name, OBJPROP_BACK, true);
   ObjectSet(name, OBJPROP_COLOR, line_color);
} 
//+------------------------------------------------------------------+

// ФУГКЦИЯ ВЫСТАВЛЕНИЯ ВЕРТИКАЛЬНОЙ ЛИНИИ

void PlotVLine(string name,double tm)
{
   bool res = ObjectCreate(name,OBJ_VLINE,0,tm,0);
   ObjectSet(name, OBJPROP_WIDTH, 0);
   ObjectSet(name, OBJPROP_STYLE, 0);
   ObjectSet(name, OBJPROP_BACK, true);
   ObjectSet(name, OBJPROP_COLOR, Silver);
} 
 
В выходные время идёт а баров нет, сдвиг накладывается. Наверное в этом причина.
 
Aleksey Mavrin:
В выходные время идёт а баров нет, сдвиг накладывается. Наверное в этом причина.

Я это учел, но мысль правильная

// введем условие по рассогласование времени в пятницу, и зимних праздников
   
     if ((TimeDayOfWeek(timed2)==1 && (TimeMonth(timed2)!=1 && TimeDay(timed2)!=2)) || (TimeDayOfWeek(timed2)==1 && (TimeMonth(timed2)!=12 && TimeDay(timed2)!=26)))   
        time_d2 = timed2-48*3600+Period(); else 
     if ((TimeDayOfWeek(timed2)!=1 && TimeMonth(timed2)==1 && TimeDay(timed2)==2) || (TimeDayOfWeek(timed2)!=1 && TimeMonth(timed2)==12 && TimeDay(timed2)==26))   
        time_d2 = timed2-24*3600+Period(); else time_d2 = timed2;

Мне кажется что функцию по времени нужно изменить, и передать ей бар через фугкцию iBarShift(NULL,0,timed1)

 

Если переделать функцию к примеру вместо datetime что бы она возвращала double, и вместо времени передать ей номера баров для расчета, возможно из за того, что время не совпадает с барами цены открытия и идет смещение?

// ФУНКЦИЯ ПЕРЕКРЕСТИЯ КООРДИНАТ ДЛЯ ПОИСКА ВРЕМЕНИ


double TimeX(double y1, double y2, double y3, double y4, double x1, double x2, double x3, double x4)
    {   
    //y1, y2, y3, y4; //цена  линий 
    //x1, x2, x3, x4; //время  линий          
    double k1, k3;
    double X,Y;
    
    k1=(y2-y1)/(x2-x1); 
    k3=(y4-y3)/(x4-x3);
    
    if(k1 != k3)
      {
      X = NormalizeDouble((y1 - y3 + k3*x3 - k1*x1)/(k3 - k1),0); // время перекрестия
      Y = NormalizeDouble( y1 + k1*(X - x1),_Digits);             // цена  перекрестия
      }
if(X != 0) return(X); else return(0);
}  
//+----------------------------------------------------------------------------+
Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Ценовые константы
Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Ценовые константы
  • www.mql5.com
Технические индикаторы требуют для своих расчетов указания значений цен и/или значений объемов, на которых они будут считаться. Существуют 7 предопределенных идентификаторов перечисления ENUM_APPLIED_PRICE, для указания нужной ценовой базы расчетов. Если технический индикатор для своих расчетов использует ценовые данные, тип которых задается...
 
Martingeil:

Я это учел, но мысль правильная

Мне кажется что фугкцию по времени нужно изменить и передать ей бар через фугкцию iBarShift(NULL,0,timed1)

Вы под мт5 пишете? Там есть галочка в настройках чтобы эти сдвиги устранить, тогда проверки эти излишни и должно работать. По крайней мере я так решил. В мт4 нет такой настройки поэтому геморрой, даже не заморачивался.
з.ы. кстати да в мт4 ещё округление к началу бара всех времён объектов. 
 
Aleksey Mavrin:
Вы под мт5 пишете? Там есть галочка в настройках чтобы эти сдвиги устранить, тогда проверки эти излишни и должно работать. По крайней мере я так решил. В мт4 нет такой настройки поэтому геморрой, даже не заморачивался.

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

 
Martingeil:

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

)) Настройки тоже в коде можно менять. Так вам под какой терминал?
 
Aleksey Mavrin:
)) Настройки тоже в коде можно менять. Так вам под какой терминал?

Решение очень простое, просто интересно кто на что способен  :0)

 
Martingeil:

Решение очень простое, просто интересно кто на что способен  :0)

Кому интересно? Вам? Мне вот интересно вы плохо читать умеете или зачем просили помочь?))
 
Aleksey Mavrin:
Кому интересно? Вам? Мне вот интересно вы плохо читать умеете или зачем просили помочь?))

Помощи как таковой я не увидел, если вы программист то сразу бы отличили код мт4 от мт5. Я задал тему с которой завтра столкнутся многие кто занимается линейными индикаторами. Вы мне ответили вопросом на вопрос, превращая ветку в флуд, таких веток уже пруд пруди на форуме, давайте не отходить от темы, у вас есть решение этой задачи? Если нет, прошу вас тогда пройти мимо ветки.

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

Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Линии индикаторов
Документация по MQL5: Константы, перечисления и структуры / Константы индикаторов / Линии индикаторов
  • www.mql5.com
Некоторые технические индикаторы имеют несколько отрисовываемых на графике буферов. Нумерация индикаторных буферов начинается с 0. При копировании значений индикатора функцией CopyBuffer() в массив типа double для некоторых индикаторов можно указывать не номер копируемого буфера, а идентификатор этого буфера.
 
Martingeil:

Привет программситам.

Столкнулся с проблемой передачи данных с разных графиков цены, с функции ObjectGetValueByTime не передает корректно данные в чем может быть проблема.

Создаю линию трендовую Rw2 недельную в функции PlotLinew

далее, определяю бар функцией iBarShift недельный по дневной свече

Определяю цену трендовой линии недельной на координате "у" времени дневного бара.

вбиваю параметры для нахождения координат перекрестия двух линий, (где R1 и R2 являются координатами дневной трендовой линии, а Rw2_1 и Rw2_2 недельные) функциии  PriceY TimeX 

В итоге  по перекрестию дневных  линий R1, R2, R2, R1 - есть перекрестие, а по дневным и недельным данным R1, R2, Rw2_1, Rw2_2 идет разброс по графику.

время передается в функцию для двух линий одинаковое   timed1,  time_d2,  timed1,  time_d2

Сами функции перекрестия PriceY, TimeX


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

 

Код индикатора:

эта задача решена в классе iCanvas. Изучайте на здоровье. 
Просто нужно переходить от типа int к типу double. 

Уйдите от объектов и придите к Канвас через мой класс iCanvas. И будет Вам счастье, код гораздо короче, а возможностей гораздо больше и скорость гораздо выше.

Причина обращения: