Self-regressive Median Coefficient

 

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);
    }
 
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



 
Nice one 
 
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...
 
How did you create an indicator for this formula?
 
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 );
}
 
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.
 
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?

 
//+------------------------------------------------------------------+
//|                                                         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);
  }
//+------------------------------------------------------------------+
 
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).

 
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)
Reason: