425 lines
		
	
	
	
		
			41 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
			
		
		
	
	
			425 lines
		
	
	
	
		
			41 KiB
		
	
	
	
		
			MQL5
		
	
	
	
	
	
//+------------------------------------------------------------------+
 | 
						|
//|                                     DR LOLI.mq5          |
 | 
						|
//|                    Expert Advisor Linear and Logistic Regression |
 | 
						|
//|                     Min 100.000c Cent Account Leverage 1:500     |
 | 
						|
//|                      XAU/USD                                     |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//test push
 | 
						|
#property copyright "Copyright 2024, MetaQuotes Software Corp."
 | 
						|
#property link         "https://www.mql5.com"
 | 
						|
#property version    "1.42"
 | 
						|
#property description "Expert Advisor for scalping with a linear and logistic regression model."
 | 
						|
#property description "V2.0: Utilizza una libreria separata per la regressione logistica e include l'ATR come input per il modello."
 | 
						|
#property description "V3.0: Usa il profitto futuro per l'apprendimento del modello logistico."
 | 
						|
#property description "V4.0: Aggiunto Stop Loss e Take Profit dinamici all'apertura della posizione."
 | 
						|
#property description "V5.0: Aggiunto controllo profitto sull'equity e verifica margine disponibile."
 | 
						|
#property description "V6.0: Aggiunto limite massimo di posizioni per direzione (buy/sell)."
 | 
						|
#property description "V7.0: Aggiunto controllo di profitto giornaliero e chiusura automatica a fine giornata."
 | 
						|
#property description "V8.0: Corretti errori di compilazione relativi alla data/ora."
 | 
						|
#property description "V9.0: Aggiunto un parametro per definire quale percentuale del profitto da un ordine Take Profit debba essere utilizzata per chiudere parzialmente una posizione in perdita."
 | 
						|
#property description "V10.0: Rimosse le vecchie logiche di chiusura e aggiunta una nuova logica di compensazione giornaliera del rischio."
 | 
						|
#property description "V11.0: Aggiunto un filtro di trend basato su due medie mobili esponenziali (EMA) su timeframe H4, attivabile e disattivabile dall'utente."
 | 
						|
#property description "V12.0: Risolto il problema del filtro di trend che bloccava le posizioni a causa di valori EMA non validi."
 | 
						|
#property description "V13.0: Ritorno alla logica di chiusura basata sull'equity totale e al controllo del margine, come richiesto dall'utente."
 | 
						|
#property description "V14.0: Aggiunto filtro di volatilità basato su ATR e SL/TP dinamici."
 | 
						|
#property description "V15.0: Aggiunta chiusura temporale delle posizioni."
 | 
						|
#property description "V16.0: Aggiunta funzione di recupero drawdown con lotto dinamico."
 | 
						|
#property description "V17.0: Implementazione dei suggerimenti, lotto dinamico in base al rischio e controlli di sicurezza."
 | 
						|
#property description "V18.0: Correzione del bug 'undeclared identifier'."
 | 
						|
#property description "V19.0: Modifica la logica di recupero per utilizzare un lotto fisso definito dall'utente."
 | 
						|
#property description "V20.0: Aggiunto Take Profit fisso per le posizioni di recupero."
 | 
						|
#property description "V21.0: Aggiunto filtro di trend basato su EMA 7 e 14 come input per il modello."
 | 
						|
#property description "V22.0: Sostituito i due modelli (Buy e Sell) con un singolo modello per evitare probabilità contraddittorie."
 | 
						|
#property description "V23.0: Aggiunta regressione lineare per calcolare dinamicamente il Take Profit."
 | 
						|
#property description "V24.0: Il periodo delle EMA è ora configurabile dall'utente."
 | 
						|
#property description "V25.0: Il timeframe del filtro EMA è ora configurabile dall'utente."
 | 
						|
#property description "V26.0: Aggiunti i Pivot Points come input per i modelli."
 | 
						|
#property description "V27.0: Aggiunto il volume come input per i modelli."
 | 
						|
#property description "V28.0: Aggiunto controllo di sicurezza per TP negativi."
 | 
						|
#property description "V29.0: Aggiornamento dei parametri di input."
 | 
						|
#property description "V30.0: Aggiunto filtro ADX e ADX come input per il modello."
 | 
						|
#property description "V31.0: Corretto il problema del valore ADX = 11."
 | 
						|
#property description "V32.0: Utilizza l'handle ADX per un calcolo corretto."
 | 
						|
#property description "V33.0: Aggiunta funzione per rimuovere il TP in caso di drawdown."
 | 
						|
#property description "V34.0: Sostituzione della chiusura fissa con un trailing profit complessivo."
 | 
						|
#property description "V35.0: Implementato un trailing profit basato sull'ATR per maggiore adattabilità alla volatilità."
 | 
						|
#property description "V36.0: Aggiunto moltiplicatore dinamico del lotto in base all'equity del conto."
 | 
						|
#property description "V37.0: Correzione bug Invalid Stops"
 | 
						|
#property description "V38.0: Correzione bug Invalid Stops persistente dovuto a calcolo TP errato"
 | 
						|
#property description "V39.0: Correzione bug Invalid Stops causato da input errati nel modello"
 | 
						|
#property description "V40.0: Aggiunto un controllo di validità sulle previsioni del modello di regressione lineare."
 | 
						|
#property description "V41.0: Implementato un controllo di margine dinamico più robusto."
 | 
						|
 | 
						|
//--- Includes
 | 
						|
#include <Trade\Trade.mqh>
 | 
						|
#include "RegressionModels3.mqh"
 | 
						|
 | 
						|
//--- Inputs
 | 
						|
input double        InpMinProbabilityBuy       = 0.60;      // Min. probability for logistic prediction (0-1)
 | 
						|
input double        InpMinProbabilitySell       = 0.40;      // Min. probability for logistic prediction (0-1)
 | 
						|
input int           InpSuccessLookbackBars  = 20;        // Bars to look back for success criteria
 | 
						|
input int           InpSuccessPipsThreshold = 20;        // Pips threshold for success criteria
 | 
						|
input int           InpBollingerPeriod      = 20;        // Bollinger Bands period
 | 
						|
input double        InpBollingerDeviation   = 2.0;       // Bollinger Bands deviation
 | 
						|
input int           InpRsiPeriod            = 14;        // RSI Period
 | 
						|
input ENUM_APPLIED_PRICE InpRsiPrice           = PRICE_CLOSE; // RSI Applied Price
 | 
						|
input int           InpAtrPeriod            = 14;        // ATR Period
 | 
						|
input double        InpMinAtrFilter         = 1.0;       // Minimum ATR value in points to open a position
 | 
						|
input int           InpAdxPeriod            = 14;        // ADX Period
 | 
						|
input double        InpMinAdxFilter         = 35.0;      // Min. ADX value to open a position
 | 
						|
input double        InpSLMultiplier         = 0.0;       // Stop Loss Multiplier (x ATR)
 | 
						|
input double        InpLotSize              = 0.20;      // Lot size
 | 
						|
input double        InpBalanceFactor        = 10000.0;   // Base value for dynamic lot sizing
 | 
						|
input int           InpMagicNumber          = 12345;     // Magic Number
 | 
						|
input int           InpMaxBuyPositions      = 35;        // Max. Buy positions
 | 
						|
input int           InpMaxSellPositions     = 35;        // Max. Sell positions
 | 
						|
input int           InpTrailingATRPeriod    = 14;        // Trailing Profit ATR Period
 | 
						|
input double        InpTrailingATRMultiplier = 100.0;     // Trailing Profit ATR Multiplier (0 to disable)
 | 
						|
input int           InpCloseAfterDays       = 0;         // Close positions after this many days (0 to disable)
 | 
						|
input bool          InpEnableDrawdownRecovery = true;    // Enable/Disable drawdown recovery
 | 
						|
input int           InpRecoveryStartHour      = 14;        // Start hour for drawdown recovery (server time)
 | 
						|
input int           InpRecoveryEndHour        = 19;        // End hour for drawdown recovery (server time)
 | 
						|
input double        InpRecoveryFixedLot       = 0.40;      // Initial lot size for recovery
 | 
						|
input double        InpRecoveryTakeProfit     = 2000.0;    // Take Profit for recovery trades in pips
 | 
						|
input double        InpMaxLotSize             = 50.0;      // Maximum allowed lot size
 | 
						|
input bool          InpEnableEmaFilter        = true;    // Enable EMA Trend Filter
 | 
						|
input ENUM_TIMEFRAMES InpEmaFilterTimeframe   = PERIOD_H1; // EMA Timeframe
 | 
						|
input int           InpEmaFastPeriod          = 7;         // EMA Fast Period
 | 
						|
input int           InpEmaSlowPeriod          = 14;        // EMA Slow Period
 | 
						|
input ENUM_TIMEFRAMES InpPivotTimeframe       = PERIOD_D1; // Timeframe for Pivot Points
 | 
						|
input int           InpVolumePeriod           = 10;        // Lookback period for volume normalization
 | 
						|
input double        InpMinTakeProfitPips      = 60.0;      // Minimum Take Profit in pips
 | 
						|
input bool          InpRemoveTPOnDrawdown = true;    // Remove TP on drawdown > 2%
 | 
						|
input bool          InpDynamicLotMultiplier = true;    // Enable dynamic lot size based on balance
 | 
						|
input double        InpMaxPredictedPips = 5000;      // New input: Maximum reasonable TP in pips
 | 
						|
 | 
						|
//--- Global objects
 | 
						|
CTrade            m_trade;
 | 
						|
CLogisticRegression      model;
 | 
						|
CLinearRegression        tp_model;
 | 
						|
static double     current_lot_size;
 | 
						|
static double     current_tp_pips; // Pips value for TP
 | 
						|
static int        last_hour_check = -1;
 | 
						|
static bool       is_in_recovery_mode = false;
 | 
						|
static int        adx_handle;
 | 
						|
static double     last_high_equity = 0.0;
 | 
						|
static datetime   last_bar_time;
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Expert initialization function                                   |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
int OnInit()
 | 
						|
  {
 | 
						|
   Print("Expert Advisor started.");
 | 
						|
 | 
						|
// Create ADX handle
 | 
						|
   adx_handle = iADX(_Symbol, _Period, InpAdxPeriod);
 | 
						|
   if(adx_handle == INVALID_HANDLE)
 | 
						|
     {
 | 
						|
      Print("Failed to create ADX handle. Error: ", GetLastError());
 | 
						|
      return(INIT_FAILED);
 | 
						|
     }
 | 
						|
 | 
						|
   return(INIT_SUCCEEDED);
 | 
						|
  }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Expert deinitialization function                                 |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void OnDeinit(const int reason)
 | 
						|
  {
 | 
						|
   Print("Expert Advisor stopped.");
 | 
						|
  }
 | 
						|
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
//| Expert tick function                                             |
 | 
						|
//+------------------------------------------------------------------+
 | 
						|
void OnTick()
 | 
						|
  {
 | 
						|
   datetime current_bar_time = (datetime)SeriesInfoInteger(Symbol(), Period(), SERIES_LASTBAR_DATE);
 | 
						|
   if(current_bar_time == last_bar_time)
 | 
						|
     {
 | 
						|
      return;
 | 
						|
     }
 | 
						|
   last_bar_time = current_bar_time;
 | 
						|
 | 
						|
   double current_balance = AccountInfoDouble(ACCOUNT_BALANCE);
 | 
						|
   double current_equity = AccountInfoDouble(ACCOUNT_EQUITY);
 | 
						|
   double current_atr = iATR(Symbol(), Period(), InpTrailingATRPeriod);
 | 
						|
 | 
						|
// --- Trailing Profit based on ATR ---
 | 
						|
   if(InpTrailingATRMultiplier > 0 && current_equity > current_balance)
 | 
						|
     {
 | 
						|
      if(last_high_equity == 0 || current_equity > last_high_equity)
 | 
						|
        {
 | 
						|
         last_high_equity = current_equity;
 | 
						|
        }
 | 
						|
 | 
						|
      double trailing_level = last_high_equity - (current_atr * InpTrailingATRMultiplier * _Point);
 | 
						|
 | 
						|
      if(current_equity < trailing_level)
 | 
						|
        {
 | 
						|
         for(int i = PositionsTotal() - 1; i >= 0; i--)
 | 
						|
           {
 | 
						|
            ulong position_ticket = PositionGetTicket(i);
 | 
						|
            if(PositionSelectByTicket(position_ticket))
 | 
						|
              {
 | 
						|
               m_trade.PositionClose(position_ticket);
 | 
						|
              }
 | 
						|
           }
 | 
						|
         Print("All positions closed due to overall account trailing profit (ATR-based). Trailing level: ", NormalizeDouble(trailing_level, 2), " Equity: ", NormalizeDouble(current_equity, 2));
 | 
						|
         last_high_equity = 0.0; // Reset high watermark
 | 
						|
         return;
 | 
						|
        }
 | 
						|
     }
 | 
						|
   else
 | 
						|
     {
 | 
						|
      last_high_equity = 0.0; // Reset if trailing is disabled or account is in drawdown
 | 
						|
     }
 | 
						|
 | 
						|
// Get ADX value using handle
 | 
						|
   double adx_values[];
 | 
						|
   if(CopyBuffer(adx_handle, 0, 0, 1, adx_values) <= 0)
 | 
						|
     {
 | 
						|
      Print("Failed to copy ADX values from buffer. Error: ", GetLastError());
 | 
						|
      return;
 | 
						|
     }
 | 
						|
 | 
						|
   double adx_value = adx_values[0];
 | 
						|
 | 
						|
   if(adx_value < InpMinAdxFilter || adx_value == EMPTY_VALUE)
 | 
						|
     {
 | 
						|
      return;
 | 
						|
     }
 | 
						|
 | 
						|
   MqlDateTime server_time;
 | 
						|
   TimeCurrent(server_time);
 | 
						|
 | 
						|
// --- Trading Logic ---
 | 
						|
 | 
						|
// Calculate and learn the models
 | 
						|
   int actual_output = 0;
 | 
						|
   double past_close = iClose(Symbol(), Period(), InpSuccessLookbackBars);
 | 
						|
   double max_high = 0.0;
 | 
						|
   double min_low = 0.0;
 | 
						|
 | 
						|
   double high_prices_lookback[];
 | 
						|
   if(CopyHigh(Symbol(), Period(), InpSuccessLookbackBars + 1, InpSuccessLookbackBars, high_prices_lookback) > 0)
 | 
						|
     {
 | 
						|
      max_high = high_prices_lookback[ArrayMaximum(high_prices_lookback)];
 | 
						|
     }
 | 
						|
 | 
						|
   double low_prices_lookback[];
 | 
						|
   if(CopyLow(Symbol(), Period(), InpSuccessLookbackBars + 1, InpSuccessLookbackBars, low_prices_lookback) > 0)
 | 
						|
     {
 | 
						|
      min_low = low_prices_lookback[ArrayMinimum(low_prices_lookback)];
 | 
						|
     }
 | 
						|
 | 
						|
   double actual_magnitude = 0.0;
 | 
						|
   if((max_high - past_close) / _Point >= InpSuccessPipsThreshold)
 | 
						|
     {
 | 
						|
      actual_output = 1;
 | 
						|
      actual_magnitude = (max_high - past_close) / _Point;
 | 
						|
     }
 | 
						|
   else
 | 
						|
      if((past_close - min_low) / _Point >= InpSuccessPipsThreshold)
 | 
						|
        {
 | 
						|
         actual_output = 0;
 | 
						|
         actual_magnitude = (past_close - min_low) / _Point;
 | 
						|
        }
 | 
						|
 | 
						|
// Calculate inputs for the models
 | 
						|
   double pivot_high = iHigh(Symbol(), InpPivotTimeframe, 1);
 | 
						|
   double pivot_low = iLow(Symbol(), InpPivotTimeframe, 1);
 | 
						|
   double pivot_close = iClose(Symbol(), InpPivotTimeframe, 1);
 | 
						|
   double pp = (pivot_high + pivot_low + pivot_close) / 3;
 | 
						|
   double s1 = (2 * pp) - pivot_high;
 | 
						|
   double r1 = (2 * pp) - pivot_low;
 | 
						|
   double current_price = (SymbolInfoDouble(Symbol(), SYMBOL_BID) + SymbolInfoDouble(Symbol(), SYMBOL_ASK)) / 2;
 | 
						|
   double dist_pp = MathAbs(current_price - pp);
 | 
						|
   double dist_s1 = MathAbs(current_price - s1);
 | 
						|
   double dist_r1 = MathAbs(current_price - r1);
 | 
						|
   double pivot_distance = MathMin(dist_pp, MathMin(dist_s1, dist_r1)) / _Point;
 | 
						|
 | 
						|
   double current_volume = iVolume(Symbol(), Period(), 0);
 | 
						|
   long volume_values[];
 | 
						|
   double volume_avg = 0.0;
 | 
						|
   if(CopyTickVolume(Symbol(), Period(), 1, InpVolumePeriod, volume_values) > 0)
 | 
						|
     {
 | 
						|
      for(int i = 0; i < ArraySize(volume_values); i++)
 | 
						|
        {
 | 
						|
         volume_avg += volume_values[i];
 | 
						|
        }
 | 
						|
      volume_avg /= ArraySize(volume_values);
 | 
						|
     }
 | 
						|
   double volume_input = (volume_avg > 0) ? current_volume / volume_avg : 0.0;
 | 
						|
 | 
						|
// Call models to get predictions with live data
 | 
						|
   double trend_probability = model.PredictAndLearn(
 | 
						|
                                 actual_output,
 | 
						|
                                 _Symbol, _Period, InpRsiPeriod, InpBollingerPeriod, InpBollingerDeviation, InpAtrPeriod, InpEnableEmaFilter, InpEmaFilterTimeframe, InpEmaFastPeriod, InpEmaSlowPeriod, pivot_distance, volume_input, adx_value
 | 
						|
                              );
 | 
						|
 | 
						|
   double predicted_tp_pips = tp_model.PredictAndLearn(
 | 
						|
                                 actual_magnitude,
 | 
						|
                                 _Symbol, _Period, InpRsiPeriod, InpBollingerPeriod, InpBollingerDeviation, InpAtrPeriod, InpEnableEmaFilter, InpEmaFilterTimeframe, InpEmaFastPeriod, InpEmaSlowPeriod, pivot_distance, volume_input, adx_value
 | 
						|
                              );
 | 
						|
 | 
						|
// --- Logic for lot size and TP/SL ---
 | 
						|
 | 
						|
// Dynamic Lot Size Calculation
 | 
						|
   double balance_factor = 1.0;
 | 
						|
   if(InpDynamicLotMultiplier)
 | 
						|
     {
 | 
						|
      balance_factor = current_balance / InpBalanceFactor;
 | 
						|
     }
 | 
						|
   current_lot_size = MathMax(InpLotSize, NormalizeDouble(InpLotSize * balance_factor, 2));
 | 
						|
 | 
						|
// Recovery Mode Check
 | 
						|
   if(InpEnableDrawdownRecovery && server_time.hour >= InpRecoveryStartHour && server_time.hour < InpRecoveryEndHour && current_equity < current_balance)
 | 
						|
     {
 | 
						|
      is_in_recovery_mode = true;
 | 
						|
 | 
						|
      double recovery_lot = InpRecoveryFixedLot;
 | 
						|
      if(InpDynamicLotMultiplier)
 | 
						|
        {
 | 
						|
         double recovery_balance_factor = current_balance / InpBalanceFactor;
 | 
						|
         recovery_lot = MathMax(InpRecoveryFixedLot, NormalizeDouble(InpRecoveryFixedLot * recovery_balance_factor, 2));
 | 
						|
        }
 | 
						|
      current_lot_size = MathMin(recovery_lot, InpMaxLotSize);
 | 
						|
      current_tp_pips = InpRecoveryTakeProfit;
 | 
						|
 | 
						|
      Print("Drawdown detected. Entering recovery mode with fixed lot: ", DoubleToString(current_lot_size, 2), " and fixed TP: ", DoubleToString(current_tp_pips, 2), " pips.");
 | 
						|
     }
 | 
						|
   else
 | 
						|
     {
 | 
						|
      is_in_recovery_mode = false;
 | 
						|
 | 
						|
      // Safety check for predicted TP
 | 
						|
      if(predicted_tp_pips > InpMaxPredictedPips || predicted_tp_pips < 0)
 | 
						|
        {
 | 
						|
         current_tp_pips = InpMinTakeProfitPips;
 | 
						|
         Print("Predicted TP is invalid (", DoubleToString(predicted_tp_pips, 2), "). Using fixed minimum TP: ", DoubleToString(current_tp_pips, 2), " pips.");
 | 
						|
        }
 | 
						|
      else
 | 
						|
        {
 | 
						|
         current_tp_pips = MathMax(InpMinTakeProfitPips, predicted_tp_pips);
 | 
						|
         Print("Normal trading mode. Predicted TP: ", DoubleToString(predicted_tp_pips, 2), " pips. Final TP: ", DoubleToString(current_tp_pips, 2), " pips.");
 | 
						|
        }
 | 
						|
     }
 | 
						|
 | 
						|
// --- Security Checks Before Opening Position ---
 | 
						|
   double free_margin = AccountInfoDouble(ACCOUNT_MARGIN_FREE);
 | 
						|
   double margin_required = SymbolInfoDouble(_Symbol, SYMBOL_MARGIN_INITIAL) * current_lot_size;
 | 
						|
 | 
						|
   if(free_margin < margin_required)
 | 
						|
     {
 | 
						|
      Print("Not enough free margin for the requested operation. Required: ",
 | 
						|
            DoubleToString(margin_required, 2), ", Available: ", DoubleToString(free_margin, 2));
 | 
						|
      return;
 | 
						|
     }
 | 
						|
 | 
						|
   int buy_positions_count = 0;
 | 
						|
   int sell_positions_count = 0;
 | 
						|
 | 
						|
   for(int i = PositionsTotal() - 1; i >= 0; i--)
 | 
						|
     {
 | 
						|
      ulong position_ticket = PositionGetTicket(i);
 | 
						|
      if(PositionSelectByTicket(position_ticket))
 | 
						|
        {
 | 
						|
         if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
 | 
						|
           {
 | 
						|
            buy_positions_count++;
 | 
						|
           }
 | 
						|
         else
 | 
						|
            if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
 | 
						|
              {
 | 
						|
               sell_positions_count++;
 | 
						|
              }
 | 
						|
        }
 | 
						|
     }
 | 
						|
 | 
						|
   double current_atr_filter = iATR(Symbol(), Period(), InpAtrPeriod);
 | 
						|
 | 
						|
   if(current_atr_filter <= InpMinAtrFilter * _Point)
 | 
						|
     {
 | 
						|
      Print("ATR is too low to trade.");
 | 
						|
      return;
 | 
						|
     }
 | 
						|
 | 
						|
// --- Remove TP on drawdown ---
 | 
						|
   if(InpRemoveTPOnDrawdown)
 | 
						|
     {
 | 
						|
      if(current_equity < current_balance * 0.98)  // Drawdown > 2%
 | 
						|
        {
 | 
						|
         for(int i = PositionsTotal() - 1; i >= 0; i--)
 | 
						|
           {
 | 
						|
            ulong position_ticket = PositionGetTicket(i);
 | 
						|
            if(PositionSelectByTicket(position_ticket))
 | 
						|
              {
 | 
						|
               if(PositionGetDouble(POSITION_TP) > 0)
 | 
						|
                 {
 | 
						|
                  m_trade.PositionModify(position_ticket, PositionGetDouble(POSITION_SL), 0);
 | 
						|
                  Print("Removed TP from position ", position_ticket, " due to drawdown > 2%.");
 | 
						|
                 }
 | 
						|
              }
 | 
						|
           }
 | 
						|
        }
 | 
						|
     }
 | 
						|
 | 
						|
   Print("trend_probability ", trend_probability);
 | 
						|
 | 
						|
// --- Final Order Execution Logic ---
 | 
						|
 | 
						|
   if(trend_probability > InpMinProbabilityBuy && buy_positions_count < InpMaxBuyPositions)
 | 
						|
     {
 | 
						|
      double tp_buy = SymbolInfoDouble(_Symbol, SYMBOL_ASK) + (current_tp_pips * _Point);
 | 
						|
      double sl_buy = 0.0;
 | 
						|
      if(InpSLMultiplier > 0.0)
 | 
						|
        {
 | 
						|
         sl_buy = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - (current_atr_filter * InpSLMultiplier) * _Point;
 | 
						|
        }
 | 
						|
 | 
						|
      sl_buy = NormalizeDouble(sl_buy, _Digits);
 | 
						|
      tp_buy = NormalizeDouble(tp_buy, _Digits);
 | 
						|
 | 
						|
      m_trade.Buy(current_lot_size, _Symbol, SymbolInfoDouble(_Symbol, SYMBOL_ASK), sl_buy, tp_buy, "BUY Signal from Logistic Regression");
 | 
						|
     }
 | 
						|
   else
 | 
						|
      if((trend_probability) < (InpMinProbabilitySell) && sell_positions_count < InpMaxSellPositions)
 | 
						|
        {
 | 
						|
         double tp_sell = SymbolInfoDouble(_Symbol, SYMBOL_BID) - (current_tp_pips * _Point);
 | 
						|
         double sl_sell = 0.0;
 | 
						|
         if(InpSLMultiplier > 0.0)
 | 
						|
           {
 | 
						|
            sl_sell = SymbolInfoDouble(_Symbol, SYMBOL_BID) + (current_atr_filter * InpSLMultiplier) * _Point;
 | 
						|
           }
 | 
						|
 | 
						|
         sl_sell = NormalizeDouble(sl_sell, _Digits);
 | 
						|
         tp_sell = NormalizeDouble(tp_sell, _Digits);
 | 
						|
 | 
						|
         m_trade.Sell(current_lot_size, _Symbol, SymbolInfoDouble(_Symbol, SYMBOL_BID), sl_sell, tp_sell, "SELL Signal from Logistic Regression");
 | 
						|
        }
 | 
						|
 | 
						|
   if(InpCloseAfterDays > 0)
 | 
						|
     {
 | 
						|
      long max_duration_seconds = InpCloseAfterDays * 24 * 60 * 60;
 | 
						|
 | 
						|
      for(int i = PositionsTotal() - 1; i >= 0; i--)
 | 
						|
        {
 | 
						|
         ulong position_ticket = PositionGetTicket(i);
 | 
						|
         if(PositionSelectByTicket(position_ticket))
 | 
						|
           {
 | 
						|
            long open_time_seconds = PositionGetInteger(POSITION_TIME_MSC) / 1000;
 | 
						|
            long duration_seconds = TimeCurrent() - open_time_seconds;
 | 
						|
 | 
						|
            if(duration_seconds >= max_duration_seconds)
 | 
						|
              {
 | 
						|
               m_trade.PositionClose(position_ticket);
 | 
						|
               Print("Closing position ", position_ticket, " due to time limit exceeded.");
 | 
						|
              }
 | 
						|
           }
 | 
						|
        }
 | 
						|
     }
 | 
						|
  }
 | 
						|
//+------------------------------------------------------------------+
 |