259 lines
5.9 KiB
Plaintext
259 lines
5.9 KiB
Plaintext
///////////////////////////////////////////////////////
|
|
//
|
|
// SaherElm IT Center MQL5 NN Class Library
|
|
// ----------------------------------------
|
|
// Name: XNNClass
|
|
// Description: provides all classes for implementing
|
|
// Neural Network ...
|
|
//
|
|
//
|
|
// Maintainer:
|
|
// ------------
|
|
// Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com)
|
|
//
|
|
//////////////////////////////////////////////////////
|
|
//
|
|
// Global Properties ...
|
|
#property library
|
|
#property copyright "Copyright 2023, SaherElm IT Center"
|
|
#property link "https://www.saherelm.ir"
|
|
#property version "1.00"
|
|
#property strict
|
|
|
|
//
|
|
// START Global Definitions: Variables, Properties and etc ...
|
|
//
|
|
class XCNNBase
|
|
{
|
|
//
|
|
// Public Definitions ...
|
|
public:
|
|
//
|
|
// Constructor ...
|
|
void XCNNBase(
|
|
int nodes = 10, // Number of Input Nodes
|
|
double starterWeight = 0.5, // start weight for each input
|
|
double coEfficient = 0.1, // COEfficient Multiplier
|
|
double upperRange = 1, // Upper Normal Range Value
|
|
double lowerRange = -1, // Lower Normal Range Value
|
|
double learningRates = 0.1 // Back Propagation Learning Rate
|
|
) {
|
|
//
|
|
mNodes = nodes;
|
|
mUpperRange = upperRange;
|
|
mLowerRange = lowerRange;
|
|
mCoEfficient = coEfficient;
|
|
mLearningRates = learningRates;
|
|
mStarterWeight = starterWeight;
|
|
|
|
//
|
|
ReConstructWeights();
|
|
}
|
|
|
|
//
|
|
// Deconstructor ...
|
|
void ~XCNNBase() {}
|
|
|
|
//
|
|
// Protected Definitions ...
|
|
void NormalizeInputs(double &inputs[], double &result[])
|
|
{
|
|
//
|
|
ArrayFree(result);
|
|
ArrayResize(result, 1);
|
|
|
|
//
|
|
// Validate inputs ...
|
|
if (ArraySize(inputs) != mNodes)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Prepare Result ...
|
|
ArrayResize(result, mNodes);
|
|
|
|
//
|
|
// Calculating min and max range value ...
|
|
double minRangeValue = inputs[ArrayMinimum(inputs)];
|
|
double maxRangeValue = inputs[ArrayMaximum(inputs)];
|
|
|
|
//
|
|
// Loop through Inputs nd Normalize them ...
|
|
for (int i = 0; i < mNodes; i++)
|
|
{
|
|
//
|
|
double normalValue = (((inputs[i] - minRangeValue) * (mUpperRange - mLowerRange)) / (maxRangeValue - minRangeValue)) + mLowerRange;
|
|
result[i] = normalValue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Hyperbolic Tangent Activation Function ...
|
|
double TanHActivationFunction(double weightedInputs)
|
|
{
|
|
//
|
|
double result = (exp(weightedInputs) - exp(-weightedInputs)) / (exp(weightedInputs) + exp(-weightedInputs));
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Weighted Inputs ...
|
|
double CalculateWeightedInputs(
|
|
double &inputs[],
|
|
bool applyCOEfficient = true)
|
|
{
|
|
//
|
|
double result = 0;
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
if (ArraySize(inputs) != mNodes)
|
|
{
|
|
//
|
|
result = -1;
|
|
return result;
|
|
}
|
|
|
|
//
|
|
for (int i = 0; i < mNodes; i++)
|
|
{
|
|
result += inputs[i] * mWeights[i];
|
|
}
|
|
|
|
//
|
|
// Multiply if required ...
|
|
if (applyCOEfficient)
|
|
{
|
|
result *= mCoEfficient;
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Hidden Layers ...
|
|
virtual double CalculateHiddenLayer(double &inputs[])
|
|
{
|
|
//
|
|
// this is Default Activation Function which used ...
|
|
// you can override this by writing your own ...
|
|
double totalWeightedInputs = CalculateWeightedInputs(inputs);
|
|
double result = TanHActivationFunction(totalWeightedInputs);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Calculate Output Layers ...
|
|
double CalculateOutputLayer(double &inputs[])
|
|
{
|
|
//
|
|
double result = -1;
|
|
|
|
//
|
|
// Validate Inputs ...
|
|
if (ArraySize(inputs) != mNodes) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double normalizedInputs[];
|
|
NormalizeInputs(inputs, normalizedInputs);
|
|
if (ArraySize(normalizedInputs) != mNodes) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
double hiddenLayerResult = CalculateHiddenLayer(normalizedInputs);
|
|
|
|
//
|
|
result = 1 * hiddenLayerResult;
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Basck Propaggation Learning ...
|
|
void BackPropagation(
|
|
double &inputs[],
|
|
double &outputs,
|
|
double targetOutput
|
|
) {
|
|
//
|
|
// Validate Inputs ...
|
|
if (ArraySize(inputs) != mNodes) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
double normalizedInputs[];
|
|
NormalizeInputs(inputs, normalizedInputs);
|
|
if (ArraySize(normalizedInputs) != mNodes) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
double error = targetOutput - outputs;
|
|
double derivative = 1 - MathPow(outputs, 2);
|
|
|
|
//
|
|
for (int i = 0; i < mNodes; i++) {
|
|
//
|
|
double gradient = error * derivative * inputs[i];
|
|
mWeights[i] = mLearningRates * gradient;
|
|
}
|
|
}
|
|
|
|
protected:
|
|
//
|
|
// Private Definitions ...
|
|
private:
|
|
//
|
|
// Number of Input Nodes ...
|
|
int mNodes;
|
|
|
|
//
|
|
// Specify Upper range of Normal Values ...
|
|
double mUpperRange;
|
|
|
|
//
|
|
// Specify Lower range of Normal Values ...
|
|
double mLowerRange;
|
|
|
|
//
|
|
// Starter Weight for each input node ...
|
|
double mStarterWeight;
|
|
|
|
//
|
|
// double Input Node Weights ...
|
|
double mWeights[];
|
|
|
|
//
|
|
// CoEfficient is a multiplyer for weighted inputs ...
|
|
double mCoEfficient;
|
|
|
|
//
|
|
// Back Propagation Learning Rates ...
|
|
double mLearningRates;
|
|
|
|
//
|
|
// ReConstruct Weights ...
|
|
void ReConstructWeights() {
|
|
//
|
|
ArrayFree(mWeights);
|
|
ArrayResize(mWeights, mNodes);
|
|
|
|
//
|
|
for (int i = 0; i< mNodes; i++) {
|
|
mWeights[i] = mStarterWeight;
|
|
}
|
|
}
|
|
}
|
|
//
|
|
// END Global Definitions: Variables, Properties and etc ...
|
|
//
|