Вопрос к разработчикам по поводу "Канала линейной регрессии"

 
Заметил такой ляпсус - канал линейной регрессии не проводит линию по геометрической середине.
Построил скрипт расчитанный по стандартной формуле линейной регрессии - все четко, строится - по середине.

Вот рисунок с каналом из набора стандартных функций. И кстати так почти везде, на любой длине. С первого бара не там ставит линию, а на последнем баре, вроде там.

В чем тут дело?

Я частенько использую функцию канала линейной регрессии в скриптах и индикаторах, и поэтому, точность для меня актуальна.
Да я думаю и для многих других. Народ при торговле часто миллиметры считает.
И желательно чтобы максимальный размах строился бы не по Close, а по High/Low - это более правильно.
И канал стандартного отклонения из набора стандартных инструментов - рисуется не по линейной регрессии а по мувингу.
На всякий случай прикладываю скрипт где все это строится правильно.




//------------------------------------------
double sx,sy,sxy,sx2,aa,bb,lr,lr0,lrp;
double dm,dh,dl,dc,dcm,sq;
double per,kt,V;
int T,Tn,f;
int t0,tp,i0,ip,t0n,tpn;
string Symb;
int Per;
//*******************************************
int init() 
{
  Symb=Symbol();
  Per=Period();
  kt=Period()*60;
  t0=TimeOnDropped();
  T=40; 
  Tn=T;
  
  i0=iBarShift(Symb,Per,t0);
  ip=i0+T;
  tp=Time[ip];
  tpn=tp;
  t0n=t0;
  
  ObjectCreate("Hm",2,0,0,0,0,0);
  ObjectSet("Hm",OBJPROP_RAY,0);
  ObjectSet("Hm",OBJPROP_COLOR,DarkViolet);
  ObjectCreate("Lm",2,0,0,0,0,0);
  ObjectSet("Lm",OBJPROP_RAY,0);
  ObjectSet("Lm",OBJPROP_COLOR,DarkViolet);
  
  ObjectCreate("sqH1",2,0,0,0,0,0);
  ObjectSet("sqH1",OBJPROP_STYLE,STYLE_DOT);
  ObjectSet("sqH1",OBJPROP_RAY,0);
  ObjectSet("sqH1",OBJPROP_COLOR,Gold);
   
  ObjectCreate("sqL1",2,0,0,0,0,0);
  ObjectSet("sqL1",OBJPROP_STYLE,STYLE_DOT);
  ObjectSet("sqL1",OBJPROP_RAY,0);
  ObjectSet("sqL1",OBJPROP_COLOR,Gold);
  
  ObjectCreate("sqH2",2,0,0,0,0,0);
  ObjectSet("sqH2",OBJPROP_STYLE,STYLE_DOT);
  ObjectSet("sqH2",OBJPROP_RAY,0);
  ObjectSet("sqH2",OBJPROP_COLOR,LimeGreen);
   
  ObjectCreate("sqL2",2,0,0,0,0,0);
  ObjectSet("sqL2",OBJPROP_STYLE,STYLE_DOT);
  ObjectSet("sqL2",OBJPROP_RAY,0);
  ObjectSet("sqL2",OBJPROP_COLOR,LimeGreen);
  
  ObjectCreate("txtHL",OBJ_TEXT,0,0,0,0,0);
  ObjectCreate("txtV",OBJ_TEXT,0,0,0,0,0);
  
  ObjectCreate("RCh",4,0,tp,0,t0,0);
  ObjectSet("RCh",OBJPROP_COLOR,DodgerBlue);
  
  per=Period();
  kt=60/per;
}
//*******************************************
int start() 
{
  //-------------------------------------
  while(IsStopped()==false) 
  {
    t0=ObjectGet("RCh",OBJPROP_TIME2); 
    if (t0>Time[0]) t0=Time[0]; 
    tp=ObjectGet("RCh",OBJPROP_TIME1); 
    if (tp>Time[i0+1]) tp=Time[i0+1];
      
    if (tpn!=tp || t0n!=t0)
    {
      f=2;
      i0=iBarShift(Symb,Per,t0);
      ip=iBarShift(Symb,Per,tp);
      tpn=Time[ip];
      t0n=Time[i0];
    }
   
    if (f==2 && tpn==tp && t0n==t0) {f=3; T=ip-i0;}
    
    if (f==0 || f==3)
    {  
      f=1;
      //========================LR===================================================================
      sx=0; sy=0; sxy=0; sx2=0; 
      for (int n=0; n<=T; n++) {sx+=i0+n; sy+=Close[i0+n]; sxy+=(i0+n)*Close[i0+n]; sx2+=MathPow(i0+n,2);}
      aa=(sx*sy-(T+1)*sxy)/(MathPow(sx,2)-(T+1)*sx2); bb=(sy-aa*sx)/(T+1);
      lr0=bb+aa*i0; 
      lrp=bb+aa*ip; 
      //========================SQ/HLm===============================================================
     
      if (ip-i0>0) 
      {
        dm=0.0; 
        sq=0.0;
        for (n=0; n<=T; n++) 
        {
          lr=bb+aa*(n+i0); 
          sq+=MathPow(Close[n+i0]-lr,2);
          dh=High[n+i0]-lr; 
          dl=lr-Low[n+i0]; 
          if (dh>dm) dm=dh; 
          if (dl>dm) dm=dl;
        } 
        sq=MathSqrt(sq/(T+1));
      }
     
      //==========================ObjMome==========================
       
      ObjectMove("RCh",0,tpn,0);
      ObjectMove("RCh",1,t0n,0);

      ObjectMove("Hm",0,tp,lrp+dm);
      ObjectMove("Hm",1,t0,lr0+dm);
      ObjectMove("Lm",0,tp,lrp-dm);
      ObjectMove("Lm",1,t0,lr0-dm);
      
      ObjectMove("sqH1",0,tp,lrp+sq);
      ObjectMove("sqH1",1,t0,lr0+sq);
      ObjectMove("sqL1",0,tp,lrp-sq);
      ObjectMove("sqL1",1,t0,lr0-sq);
      
      ObjectMove("sqH2",0,tp,lrp+sq*2);
      ObjectMove("sqH2",1,t0,lr0+sq*2);
      ObjectMove("sqL2",0,tp,lrp-sq*2);
      ObjectMove("sqL2",1,t0,lr0-sq*2);
      //--------------------------------------
          
      ObjectMove("txtHL",0,t0,lr0+dm+0.0005);
      ObjectSetText("txtHL","HL="+DoubleToStr(2*dm/Point,0), 8, "Arial", LemonChiffon);

      if (i0!=ip) V=MathAbs((lr0-lrp)/Point)/((ip-i0)/kt);
      ObjectMove("txtV",0,t0,lr0-dm-0.0007);
      ObjectSetText("txtV","V="+DoubleToStr(V,1), 8, "Arial", Aqua);
    }
    //====================Comment======================================
    Comment
    (
      "t0 = ",TimeToStr(t0,TIME_DATE|TIME_MINUTES),"\n",
      "tp = ",TimeToStr(tp,TIME_DATE|TIME_MINUTES),"\n",
      "i0 = ",i0,"\n",
      "ip = ",ip
    );
  }
  //====================================================================
  return(0);
}
//**********************************************************************
int deinit() 
{ 
   ObjectDelete("RCh"); 
   ObjectDelete("Hm"); 
   ObjectDelete("Lm"); 
   ObjectDelete("sqH1"); 
   ObjectDelete("sqL1");
   ObjectDelete("sqH2"); 
   ObjectDelete("sqL2"); 
   ObjectDelete("txtHL");
   ObjectDelete("txtV"); 
   Comment(" ");
   return(0);
}
//**********************************************************************
 
В последнее время эта тема поднималась не раз.
Смотри "Канал линейной регрессии" и "Канал линейной регрессии"
Однако, до сих пор никому не удалось получить от разработчиков хоть какой-то ответ. :-(
 
В последнее время эта тема поднималась не раз.
Смотри "Канал линейной регрессии"
Однако, до сих пор никому не удалось получить от разработчиков хоть какой-то ответ. :-(


Да странно. Исправить ошибку - несколько минут дела. Эта ошибка же принижает ценность программы.
Просьба к разработчикам все-таки исправить это несоответствие.
 
Хотите построенную линейную регрессию и угол как индикатор - воспользуйтесь http://chart-hammer.narod.ru/
 
Хотите построенную линейную регрессию и угол как индикатор - воспользуйтесь http://chart-hammer.narod.ru/


Да не. Мы "патриоты".
 
Заметил такой ляпсус - канал линейной регрессии не проводит линию по геометрической середине.
Построил скрипт расчитанный по стандартной формуле линейной регрессии - все четко, строится - по середине.

Вот рисунок с каналом из набора стандартных функций. И кстати так почти везде, на любой длине. С первого бара не там ставит линию, а на последнем баре, вроде там.

В чем тут дело?

А почему Вы смотрите на линейный график, а не на свечной или в барах?
Канал линейной регрессии также использует High и Low, а не только Close.
Краткое описание Казала линейной регрессии есть по ссылке: "Канал Линейной Регрессии"

Включите режим баров и проверьте еще раз, пожалуйста.

ps: или я не так понял вопрос?
 
Заметил такой ляпсус - канал линейной регрессии не проводит линию по геометрической середине.
Построил скрипт расчитанный по стандартной формуле линейной регрессии - все четко, строится - по середине.

Вот рисунок с каналом из набора стандартных функций. И кстати так почти везде, на любой длине. С первого бара не там ставит линию, а на последнем баре, вроде там.

В чем тут дело?

А почему Вы смотрите на линейный график, а не на свечной или в барах?
Канал линейной регрессии также использует High и Low, а не только Close.
Краткое описание Казала линейной регрессии есть по ссылке: "Канал Линейной Регрессии"

Включите режим баров и проверьте еще раз, пожалуйста.

ps: или я не так понял вопрос?


Кстати, Renat, иллюстрации к каналам линейной регрессии и стандартного отклонения, очень похоже, перепутаны местами.
 
А почему Вы смотрите на линейный график, а не на свечной или в барах?
Канал линейной регрессии также использует High и Low, а не только Close.
Краткое описание Казала линейной регрессии есть по ссылке: "Канал Линейной Регрессии"

Renat,
Может я и не кстати, но, как мне кажется, Вы опять ответили не по существу.
1. Алгоритм линейной регрессии никак не зависит от того, в каком виде представлен график, линейный он, свечной или в барах. Вы разве считаете иначе ?
2. Канал линейной регрессии MQ НЕ использует ни High, ни Low, а только Close. Если не верите, то посмотрите вот в этой ветке "Linear Regression Channel, Calculating Method", куда меня когда-то отослал Slawa, и где он же привел код ЛР. В кратком описании по приведенной Вами ссылке сказано то же самое:
Расстояние между границами канала и линией регрессии равно величине максимального отклонения цены закрытия от линии регрессии.

3. В самом первом посте этой ветки Вы не обратили внимание на ключевые слова ANG3110:
С первого бара не там ставит линию, а на последнем баре, вроде там.

Если Вы посмотрите вот в этой ветке "Канал линейной регрессии", где энный раз безуспешно поднимается этот вопрос, то в 4-м посте (автор - Rosh) увидите, как это выглядит на графике.
4. Причины всего этого заключаются в одной маленькой ошибке. Я писал об этом вот здесь "Канал линейной регрессии", однако, никакой реакции не последовало. А жаль, ведь период тестирования давно закончен и МТ4 используют десятки тысяч трейдеров. Они уверены, что софту MQ можно доверять.
 
Будем разбираться и исправлять - на днях как раз будет официальный 194 билд.
Я сразу не разобрался - спасибо за объяснения.
 
Да, действительно. В реализации ошибка, которую я только что обнаружил.
Должно быть так:
   int n=m_pos[1]-m_pos[0]+1;
//---- calculate price values
   double value=Close[m_pos[0]];
   double a,b,c;
   double sumy=value;
   double sumx=0.0;
   double sumxy=0.0;
   double sumx2=0.0;
   for(i=0; i<n; i++)
     {
      value=Close[m_pos[0]+i];
      sumy+=value;
      sumxy+=value*i;
      sumx+=i;
      sumx2+=i*i;
     }
   c=sumx2*n-sumx*sumx;
   if(c==0.0) return;
   b=(sumxy*n-sumx*sumy)/c;
   a=(sumy-sumx*b)/n;
   m_value[0]=a;
   m_value[1]=a+b*n;
//---- maximal deviation
   double maxdev=0;
   double deviation=0;
   double dvalue=a;
   for(i=0; i<n; i++)
     {
      value=Close[m_pos[0]+i];
      dvalue+=b;
      deviation=fabs(value-dvalue);
      if(maxdev<=deviation) maxdev=deviation;
     }


То есть, первоначальное накопление сумм должно идти с 0, а не с 1, как это показано в "Linear Regression Channel, Calculating Method"

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