Successfully initialised vector is out of range after matrix.Lstsq()

 

This little test indicator stores the OHLC values of the last 14 bars inside a matrix of four rows. 

There are also two vectors declared and initialised for later operations.

One gets filled with the matrix row containing the close values, the other one is all zeros, then they are both printed out to show how they look before and after matrix.Lstsq() .

After Lstsq the print function can not access the second vector anymore like it has been deinitialised. Here the debugger throws a critical error.

I am almost certain that this is not how it was intented although I would love to be proven wrong.

#property indicator_chart_window


long rows = 5;
long cols = 14;
matrix matx1;
vector vec_row1, vec_row2;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {

   matx1.Init(rows, cols);
   vec_row1.Init(cols);
   vec_row2.Init(cols);

//---
   return(INIT_SUCCEEDED);
}

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(open, false);        // OHLC
   ArraySetAsSeries(high, false);
   ArraySetAsSeries(low, false);
   ArraySetAsSeries(close, false);


// Fill matrix rows with OHLC values of the last 14 bars
   int bar_ind = (int)cols - 1;
   for(int i = 0; i < cols; i++) {       
      int rate = rates_total - (int)cols + i;
      matx1[0][i] = open[rate];          // first candle= rates_total-13+0, second= rates_total-13+1 etc.
      matx1[1][i] = high[rate];
      matx1[2][i] = low[rate];
      matx1[3][i] = close[rate];         
   }
   
   vec_row1 = GetRowAsVector(matx1,3);  //The first vector gets the close values from the matrix row with index 3
   
   Print("BEFORE:");
   PrintVectors();
   
   vec_row2 = GetRegressionLine(matx1, vec_row1);  //see below
                                                   
                                                   
   Print("AFTER:");
   PrintVectors();
   

//--- return value of prev_calculated for next call
   return(rates_total);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
vector GetRegressionLine(const matrix& matx, const vector& b) {
   vector vec_res = matx.LstSq(b);  //I am not sure if it is done like that. I was trying to fill the 
   return(vec_res);                 //second vector with the solution of the least square function which is
                                    //of type vector and also I was expecting it to be some line of best fit.
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
vector GetRowAsVector(const matrix& matx, const long src_row) {
   vector vec_res = matx.Row(src_row);
   return(vec_res);
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void PrintVectors(){
   for(int i = 0; i < cols; i++) {
      Print(StringFormat("vec_row1[%d] = ",i), vec_row1[i]);
   }
   for(int i = 0; i < cols; i++) {
      Print(StringFormat("vec_row2[%d] = ",i), vec_row2[i]);
   }}
Projects assist in creating profitable trading robots! Or at least, so it seems
Projects assist in creating profitable trading robots! Or at least, so it seems
  • www.mql5.com
A big program starts with a small file, which then grows in size as you keep adding more functions and objects. Most robot developers utilize include files to handle this problem. However, there is a better solution: start developing any trading application in a project. There are so many reasons to do so.
 

Did you read the "lstsq" documentation ?

You don't provide the correct data (the matrix is incorrect), your function call returns an empty vector and an error (check _LastError).

 
Alain Verleyen #:

Did you read the "lstsq" documentation ?

You don't provide the correct data (the matrix is incorrect), your function call returns an empty vector and an error (check _LastError).

First of all thank you for responding to this problem, Alain. Let me adress the different points that you mentioned.
  1. To be honest, I tried to read it but I did not find the numpy documentation particularly helpful in this matter. My Python is just not that good. Also my linalg math is college beginner level at best but not college graduate level. Besides that I couldn't see what this has to do with the particularities of MQL syntax. The syntax of the results of numpy.linalg are quite different from those in the MQL documentation. To be honest I am lost after half of the first section. What does it say about the use of the MQL function matrix.Lstsq() ?
    Why can't an MQL function be documented on the MQL website in a way that makes it easy to use?

    vector matrix.LstSq(const vector b)

    lstsq

    Return the least-squares solution of linear algebraic equations (for non-square or degenerate matrices)



  2. What is incorrect about the matrix? It is a 4X14 Matrix, the four rows represent the series of the latest 14 OHLC rates. This is just what I intended to have the price points for which I wanted to find the regression line. I am convinced that it is possible to use mathematical functions in various ways. I can print the whole matrix and check the matrix rows and colums. Would you mind telling me how it is incorrect?

    #property indicator_chart_window
    
    
    long rows = 4;
    long cols = 14;
    matrix matx1;
    vector vec_row1, vec_row2;
    
    //+------------------------------------------------------------------+
    //| Custom indicator initialization function                         |
    //+------------------------------------------------------------------+
    int OnInit() {
    
       matx1.Init(rows, cols);
       vec_row1.Init(cols);
       vec_row2.Init(cols);
    
    //---
       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[]) {
    //---
       ArraySetAsSeries(open, false);        // OHLC
       ArraySetAsSeries(high, false);
       ArraySetAsSeries(low, false);
       ArraySetAsSeries(close, false);
    
       int bar_ind = (int)cols - 1;
       for(int i = 0; i < cols; i++) {
          int rate = rates_total - (int)cols + i;
          matx1[0][i] = open[rate];          // first candle= rates_total-13+0, second= rates_total-13+1 etc.
          matx1[1][i] = high[rate];
          matx1[2][i] = low[rate];
          matx1[3][i] = close[rate];
       }
       ulong column_num = matx1.Cols();             // I checked this with observation
       ulong row_num = matx1.Rows();
    
       PrintMatrix();                               //and printed out all the values
    
       vec_row1 = GetRowAsVector(matx1, 3);
    
       Print("BEFORE:");
       PrintVectors();
    
       vec_row2 = GetRegressionLine(matx1, vec_row1);
    
       Print("AFTER:");
       PrintVectors();
    
    
    //--- return value of prev_calculated for next call
       return(rates_total);
    }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    vector GetRegressionLine(const matrix& matx, const vector& b) {
       vector vec_res = matx.LstSq(b);
       return(vec_res);
    }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    vector GetRowAsVector(const matrix& matx, const long src_row) {
       vector vec_res = matx.Row(src_row);
       return(vec_res);
    }
    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    void PrintVectors() {
       for(int i = 0; i < cols; i++) {
          Print(StringFormat("vec_row1[%d] = ", i), vec_row1[i]);
       }
       for(int i = 0; i < cols; i++) {
          Print(StringFormat("vec_row2[%d] = ", i), vec_row2[i]);
       }
    }
    //+------------------------------------------------------------------+
    void PrintMatrix() {
    
       for(int i = 0; i < rows; i++) {
          Print(StringFormat("matrix row number %d",i));
          for(int j = 0; j < cols; j++) {
             Print(StringFormat("matx1[%d][%d] = ", i, j), matx1[i][j]);
          }
       }
    }
    //+------------------------------------------------------------------+


  3. Last Error

    96

    This error doesn't exist in the list



    58

    Two 'OnCalculate' functions are defined. OnCalculate () at one price array will be used


    I don't have two OnCalculate() functions defined...
Documentation on MQL5: Event Handling / OnCalculate
Documentation on MQL5: Event Handling / OnCalculate
  • www.mql5.com
OnCalculate - Event Handling - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
 
vector GetRegressionLine(const matrix& matx, const vector& b)
  {
   ResetLastError();
   vector vec_res = matx.LstSq(b);
   int err=_LastError;          // 4003
   return(vec_res);

ERR_INVALID_PARAMETER

4003

Wrong parameter when calling the system function

Least square is in the form :

y = mx + c    Your are searching for m and c.

Your vector b is y, that's ok.

But the matrix you need to provide is based on the x ( A = [[x 1]]as stated in python example).

Something like :

([[ 0., 1.], [ 1., 1.], [ 2., 1.], ... [ 13., 1.]])

Reason: