Self-regressive Median Coefficient

To add comments, please log in or register
Arthur Albano
368
Arthur Albano  

Hi all,

I am trying to build an indicator that uses the following formula and returns the expected value, so I can use the same chart as indicator_chart_window.

//+------------------------------------------------------------------+
//|                                                    Quantiles.mqh |
//|                                                    Arthur Albano |
//|                            https://www.facebook.com/arthuralbano |
//+------------------------------------------------------------------+
#property copyright "Arthur Albano"
#property link      "https://www.facebook.com/arthuralbano"
#include <Math\Stat\Math.mqh>

//+------------------------------------------------------------------+
//| Regression Coefficient Median                                    |
//+------------------------------------------------------------------+
double MathQuantRegCoeff(double &time[], double &price[])
    {
    ArrayPrint(time);
    ArrayPrint(price);
    if(ArraySize(time)!=ArraySize(price))
        return(QNaN);
    int size = ArraySize(time);
    if(size<2)
        return(QNaN);
    double QuantRegCoeff = 0.0;
    double CoeffBuffer[];
    
    int k=0;
    double Coefficient=0;
    
    for(int i=0;i<(size-1);i++)
        {
            for(int j=(i+1);j<(size);j++)
                {
                    ArrayResize(CoeffBuffer,k+1);
                    Coefficient = (price[j]-price[i])/(time[j]-time[i]);
                    CoeffBuffer[k] = Coefficient;
                    k++;
                };
        };
    QuantRegCoeff = MathMedian(CoeffBuffer);
    return(QuantRegCoeff);
    }
Mladen Rakic
110880
Mladen Rakic  
Arthur Albano:

Hi all,

I am trying to build an indicator that uses the following formula and returns the expected value, so I can use the same chart as indicator_chart_window.

You can not use it as indicator_chart_window (the values won't fit to main chart). Use separate window



Siyabonga Ngubane
21
Siyabonga Ngubane  
Nice one 
Arthur Albano
368
Arthur Albano  
Mladen Rakic:

You can not use it as indicator_chart_window (the values won't fit to main chart). Use separate window


How did you use the code I wrote to place it as indicator? I am good at maths, but not on coding...
Arthur Albano
368
Arthur Albano  
How did you create an indicator for this formula?
Mladen Rakic
110880
Mladen Rakic  
Arthur Albano:
How did you create an indicator for this formula?

I am afraid I do not understand the question

I did it all the usual way how indicators are build (used metatrader 5 for that test) - nothing special about that. The only deviation is that I have changed the function (in order to optimize it a bit). This is the function I have used :

double QNaN =(double)"nan"; // QNaN
double CoeffBuffer[]; 
double MathQuantRegCoeff(double &time[], double &price[])
{
   int size = ArraySize(time);
   if (size<2)                   return(QNaN);
   if (size != ArraySize(price)) return(QNaN);
   int coeffSize = (size*(size-1))/2; if (ArraySize(CoeffBuffer)!=coeffSize) ArrayResize(CoeffBuffer,coeffSize); 
    
   for(int i=0,k=0;i<(size-1);i++)
   for(int j=(i+1);j<(size);j++,k++) CoeffBuffer[k] = (price[j]-price[i])/(time[j]-time[i]); ArraySort(CoeffBuffer);
                              
   double  QuantRegCoeff = (coeffSize%2==1) ? (CoeffBuffer[coeffSize/2]) : (0.5*(CoeffBuffer[(coeffSize-1)/2]+CoeffBuffer[(coeffSize+1)/2]));
   return( QuantRegCoeff );
}
Arthur Albano
368
Arthur Albano  
Mladen Rakic:

I am afraid I do not understand the question

I did it all the usual way how indicators are build (used metatrader 5 for that test) - nothing special about that. The only deviation is that I have changed the function (in order to optimize it a bit). This is the function I have used :

You are good.
Arthur Albano
368
Arthur Albano  
Mladen Rakic:

I am afraid I do not understand the question

I did it all the usual way how indicators are build (used metatrader 5 for that test) - nothing special about that. The only deviation is that I have changed the function (in order to optimize it a bit). This is the function I have used :

Newbie question: why not
double CoeffBuffer[]; 

inside the function?

Arthur Albano
368
Arthur Albano  
//+------------------------------------------------------------------+
//|                                                         QLRC.mq5 |
//|                                                    Arthur Albano |
//|                            https://www.facebook.com/arthuralbano |
//+------------------------------------------------------------------+
#property copyright "Arthur Albano"
#property link      "https://www.facebook.com/arthuralbano"
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
//--- plot QLRC
#property indicator_label1  "QLRC"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//includes
#include <Math\Stat\Math.mqh>
#include <Math\Stat\Quantiles.mqh>

//--- input parameters
input int      InpPeriod=12;
input int      InpShift=0;
input double   InpPercentRank=0.5;
//--- indicator buffers
double         QLRCBuffer[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   SetIndexBuffer(0,QLRCBuffer,INDICATOR_DATA);
//--- set plot shift along the horizontal axis by InpShift bars
   PlotIndexSetInteger(0,PLOT_SHIFT,InpShift);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| 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[])
  {
//---
    //--- the main loop of calculations
   int start=!prev_calculated?InpPeriod-1:prev_calculated-1;
   for(int i=start;i<rates_total;i++)
   {
      double TimeArray[];
      ArrayCopy(TimeArray, time, 0, i-InpPeriod+1, InpPeriod);

      double PriceArray[];
      ArrayCopy(PriceArray, close, 0, i-InpPeriod+1, InpPeriod);
        
      QLRCBuffer[i]=MathQuantLRCoeff(TimeArray,PriceArray,InpPercentRank);
   }

   //--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
Arthur Albano
368
Arthur Albano  
Mladen Rakic:

I am afraid I do not understand the question

I did it all the usual way how indicators are build (used metatrader 5 for that test) - nothing special about that. The only deviation is that I have changed the function (in order to optimize it a bit). This is the function I have used :

//+------------------------------------------------------------------+
//| Quantile Linear Regression Coefficient                                  |
//+------------------------------------------------------------------+
double MathQuantLRCoeff(double &x_array[], double &y_array[], const double percent_rank = 0.5)
{
   int size = ArraySize(x_array);
   if (size<2)                   return(QNaN);
   if (size != ArraySize(y_array)) return(QNaN);

   double CoeffBuffer[];

   int coeffSize = (size*(size-1))/2; if (ArraySize(CoeffBuffer)!=coeffSize) ArrayResize(CoeffBuffer,coeffSize); 

   for(int i=0,k=0;i<(size-1);i++)
   for(int j=(i+1);j<(size);j++,k++) CoeffBuffer[k] = (y_array[j]-y_array[i])/(x_array[j]-x_array[i]); ArraySort(CoeffBuffer);
                              
   double  QuantRegCoeff = (coeffSize%2==1) ? (CoeffBuffer[coeffSize/2]) : (0.5*(CoeffBuffer[(coeffSize-1)/2]+CoeffBuffer[(coeffSize+1)/2]));
   return(QuantRegCoeff);
}

I changed it a bit so I calculate different coefficients based on different percent_ranks (I am working on it).

Mladen Rakic
110880
Mladen Rakic  
Arthur Albano:
Newbie question: why not

inside the function?

I removed it from inside the function since this way it will be created (and resized) only if the size of the input arrays changes. That way you are avoiding repeated array creation (on each new call of the function - since the array remains allocated between the two calls) and resizing within the loop (which, when you take into account that, for example, for period 32 the array is size 496 - ie: creating a new array, and resizing it 495 times, can slow down the overall work of the function significantly)
To add comments, please log in or register