kNN Indicator not plotting

 
//+------------------------------------------------------------------+
//|                                                          RSI.mq5 |
//|                   Copyright 2009-2017, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+

//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_type1   DRAW_LINE
#property indicator_color1  LightSeaGreen

#property indicator_label1  "kNN"

input int k = 5;
input int period = 14;
input int slowPeriod = 28;
input int pastDataSize = 100;

// Declare arrays for feature values
double Feature1[];
double Feature2[];

double PredictionLine[];


// Declare arrays for indicators
double RSI1[];
double RSI2[];
double MOM1[];
double MOM2[];
double ROC1[];
double ROC2[];
double CCI1[];
double CCI2[];


double RSI1handle, RSI2handle, CCI1handle, CCI2handle, MOM1handle, MOM2handle, kNNhandle1, kNNhandle2;

double openhandle0, closehandle0, openhandle1, closehandle1, class_labelhandle;

// Declare arrays for distances and predictions
double Distances[];
double Directions[];
double Predictions[];

double Feature1indicators[];
double Feature2indicators[];

// On initialization of the indicator
int OnInit()
{
    // Set the indicator buffers
    SetIndexBuffer(0, Feature1, INDICATOR_DATA);
    SetIndexBuffer(1, Feature2, INDICATOR_DATA);
    SetIndexBuffer(2, Directions, INDICATOR_CALCULATIONS);
    SetIndexBuffer(3, Directions, INDICATOR_CALCULATIONS);
    SetIndexBuffer(4, Predictions, INDICATOR_CALCULATIONS);


    SetIndexBuffer(5, PredictionLine, INDICATOR_DATA);
    IndicatorSetInteger(INDICATOR_DIGITS, _Digits);

    //--- sets first bar from what index will be drawn
    PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,period-1);
    
    // Set the indicator parameters
    string short_name=StringFormat("kNN(%d,%d,%d)",k,period,slowPeriod);
    IndicatorSetString(INDICATOR_SHORTNAME,short_name);
    
    // Calculate the indicators for the current bar with period 14
    RSI1handle = iRSI(_Symbol, _Period, period, PRICE_CLOSE);
    MOM1handle = iMomentum(_Symbol, _Period, period, PRICE_CLOSE);
    CCI1handle = iCCI(_Symbol, _Period, period, PRICE_CLOSE);
    
    // Calculate the indicators for the current bar with period 14
    RSI2handle = iRSI(_Symbol, _Period, slowPeriod, PRICE_CLOSE);
    MOM2handle = iMomentum(_Symbol, _Period, slowPeriod, PRICE_CLOSE);
    CCI2handle = iCCI(_Symbol, _Period, slowPeriod, PRICE_CLOSE);
         
    openhandle0 = iOpen(_Symbol,_Period, 0);
    closehandle0 = iClose(_Symbol,_Period, 0);
    openhandle1 = iOpen(_Symbol,_Period, 1);
    closehandle1 = iClose(_Symbol,_Period, 1);
    
    class_labelhandle = closehandle1 - closehandle0;
    
    kNNhandle1 = (RSI1handle + MOM1handle + CCI1handle ) / 3.0;
    kNNhandle2 = (RSI2handle + MOM2handle + CCI2handle ) / 3.0;
    
    // Initialize the arrays
//    ArraySetAsSeries(Feature1s, true);
 //   ArraySetAsSeries(Feature2s, true);
  //  ArraySetAsSeries(Distances, true);
   // ArraySetAsSeries(Directions, true);
   // ArraySetAsSeries(Predictions, true);
    
    // Return success
    return(INIT_SUCCEEDED);
}

// On calculation of the indicator
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[])
{
    // Declare variables
    int i;
    int start = prev_calculated > 0 ? prev_calculated - 1 : period;

    
    double maxDist =-999.0;
    
    ArrayResize(Predictions, 0);
    // Calculate the slow period
//    int slowPeriod2 = slowPeriod * 2;
    
    // Calculate the feature values for each bar
    for (i = start; i < rates_total; i++)
    {
        int class_label = 0;
        // Classification data, what happens on the next bar
        if (closehandle1 < closehandle0)
            {
            class_label = -1;
            }
        if (closehandle1 > closehandle0)
            {
            class_label = 1;
            }
         Directions[i] = class_label;
//        int class_label = (closehandle1 < closehandle0) ? -1 : (closehandle1 > closehandle0) ? 1 : 0;
        
        // Calculate feature 1 as the average of RSI, MOM, and ROC
        double feature1Value = kNNhandle1;
        double feature2Value = kNNhandle2;
        
        Feature1[i] = feature1Value;
        Feature2[i] = feature2Value;

         // Calculate the euclidean distance of current point to all historic points
        double d = MathSqrt(MathPow(feature1Value - Feature1[i], 2) + MathPow(feature2Value - Feature2[i], 2));
       
         if (d > maxDist)
         {
            maxDist = d;
   if (ArraySize(Predictions) >= k)
    {
        // Shift elements in the Predictions array to the left by 1 position
        for (int j = 0; j < ArraySize(Predictions) - 1; j++)
        {
            Predictions[j] = Predictions[j + 1];
        }
        // Resize the Predictions array if necessary
        ArrayResize(Predictions, k);
    }
    else
    {
        // Resize the Predictions array to add a new element
        ArrayResize(Predictions, ArraySize(Predictions) + 1);
    }
    // Add the new direction at the end of the Predictions array
    Predictions[ArraySize(Predictions) - 1] = Directions[i];
}

    }
   
    // Sum the predictions and plot the result
    double prediction = 0;
    for(int j=0;  j< ArraySize(Predictions); j++)
      {
      prediction += Predictions[j];
      }
   PredictionLine[i] = prediction;
      


    return(rates_total);
}

Hello everyone, I have searched on the forum but I could not properly identify what's going on on my code, since I don't receive an error.

The code should work like this:


1 - Get the RSI, CCI, and MOM values for the period of 14 and 28;

2 - Average them and respectively insert them in arrays. Feature1 and Feature2;

3 - If Close[0] > Close[1], assign -1 to an array. Else, +1. Store it in Directions;

4 - For the new bar, get the average values from the three indicators in both periods, and calculate the euclidean distance from each of the past values (in this case, 100). So d=sqrt((f1-Feature1)^2 + (f2-Feature2)^2) . Get the k=5 nearest neighbors and retreive their +1 or -1 values on step 3 and put them into an array called Predictions;

5 - Sum the elements in step 4 and plot them with the array PredictionsLine.


My code is compiling without error, but the plot is giving an horizontal line of a fixed value. somewhere in the loop the values are not being updated. Could someone be so kind and take a look?


PS. There are a lot of arrays and handles in the code that are not being used that I am keeping for testing different versions of the code.

Documentation on MQL5: Constants, Enumerations and Structures / Objects Constants / Object Types
Documentation on MQL5: Constants, Enumerations and Structures / Objects Constants / Object Types
  • www.mql5.com
Object Types - Objects Constants - Constants, Enumerations and Structures - MQL5 Reference - Reference on algorithmic/automated trading language for MetaTrader 5
Files:
kNN_v19.mq5  6 kb
 
gustgdp: what's going on on my code, since I don't receive an error.
  1. Does this:
    #property indicator_buffers 1
    #property indicator_plots   1
    Match this:
        SetIndexBuffer(0, Feature1, INDICATOR_DATA);
        SetIndexBuffer(1, Feature2, INDICATOR_DATA);
        SetIndexBuffer(2, Directions, INDICATOR_CALCULATIONS);
        SetIndexBuffer(3, Directions, INDICATOR_CALCULATIONS);
        SetIndexBuffer(4, Predictions, INDICATOR_CALCULATIONS);
        SetIndexBuffer(5, PredictionLine, INDICATOR_DATA);

  2. Total nonsense.
    Average the values read.
        kNNhandle1 = (RSI1handle + MOM1handle + CCI1handle ) / 3.0;
        kNNhandle2 = (RSI2handle + MOM2handle + CCI2handle ) / 3.0;
  3. A handle is not a value.
    Read in the values.
            double feature1Value = kNNhandle1;
            double feature2Value = kNNhandle2;
  4. You do not resize buffers.
        SetIndexBuffer(4, Predictions, INDICATOR_CALCULATIONS);
       ⋮
            ArrayResize(Predictions, k);
 

i apologize for the intrusion but won't you need to store the outcome of what you are collecting the kNN distance from somewhere ?

Like , distance from values that have resulted in ... and then tally the votes 

And won't you also need the closest k to your stored "knowns" ?