Вопрос про OBJ_REGRESSION

 

Здравствуйте! Имеется вопрос про то, как узнать крайние границы канала регрессии OBJ_REGRESSION.

Канал рисуется тремя линиями, а в списке объектов только одна средняя линия. Соответсвенно, функция ObjectGetValueByShift бесполезна.

Буду признателен, если кто ответит.

 
Evgeniy Zhdan:

Здравствуйте! Имеется вопрос про то, как узнать крайние границы канала регрессии OBJ_REGRESSION.

Канал рисуется тремя линиями, а в списке объектов только одна средняя линия. Соответсвенно, функция ObjectGetValueByShift бесполезна.

Буду признателен, если кто ответит.


Как получить границы канала нарисованного OBJ_REGRESSION не знаю, сам когда то задавался этим вопросом...

Но можно рассчитать его самому:

 
#property copyright "Copyright 2017, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0

input int Index_1 = 20;
input int Index_2 = 1;

double mid_pr_1;
double mid_pr_2;
double up_pr_1;
double up_pr_2;
double dn_pr_1;
double dn_pr_2;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
   ArraySetAsSeries(close, true);
//---
   int n = Index_1 - Index_2; // Количество баров для расчета
   if(n <= 0) return(0);                                
   
   double sum_y = 0;                                  
   double sum_x = 0.0;                                
   double sum_xy = 0.0;                               
   double sum_x2 = 0.0;                               
//---
   for(int i = Index_2; i <= Index_1; i++)          
   {
      sum_y += close[i];                              
      sum_x += i; 
      sum_xy += close[i] * i;                           
      sum_x2 += i * i;                                  
   }  
//--- 
   double c = sum_x2 * n - sum_x * sum_x;                   
   if(c == 0.0) return(0);                             
   double k = (sum_xy * n - sum_x * sum_y) / c;               
   double b = (1.0 / n)*(sum_y - k * sum_x);               
//--- 
   double max = 0;                                   
   for(int i = Index_2; i <= Index_1; i++)           
   {
      double y = k * i + b;                           
      max = MathMax(max, MathAbs(close[i] - y));     
   }
//--- Расчет цены точек линий канала
   mid_pr_1 = k * Index_1 + b;    // Цена первой точки средней линии канала
   mid_pr_2 = k * Index_2 + b;    // Цена второй точки средней линии канала
   up_pr_1 = mid_pr_1 + max * 1;  // Цена первой точки верхней линии канала
   up_pr_2 = mid_pr_2 + max * 1;  // Цена второй точки верхней линии канала
   dn_pr_1 = mid_pr_1 - max * 1;  // Цена первой точки нижней линии канала
   dn_pr_2 = mid_pr_2 - max * 1;  // Цена второй точки нижней линии канала
//--- Посмотрим рассчитанные значения
   Comment("mid 1 = " + DoubleToString(mid_pr_1, _Digits) + 
           "\nmid 2 = " + DoubleToString(mid_pr_2, _Digits) +
           "\nup 1 = " + DoubleToString(up_pr_1, _Digits) +
           "\nup 2 = " + DoubleToString(up_pr_2, _Digits) +
           "\ndn 1 = " + DoubleToString(dn_pr_1, _Digits) +
           "\ndn 2 = " + DoubleToString(dn_pr_2, _Digits));
//--- 
   return(rates_total);
}
//+------------------------------------------------------------------+
 
Sergey Kolemanov:

Спасибо. Слишком уж закручено. Странно, что нету штатной функции в 1 строчку.

 

Давно обсуждался вопрос несоответствия расчетных границ канала с теми границами, которые получаются при помощи стандартного инструмента "Линейная регрессия".

Оказалось, что инструмент считает по Open, а не по Close. Это хорошо видно на рисунке:


Красная линия - Open свечи, по которой рассчитаны границы канала. Синяя линия - Close за пределами границ канала.

 
Evgeniy Zhdan:

Спасибо. Слишком уж закручено. Странно, что нету штатной функции в 1 строчку.

Помещаете этот код в функцию и получаете значение в одну строку ))
 
Sergey Kolemanov:

Это не правильный код. Ересь какую-то показывает. Показывает ценовые значения, которых и на графике нет:

https://www.mql5.com/en/charts/8116209/eurusd-h1-alpari-international-limited

Chart EURUSD, H1, 2018.01.03 08:23 UTC, Alpari International Limited, MetaTrader 4, Real
Chart EURUSD, H1, 2018.01.03 08:23 UTC, Alpari International Limited, MetaTrader 4, Real
  • www.mql5.com
Symbol: EURUSD. Periodicity: H1. Broker: Alpari International Limited. Trading Platform: MetaTrader 4. Trading Mode: Real. Date: 2018.01.03 08:23 UTC.
 
Evgeniy Zhdan:

Это не правильный код. Ересь какую-то показывает. Показывает ценовые значения, которых и на графике нет:

https://www.mql5.com/en/charts/8116209/eurusd-h1-alpari-international-limited


в коде ошибка

int n = Index_1 - Index_2 +1; // Количество баров для расчета
...или же вместо <= поставить <
 
Evgeniy Zhdan:

Это не правильный код. Ересь какую-то показывает. Показывает ценовые значения, которых и на графике нет:

https://www.mql5.com/en/charts/8116209/eurusd-h1-alpari-international-limited


Извиняюсь , в коде была логическая ошибка.. , постом выше показано как исправить.

 
Taras Slobodyanik:

в коде ошибка

...или же вместо <= поставить <

А вот это другое дело! Снимаю шляпу!

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