Никогда не шарил как правильно пишутся индикаторы, помогите плз.. :)

 

Нужно посчитать корреляцию кастомного индикатора с текущими ценами открытия, и вывести значения за всю историю

какая вообще правильная последовательность должна быть? делаю вот так, а он какую-то шляпу рисует в тестере

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

#property copyright "Copyright 2017, Dmitrievskiy Max."
#property link      "https://www.mql5.com/ru/users/dmitrievsky"
#property version   "1.00"

#include <Math\Stat\Math.mqh>
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   1
//---- plot MA

#property indicator_type1   DRAW_LINE
#property indicator_color1  clrGreen
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

//--- input parameters
input int DPperiod = 15;
input int CorrPeriod = 15;
ENUM_APPLIED_PRICE price=PRICE_OPEN;

//--- indicator buffers
double corrBuffer[];
double dpBuffer[];

double detrends[];
double prices[];

int dp_handle;
static datetime last_time=0;
 double pearson=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,corrBuffer,INDICATOR_DATA);
   IndicatorSetInteger(INDICATOR_DIGITS,5);
   SetIndexBuffer(1,dpBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,prices,INDICATOR_CALCULATIONS);
  
   ArrayResize(prices,CorrPeriod);
   ArrayResize(detrends,CorrPeriod);
//--- set short name
   IndicatorSetString(INDICATOR_SHORTNAME,"CORRELATION IND("+_Symbol+"): ");
//---
   dp_handle=iMA(_Symbol,0,DPperiod,0,MODE_EMA,PRICE_OPEN);
   return(0);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
   if(!isNewBar())
     {  
      return(prev_calculated);
     }
 //--- check if all data calculated
   if(BarsCalculated(dp_handle)<rates_total) return(0);
//--- we can copy not all data
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) to_copy=rates_total;
   else
     {
      to_copy=prev_calculated-1;
     }
//--- calculate 
   CopyBuffer(dp_handle,0,0,to_copy,dpBuffer);
    
   if(prev_calculated==0)
     {
      for(int i=CorrPeriod;i<rates_total && !IsStopped();i++)
       { 
        ArrayCopy(prices,open,0,i-CorrPeriod,CorrPeriod);
        ArrayCopy(detrends,dpBuffer,i-CorrPeriod,i-CorrPeriod,CorrPeriod);
        
        bool corr=MathCorrelationPearson(prices,detrends,pearson);
        corrBuffer[i]=pearson;   
       }
      }
   else
   for(int i=to_copy+1;i<rates_total && !IsStopped();i++)
     {    
      int cop1 = ArrayCopy(prices,open,0,i-CorrPeriod,CorrPeriod);
      int cop2 = ArrayCopy(detrends,dpBuffer,i-CorrPeriod,i-CorrPeriod,CorrPeriod);
      CopyBuffer(dp_handle,0,i-CorrPeriod,CorrPeriod,dpBuffer);
      bool corr=MathCorrelationPearson(prices,dpBuffer,pearson);
      corrBuffer[i]=pearson;  
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

bool isNewBar()
  {
   datetime lastbar_time=datetime(SeriesInfoInteger(Symbol(),_Period,SERIES_LASTBAR_DATE));
   if(last_time==0)
     {
      last_time=lastbar_time;
      return(false);
     }
   if(last_time!=lastbar_time)
     {
      last_time=lastbar_time;
      return(true);
     }
   return(false); 
  }

я чувствую что почти сделал, но где-то что-то не так :)

 
Maxim Dmitrievsky:

нужно для каждого бара взять 2 массива с ценами: мувинга и цен открытия, начиная с текущего бара и до CorrPeriod назад, и посчитать между ними корреляцию Пирсона, и так пройтись по всей истории

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Помогите с корреляцией

Quantum, 2016.12.01 12:48

В таких случаях лучше свою функцию написать, которая хранит суммы и пересчитывает их с учетом ушедшего и добавленного элементов.

 
fxsaber:

ага, так еще и медленно будет.. будем искатьс

 
Maxim Dmitrievsky:

ага, так еще и медленно будет.. будем искатьс

Для вычисления корреляционной/ковариационной матриц точно есть рекурентные способы. Наверное, быстрее поиска - самому вывести.

 
Maxim Dmitrievsky:

ага, так еще и медленно будет.. будем искатьс


Такая конструкция будет сильно тормозить в тестере, лучше сделайте включаемый файл, в котором считается значение только на текущем баре.

Или Вам нужен индикатор для визуальной оценки, если это так, то можно сделать немного по другому?

К примеру заменить вызов хендла ima, на MovingAverages.mqh.

//------------------------------------------------------------------------------------

for(int i=to_copy+1;i<rates_total && !IsStopped();i++)
     {    
      int cop1 = ArrayCopy(prices,open,0,i-CorrPeriod,CorrPeriod);
      int cop2 = ArrayCopy(detrends,dpBuffer,i-CorrPeriod,i-CorrPeriod,CorrPeriod);
      CopyBuffer(dp_handle,0,i-CorrPeriod,CorrPeriod,dpBuffer);
      bool corr=MathCorrelationPearson(prices,dpBuffer,pearson);
      corrBuffer[i]=pearson;  
     }
В цикле строку CopyBuffer поставьте в начало, до cop1, cop2.
 
fxsaber:

Для вычисления корреляционной/ковариационной матриц точно есть рекурентные способы. Наверное, быстрее поиска - самому вывести.


Когда-то писал подобное. Потому использовал такой способ ускорения расчетов.

Computing linear regression in one pass
Computing linear regression in one pass
  • www.johndcook.com
The class is the analog of the class described here and uses that class. You add pairs of (x, y) values by using the . At any point along the way you can call the , , or functions to see the current value of these statistics. You can also combine two objects by using the and operators. For...
 
forexman77:

Такая конструкция будет сильно тормозить в тестере, лучше сделайте включаемый файл, в котором считается значение только на текущем баре.

Или Вам нужен индикатор для визуальной оценки, если это так, то можно сделать немного по другому?

К примеру заменить вызов хендла ima, на MovingAverages.mqh.


да, мне нужно получить сразу по большой глубине истории, делаю предикторы для НС.. думал слету напишу а нет завтык :) как что-то сделаю -скину

 
forexman77:

Такая конструкция будет сильно тормозить в тестере, лучше сделайте включаемый файл, в котором считается значение только на текущем баре.

Или Вам нужен индикатор для визуальной оценки, если это так, то можно сделать немного по другому?

К примеру заменить вызов хендла ima, на MovingAverages.mqh.

//------------------------------------------------------------------------------------

В цикле строку CopyBuffer поставьте в начало, до cop1, cop2.

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

 
Maxim Dmitrievsky:

да, мне нужно получить сразу по большой глубине истории, делаю предикторы для НС.. думал слету напишу а нет завтык :) как что-то сделаю -скину

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

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

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

Могу попробовать сделать индикатор, но он будет тормозной.?

 
forexman77:

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

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

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

Могу попробовать сделать индикатор, но будет тормозной.?


желательно быстрый что бы был, да я покопаюсь сам, спасибо, кстати индикатор Дмитрия вроде бы быстро считает https://www.mql5.com/ru/code/572

можно переделать под свои нужды

iBeta
iBeta
  • голосов: 16
  • 2011.10.14
  • Dmitry Fedoseev
  • www.mql5.com
Индикатор ковариации, корреляции и коэффициента Beta двух символов.
 
Maxim Dmitrievsky:

желательно быстрый что бы был, да я покопаюсь сам, спасибо, кстати индикатор Дмитрия вроде бы быстро считает https://www.mql5.com/ru/code/572

можно переделать под свои нужды


Когда сам делал индикатор корреляции Пирсона  на MQL4,  решил проверить, как раз с iBeta сверял.