292 lines
		
	
	
		
			No EOL
		
	
	
		
			26 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			No EOL
		
	
	
		
			26 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                                   RegressionModels3.mqh |
 | 
						|
//|                                                                    |
 | 
						|
//|    This library implements simple machine learning models for    |
 | 
						|
//|    price prediction, including Logistic and Linear Regression.   |
 | 
						|
//|                                                                    |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
#property strict
 | 
						|
 | 
						|
//--- Include files
 | 
						|
#include <Indicators\Indicators.mqh>
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Class for Logistic Regression Model                                |
 | 
						|
//| Predicts the probability of a binary outcome (e.g., up/down).      |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CLogisticRegression
 | 
						|
{
 | 
						|
private:
 | 
						|
    double weights[];
 | 
						|
    double learning_rate;
 | 
						|
    double lambda;
 | 
						|
    double learning_decay;
 | 
						|
 | 
						|
 | 
						|
    double ema_trend_min;
 | 
						|
    double ema_trend_max;
 | 
						|
    
 | 
						|
     double normalized_rsi_min;
 | 
						|
     double normalized_rsi_max;
 | 
						|
     double normalized_atr_min;
 | 
						|
     double normalized_atr_max;
 | 
						|
     double normalized_pivot_dist_min;
 | 
						|
     double normalized_pivot_dist_max;
 | 
						|
     double normalized_volume_min;
 | 
						|
     double normalized_volume_max;
 | 
						|
     double normalized_adx_min;
 | 
						|
     double normalized_adx_max;
 | 
						|
 | 
						|
 | 
						|
    double sigmoid(double x)
 | 
						|
    {
 | 
						|
        return 1.0 / (1.0 + MathExp(-x));
 | 
						|
    }
 | 
						|
    
 | 
						|
    double normalize(double value, double min_value, double max_value)
 | 
						|
    {
 | 
						|
        if (max_value - min_value == 0) return 0.5;
 | 
						|
        return (value - min_value) / (max_value - min_value);
 | 
						|
    }
 | 
						|
    
 | 
						|
public:
 | 
						|
    CLogisticRegression(double regularization_lambda = 0.002, double decay_factor = 0.999)
 | 
						|
    {
 | 
						|
        ArrayResize(weights, 8); // 1 bias + 7 feature
 | 
						|
    for(int i = 0; i < 8; i++) weights[i] = 0.0;
 | 
						|
        learning_rate = 0.02;
 | 
						|
        lambda = regularization_lambda;
 | 
						|
        learning_decay = decay_factor;
 | 
						|
       ema_trend_min = -100 * _Point;
 | 
						|
       ema_trend_max = 100 * _Point;
 | 
						|
       
 | 
						|
       normalized_rsi_min = 0;
 | 
						|
       normalized_rsi_max = 100;
 | 
						|
       normalized_atr_min = 0;
 | 
						|
       normalized_atr_max = 200;
 | 
						|
       normalized_pivot_dist_min = 0;
 | 
						|
       normalized_pivot_dist_max = 500;
 | 
						|
       normalized_volume_min = 0;
 | 
						|
       normalized_volume_max = 5;
 | 
						|
       normalized_adx_min = 0;
 | 
						|
       normalized_adx_max = 100;
 | 
						|
    }
 | 
						|
 | 
						|
   double to_sym(double x01) { return 2.0 * x01 - 1.0; };
 | 
						|
 | 
						|
   double PredictAndLearn(
 | 
						|
       int actual_output,
 | 
						|
       string symbol, ENUM_TIMEFRAMES period,
 | 
						|
       int rsi_period, int bollinger_period, double bollinger_dev,
 | 
						|
       int atr_period, bool enable_ema_filter, ENUM_TIMEFRAMES ema_filter_timeframe,
 | 
						|
       int ema_fast_period, int ema_slow_period,
 | 
						|
       double pivot_distance_pips, double volume_ratio, double adx_value)
 | 
						|
   {
 | 
						|
       double rsi_value = iRSI(symbol, period, rsi_period, PRICE_CLOSE);
 | 
						|
       double atr_value = iATR(symbol, period, atr_period);
 | 
						|
       double current_close = iClose(symbol, period, 0);
 | 
						|
   
 | 
						|
       double bollinger_upper = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 0);
 | 
						|
       double bollinger_lower = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 1);
 | 
						|
   
 | 
						|
       double bollinger_position = 0.5;
 | 
						|
       if (bollinger_upper > bollinger_lower)
 | 
						|
       {
 | 
						|
           bollinger_position = (current_close - bollinger_lower) / (bollinger_upper - bollinger_lower);
 | 
						|
       }
 | 
						|
   
 | 
						|
       double ema_fast_val = iMA(symbol, ema_filter_timeframe, ema_fast_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
       double ema_slow_val = iMA(symbol, ema_filter_timeframe, ema_slow_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
   
 | 
						|
       double ema_trend_input01 = 0.5;
 | 
						|
       if(enable_ema_filter && ema_fast_val > 0 && ema_slow_val > 0)
 | 
						|
       {
 | 
						|
           if (ema_fast_val - ema_slow_val < ema_trend_min)
 | 
						|
               ema_trend_min = ema_fast_val - ema_slow_val;
 | 
						|
           if (ema_fast_val - ema_slow_val > ema_trend_max)
 | 
						|
               ema_trend_max = ema_fast_val - ema_slow_val;
 | 
						|
   
 | 
						|
           ema_trend_input01 = normalize(ema_fast_val - ema_slow_val, ema_trend_min, ema_trend_max);
 | 
						|
       }
 | 
						|
   
 | 
						|
       // Aggiorna i range dinamici come già fai
 | 
						|
       if (rsi_value < normalized_rsi_min) normalized_rsi_min = rsi_value;
 | 
						|
       if (rsi_value > normalized_rsi_max) normalized_rsi_max = rsi_value;
 | 
						|
       double rsi01 = normalize(rsi_value, normalized_rsi_min, normalized_rsi_max);
 | 
						|
   
 | 
						|
       double atrp = atr_value / _Point;
 | 
						|
       if (atrp < normalized_atr_min) normalized_atr_min = atrp;
 | 
						|
       if (atrp > normalized_atr_max) normalized_atr_max = atrp;
 | 
						|
       double atr01 = normalize(atrp, normalized_atr_min, normalized_atr_max);
 | 
						|
   
 | 
						|
       if (pivot_distance_pips < normalized_pivot_dist_min) normalized_pivot_dist_min = pivot_distance_pips;
 | 
						|
       if (pivot_distance_pips > normalized_pivot_dist_max) normalized_pivot_dist_max = pivot_distance_pips;
 | 
						|
       double pivot01 = normalize(pivot_distance_pips, normalized_pivot_dist_min, normalized_pivot_dist_max);
 | 
						|
   
 | 
						|
       if (volume_ratio < normalized_volume_min) normalized_volume_min = volume_ratio;
 | 
						|
       if (volume_ratio > normalized_volume_max) normalized_volume_max = volume_ratio;
 | 
						|
       double vol01 = normalize(volume_ratio, normalized_volume_min, normalized_volume_max);
 | 
						|
   
 | 
						|
       if (adx_value < normalized_adx_min) normalized_adx_min = adx_value;
 | 
						|
       if (adx_value > normalized_adx_max) normalized_adx_max = adx_value;
 | 
						|
       double adx01 = normalize(adx_value, normalized_adx_min, normalized_adx_max);
 | 
						|
   
 | 
						|
       // 1) Centra in [-1,1]
 | 
						|
       double ema_trend_sym = to_sym(ema_trend_input01);
 | 
						|
       double rsi_sym       = to_sym(rsi01);
 | 
						|
       double bbpos_sym     = to_sym(bollinger_position);
 | 
						|
       double atr_sym       = to_sym(atr01);
 | 
						|
       double pivot_sym     = to_sym(pivot01);
 | 
						|
       double vol_sym       = to_sym(vol01);
 | 
						|
       double adx_sym       = to_sym(adx01);
 | 
						|
   
 | 
						|
       // 2) Input con bias in testa
 | 
						|
       double x[8] = {
 | 
						|
           -1.0,             // bias
 | 
						|
           rsi_sym,
 | 
						|
           bbpos_sym,
 | 
						|
           atr_sym,
 | 
						|
           ema_trend_sym,
 | 
						|
           pivot_sym,
 | 
						|
           vol_sym,
 | 
						|
           adx_sym
 | 
						|
       };
 | 
						|
   
 | 
						|
       // 3) Somma pesata e gain di risposta
 | 
						|
       double weighted_sum = 0.0;
 | 
						|
       for (int i = 0; i < ArraySize(weights); i++)
 | 
						|
           weighted_sum += weights[i] * x[i];
 | 
						|
   
 | 
						|
       const double response_gain = 2.0; // 1.5-3.0 tipicamente
 | 
						|
       double prediction = sigmoid(response_gain * weighted_sum);
 | 
						|
   
 | 
						|
       // 4) Aggiorna i pesi con regolarizzazione e decay
 | 
						|
       double error = actual_output - prediction;
 | 
						|
       for (int i = 0; i < ArraySize(weights); i++)
 | 
						|
       {
 | 
						|
           // weight decay moltiplicativo + gradiente regolarizzato
 | 
						|
           double grad = error * x[i] - lambda * weights[i];
 | 
						|
           weights[i] = weights[i] * learning_decay + learning_rate * grad;
 | 
						|
       }
 | 
						|
       Print("inputs_logistic", x[1], "/", x[2], "/", x[3], "/", x[4], "/", x[5], "/", x[6], "/", x[7]);
 | 
						|
   
 | 
						|
       return prediction;
 | 
						|
   }
 | 
						|
    
 | 
						|
    double get_probability(string symbol, ENUM_TIMEFRAMES period, int rsi_period, int bollinger_period, double bollinger_dev, int atr_period, bool enable_ema_filter, ENUM_TIMEFRAMES ema_filter_timeframe, int ema_fast_period, int ema_slow_period, double pivot_distance_pips, double volume_ratio, double adx_value)
 | 
						|
    {
 | 
						|
        double rsi_value = iRSI(symbol, period, rsi_period, PRICE_CLOSE);
 | 
						|
        double atr_value = iATR(symbol, period, atr_period);
 | 
						|
        double current_close = iClose(symbol, period, 0);
 | 
						|
 | 
						|
        double bollinger_upper = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 0);
 | 
						|
        double bollinger_lower = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 1);
 | 
						|
        
 | 
						|
        double bollinger_position = 0.5;
 | 
						|
        if (bollinger_upper > bollinger_lower)
 | 
						|
        {
 | 
						|
            bollinger_position = (current_close - bollinger_lower) / (bollinger_upper - bollinger_lower);
 | 
						|
        }
 | 
						|
        
 | 
						|
        double ema_fast_val = iMA(symbol, ema_filter_timeframe, ema_fast_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
        double ema_slow_val = iMA(symbol, ema_filter_timeframe, ema_slow_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
 | 
						|
        double ema_trend_input = 0.5;
 | 
						|
        if(enable_ema_filter && ema_fast_val > 0 && ema_slow_val > 0)
 | 
						|
        {
 | 
						|
            ema_trend_input = normalize(ema_fast_val - ema_slow_val, -100 * _Point, 100 * _Point);
 | 
						|
        }
 | 
						|
 | 
						|
        double normalized_rsi = normalize(rsi_value, 0, 100);
 | 
						|
        double normalized_atr = normalize(atr_value / _Point, 0, 200);
 | 
						|
        double normalized_pivot_dist = normalize(pivot_distance_pips, 0, 500);
 | 
						|
        double normalized_volume = normalize(volume_ratio, 0, 5);
 | 
						|
        double normalized_adx = normalize(adx_value, 0, 100);
 | 
						|
 | 
						|
        double inputs_logistic[7] = { normalized_rsi, bollinger_position, normalized_atr, ema_trend_input, normalized_pivot_dist, normalized_volume, normalized_adx };
 | 
						|
        //Print("inputs_logistic", inputs_logistic[0], "/", inputs_logistic[1], "/", inputs_logistic[2], "/", inputs_logistic[3], "/", inputs_logistic[4], "/", inputs_logistic[5], "/", inputs_logistic[6]);
 | 
						|
        
 | 
						|
        double weighted_sum = 0.0;
 | 
						|
        for (int i = 0; i < ArraySize(weights); i++) {
 | 
						|
            weighted_sum += weights[i] * inputs_logistic[i];
 | 
						|
        }
 | 
						|
 | 
						|
        return sigmoid(weighted_sum);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Class for Linear Regression Model                                |
 | 
						|
//| Predicts the magnitude of a continuous outcome (e.g., pips).       |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
class CLinearRegression
 | 
						|
{
 | 
						|
private:
 | 
						|
    double weights[];
 | 
						|
    double learning_rate;
 | 
						|
    double lambda;
 | 
						|
    double learning_decay;
 | 
						|
 | 
						|
    double normalize(double value, double min_value, double max_value)
 | 
						|
    {
 | 
						|
        if (max_value - min_value == 0) return 0.5;
 | 
						|
        return (value - min_value) / (max_value - min_value);
 | 
						|
    }
 | 
						|
 | 
						|
public:
 | 
						|
    CLinearRegression(double regularization_lambda = 0.001, double decay_factor = 0.999)
 | 
						|
    {
 | 
						|
        ArrayResize(weights, 7); // 6 + 1 per il ADX
 | 
						|
        for(int i = 0; i < 7; i++) weights[i] = 0.0;
 | 
						|
        learning_rate = 0.01;
 | 
						|
        lambda = regularization_lambda;
 | 
						|
        learning_decay = decay_factor;
 | 
						|
    }
 | 
						|
 | 
						|
    double PredictAndLearn(double actual_output_magnitude_in_pips, string symbol, ENUM_TIMEFRAMES period, int rsi_period, int bollinger_period, double bollinger_dev, int atr_period, bool enable_ema_filter, ENUM_TIMEFRAMES ema_filter_timeframe, int ema_fast_period, int ema_slow_period, double pivot_distance_pips, double volume_ratio, double adx_value)
 | 
						|
    {
 | 
						|
        double rsi_value = iRSI(symbol, period, rsi_period, PRICE_CLOSE);
 | 
						|
        double atr_value = iATR(symbol, period, atr_period);
 | 
						|
        double current_close = iClose(symbol, period, 0);
 | 
						|
 | 
						|
        double bollinger_upper = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 0);
 | 
						|
        double bollinger_lower = iBands(symbol, period, bollinger_period, 0, bollinger_dev, 1);
 | 
						|
        
 | 
						|
        double bollinger_position = 0.5;
 | 
						|
        if (bollinger_upper > bollinger_lower)
 | 
						|
        {
 | 
						|
            bollinger_position = (current_close - bollinger_lower) / (bollinger_upper - bollinger_lower);
 | 
						|
        }
 | 
						|
        
 | 
						|
        double ema_fast_val = iMA(symbol, ema_filter_timeframe, ema_fast_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
        double ema_slow_val = iMA(symbol, ema_filter_timeframe, ema_slow_period, 0, MODE_EMA, PRICE_CLOSE);
 | 
						|
 | 
						|
        double ema_trend_input = 0.5;
 | 
						|
        if(enable_ema_filter && ema_fast_val > 0 && ema_slow_val > 0)
 | 
						|
        {
 | 
						|
            ema_trend_input = normalize(ema_fast_val - ema_slow_val, -100 * _Point, 100 * _Point);
 | 
						|
        }
 | 
						|
 | 
						|
        double normalized_rsi = normalize(rsi_value, 0, 100);
 | 
						|
        double normalized_atr = normalize(atr_value / _Point, 0, 200);
 | 
						|
        double normalized_pivot_dist = normalize(pivot_distance_pips, 0, 500);
 | 
						|
        double normalized_volume = normalize(volume_ratio, 0, 5);
 | 
						|
        double normalized_adx = normalize(adx_value, 0, 100);
 | 
						|
 | 
						|
        double inputs_linear[7] = { normalized_rsi, bollinger_position, normalized_atr, ema_trend_input, normalized_pivot_dist, normalized_volume, normalized_adx };
 | 
						|
        //Print("inputs_linear", inputs_linear[0], "/", inputs_linear[1], "/", inputs_linear[2], "/", inputs_linear[3], "/", inputs_linear[4], "/", inputs_linear[5], "/", inputs_linear[6]);
 | 
						|
        double prediction = 0.0;
 | 
						|
        for (int i = 0; i < ArraySize(weights); i++) {
 | 
						|
            prediction += weights[i] * inputs_linear[i];
 | 
						|
        }
 | 
						|
 | 
						|
        double error = actual_output_magnitude_in_pips - prediction;
 | 
						|
 | 
						|
        for (int i = 0; i < ArraySize(weights); i++)
 | 
						|
        {
 | 
						|
            weights[i] = weights[i] * learning_decay + learning_rate * (error * inputs_linear[i] - lambda * weights[i]);
 | 
						|
        }
 | 
						|
 | 
						|
        return prediction;
 | 
						|
    }
 | 
						|
}; |