FANN lib train

//+------------------------------------------------------------------+

//|                                                    FannLib_2.mq4 |

//|                      Copyright © 2009, MetaQuotes Software Corp. |

//|                                        http://www.metaquotes.net |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2009, MetaQuotes Software Corp."

#property link      "http://www.metaquotes.net"

#property indicator_separate_window

#property  indicator_buffers 0

#include <Fann2MQL.mqh>

// Global defines

#define ANN_PATH "C:\\ANN\\"

#define nn_layer 4   // the total number of layers. here, there is one input layer, 2 hidden layers, and one output layer = 4 layers.

#define nn_input 3   // Number of input neurones. Our pattern is made of 3 numbers, so that means 3 input neurones.

#define nn_hidden1 8 // Number of neurones on the first hidden layer

#define nn_hidden2 5 // number on the second hidden layer

#define nn_output 1  // number of outputs

#define nn_input_nn_output 4 // IMPORTANT! size = nn_input + nn_output

// trainingData[][] will contain the examples we're gonna use to teach the rules to the neurones.

double      trainingData[][nn_input_nn_output]; 

int maxTraining = 500;  // maximun number of time we will train the neurones with some examples

double targetMSE = 0.00002; // the Mean-Square Error of the neurones we should get at most (you will understand this lower in the code)

int ann; // This var will be the identifier of the neuronal network.

//+------------------------------------------------------------------+

//| Custom indicator deinitialization function                       |

//+------------------------------------------------------------------+

int deinit()

  {

//----

      f2M_destroy_all_anns();

//----

   return(0);

  }

  

//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int init()

  {

   int i;

   double MSE;  

//---- indicators

   IndicatorBuffers(0);

   IndicatorDigits(6);

 

   ArrayResize(trainingData,1);  

   

   // We create a new neuronal networks

   ann = f2M_create_standard(nn_layer, nn_input, nn_hidden1, nn_hidden2, nn_output);

   // We set the activation function. Don't worry about that. Just do it.

f2M_set_act_function_hidden (ann, FANN_SIGMOID_SYMMETRIC_STEPWISE);

f2M_set_act_function_output (ann, FANN_SIGMOID_SYMMETRIC_STEPWISE);

// Some studies show that statistically, the best results are reached using this range; but you can try to change and see is it gets better or worst

f2M_randomize_weights (ann, -0.77, 0.77);


   // UP UP = UP / if a < b && b < c then output = 1

   prepareTrainingData(1,2,3,1);

   prepareTrainingData(8,12,20,1);

   prepareTrainingData(4,6,8,1);

   prepareTrainingData(0,5,11,1);

   // UP DOWN = DOWN / if a < b && b > c then output = 0

   prepareTrainingData(1,2,1,0);

   prepareTrainingData(8,10,7,0);

   prepareTrainingData(7,10,7,0);

   prepareTrainingData(2,3,1,0);

   // DOWN DOWN = DOWN / if a > b && b > c then output = 0

   prepareTrainingData(8,7,6,0);

   prepareTrainingData(20,10,1,0);

   prepareTrainingData(3,2,1,0);

   prepareTrainingData(9,4,3,0);

   prepareTrainingData(7,6,5,0);

   // DOWN UP = UP / if a > b && b < c then output = 1

   prepareTrainingData(5,4,5,1);

   prepareTrainingData(2,1,6,1);

   prepareTrainingData(20,12,18,1);

   prepareTrainingData(8,2,10,1);   

   

   printDataArray();

   Print("##### TRAINING #####");

   for (i=0;i<maxTraining;i++) {

      MSE = teach(); // everytime the loop run, the teach() function is activated. Check the comments associated to this function to understand more.

      if (MSE < targetMSE) { // if the MSE is lower than what we defined (here targetMSE = 0.02)

         debug("training finished. Trainings ",i+1); // then we print in the console how many training it took them to understand

         i = maxTraining; // and we go out of this loop

      }

   } 

   // we print to the console the MSE value once the training is completed

   debug("MSE",f2M_get_MSE(ann));      

   string AnnPath = ANN_PATH+Symbol()+Period()+".net";

   debug("FANN file:",AnnPath); 

   f2M_save (ann, AnnPath);        

//----

   return(0);

  }  

//+------------------------------------------------------------------+

//| Custom indicator iteration function                              |

//+------------------------------------------------------------------+

int start()

  {

   int    counted_bars=IndicatorCounted();

//----

   

//----

   return(0);

  }

//+------------------------------------------------------------------+

/*************************

** teach()

** Get all the trainign data and use them to train the neurones one time.

** In order to properly train the neurones, you need to run this function many time,

** until the Mean-Square Error get low enough.

*************************/

double teach() {

   int i,j;

   double MSE;

   double inputVector[];

   double outputVector[];

   // we resize the arrays to the right size

   ArrayResize(inputVector,nn_input);

   ArrayResize(outputVector,nn_output);

   int call;

   int bufferSize = ArraySize(trainingData)/nn_input_nn_output-1;

   for (i=0;i<bufferSize;i++) {

     for (j=0;j<nn_input;j++) {

       inputVector[j]=trainingData[bufferSize][j];

     }

     for (j=0;j<nn_output;j++) {

       outputVector[j]=trainingData[bufferSize][nn_input+j];

     }

      //f2M_train() is showing the neurones only one example at a time.

      call = f2M_train(ann, inputVector, outputVector);

   }

   // Once we have show them an example, we check if how good they are by checking their MSE. If it's low, they learn good!

   MSE = f2M_get_MSE(ann);

   return(MSE);

}

/*************************

** prepareTrainingData()

** Prepare the data for training.

*************************/

void prepareTrainingData(double input1, double input2, double input3, double output) {

   int i,j;

   double inputVector[];

   double outputVector[];

   // we resize the arrays to the right size

   ArrayResize(inputVector,nn_input);

   ArrayResize(outputVector,nn_output);

   

   inputVector[0]  = input1;

   inputVector[1]  = input2;

   inputVector[2]  = input3;

   outputVector[0] = output;

   int bufferSize = ArraySize(trainingData)/nn_input_nn_output-1;

      

   //register the input data to the main array

   for (j=0;j<nn_input;j++) {

      trainingData[bufferSize][j] = inputVector[j];

   }

   for (j=0;j<nn_output;j++) {

      trainingData[bufferSize][nn_input+j] = outputVector[j];

   }

   

   ArrayResize(trainingData,bufferSize+2);

}

/*************************

** printDataArray()

** Print the datas used for training the neurones

** This is useless. Just created for debug purpose.

*************************/

void printDataArray() {

   int i,j;

   int bufferSize = ArraySize(trainingData)/nn_input_nn_output-1;

   string lineBuffer = "";

        

   for (i=0;i<bufferSize;i++) {

      for (j=0;j<nn_input_nn_output;j++) {

         lineBuffer = StringConcatenate(lineBuffer, trainingData[i][j], ",");

      }

      debug("DataArray["+i+"]", lineBuffer);      

      lineBuffer = "";

   }

}

/*************************

** debug()

** Print data to the console

*************************/

void debug(string a, string b) {

   Print(a+" ==> "+b);

}