//+------------------------------------------------------------------+
//|                                                      Ai+I EA.mq5 |
//+------------------------------------------------------------------+
#property strict
#property version   "1.00"
#property copyright "https://t.me/tripeller"
#property link      "https://t.me/tripeller"
#property description "Ai+I EA v1.00 for MT5 - Machine Learning / AI Based Free Advisor."
#property description "Utilize with EURUSD on the M30 timeframe, suitable for standard"
#property description "account with a minimum balance of $1000. The EA excels with"
#property description "spreads of 0 to 1, coupled with low commissions. Avoid running"
#property description "on a low-capacity VPS server as it is highly resource-intensive."
#property description " "
#property description "Crypto donations appreciated if you find this advisor beneficial."
#property description " "
#property description "BTC - 35FVUdiTPDyNHRnLJqaCK7g43hpmQyRBHW"
#property description "ETH - 0x9E72A4bC29beDdCB8BDCf90D825b1E8E8cEC51cC"

input double FixedLots = 0.01;             // Fixed Lots
input double MaxLots = 2.5;                // Maximum Lots
input int MaxSpread = 2;                   // Maximum Spread (in points)
input int TakeProfit = 50;                 // Take Profit (in points)
input int StopLoss = 5;                    // Stop Loss (in points)
double ProfitPercent = 0.0;                // Profit Percent to Close Orders
double TrailingStop = 0.0;                 // Trailing Stop (in points)
input int Slippage = 3;                    // Slippage
input int MaFastPeriod = 5;                // Period for Fast Moving Average
input int MaSlowPeriod = 10;               // Period for Slow Moving Average
input int TradingStartTime = 11;           // Trading Start Hour
input int TradingEndTime = 19;             // Trading End Hour
input int MagicNumber = 10001;
input string OrderComments = "Ai+I v1.0 ";  // Order Comments
input string Notes = "This is a free advisor, improve and reshare ...";
input string BTCDonations = "35FVUdiTPDyNHRnLJqaCK7g43hpmQyRBHW"; // BTC donations
input string ETHDonations = "0x9E72A4bC29beDdCB8BDCf90D825b1E8E8cEC51cC"; // ETH donations

// Machine learning model parameters
int LookbackPeriod = 50;                   // Lookback period for historical data
int TrainRatio = 80;                       // Percentage of data used for training

double TotalOpenLots = 0;                  // Keep track of total open lot size

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   // Initialization code here
   return INIT_SUCCEEDED;
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   // De-initialization code here
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   // Check trading hours
   if(!IsTradingTime())
      return;

   // Check spread
   if(SpreadExceedsMax())
      return;

   // Get historical market data
   double HistoricalData[];
   GetHistoricalData(HistoricalData);

   // Train machine learning model
   double TrainData[], TestData[];
   SplitData(HistoricalData, TrainData, TestData);

   // Predict market trend
   int PredictedTrend = PredictTrend(HistoricalData);

   // Execute trade based on predicted trend
   ExecuteTrade(PredictedTrend);

   // Close orders if equity profit percent exceeds threshold
   if(ProfitPercent > 0)
     {
      double Equity = AccountInfoDouble(ACCOUNT_EQUITY);
      double Balance = AccountInfoDouble(ACCOUNT_BALANCE);
      double ProfitPercentTotal = (Equity - Balance) / Balance * 100;
      if(ProfitPercentTotal >= ProfitPercent)
        {
         CloseAllOrders();
        }
     }
  }

//+------------------------------------------------------------------+
//| Retrieve historical data                                         |
//+------------------------------------------------------------------+
void GetHistoricalData(double &Data[])
  {
   ArraySetAsSeries(Data, true); // Set array to be accessed in the reverse order
   int Limit = LookbackPeriod + 100; // Number of bars to retrieve

   ArrayResize(Data, Limit);
   int CopiedBars = CopyClose(_Symbol, _Period, 0, Limit, Data);
   if(CopiedBars <= 0)
     {
      Print("Failed to retrieve historical data!");
      return;
     }
   ArraySetAsSeries(Data, false); // Restore array to the forward order
  }

//+------------------------------------------------------------------+
//| Split the data into training and test sets                       |
//+------------------------------------------------------------------+
void SplitData(double &Data[], double &TrainData[], double &TestData[])
  {
   int TrainSize = ArraySize(Data) * TrainRatio / 100;
   ArrayResize(TrainData, TrainSize);
   ArrayResize(TestData, ArraySize(Data) - TrainSize);
   ArrayCopy(TrainData, Data, 0, 0, TrainSize);
   ArrayCopy(TestData, Data, 0, TrainSize, ArraySize(Data) - TrainSize);
  }

//+------------------------------------------------------------------+
//| Predict trend using moving averages                              |
//+------------------------------------------------------------------+
int PredictTrend(double &HistoricalData[])
  {
   double MaFast = iMA(NULL, 0, MaFastPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
   double MaSlow = iMA(NULL, 0, MaSlowPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);

   if(MaFast > MaSlow)
      return 1; // Buy signal
   else if(MaFast < MaSlow)
      return -1; // Sell signal
   else
      return 0; // No signal
  }

//+------------------------------------------------------------------+
//| Execute trade based on predicted trend                           |
//+------------------------------------------------------------------+
void ExecuteTrade(int PredictedTrend)
  {
   double CurrentOpenLots = 0.0;
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if(PositionGetSymbol(i) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
         CurrentOpenLots += PositionGetDouble(POSITION_VOLUME);
     }

   if(CurrentOpenLots + FixedLots > MaxLots)
     {
      Print("Max open lot size reached. Cannot open new trade.");
      return;
     }

   MqlTradeRequest request;
   MqlTradeResult result;
   ZeroMemory(request);
   ZeroMemory(result);

   if(PredictedTrend == 1)
     {
      // Place buy order
      request.action = TRADE_ACTION_DEAL;
      request.symbol = _Symbol;
      request.volume = FixedLots;
      request.type = ORDER_TYPE_BUY;
      request.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      request.sl = request.price - StopLoss * _Point;
      request.tp = request.price + TakeProfit * _Point;
      request.deviation = Slippage;
      request.magic = MagicNumber;
      request.comment = OrderComments;
      
      if(!OrderSend(request, result) || result.retcode != TRADE_RETCODE_DONE)
        {
         Print("Trade request failed with code: ", result.retcode);
        }
     }
   else if(PredictedTrend == -1)
     {
      // Place sell order
      request.action = TRADE_ACTION_DEAL;
      request.symbol = _Symbol;
      request.volume = FixedLots;
      request.type = ORDER_TYPE_SELL;
      request.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      request.sl = request.price + StopLoss * _Point;
      request.tp = request.price - TakeProfit * _Point;
      request.deviation = Slippage;
      request.magic = MagicNumber;
      request.comment = OrderComments;

      if(!OrderSend(request, result) || result.retcode != TRADE_RETCODE_DONE)
        {
         Print("Trade request failed with code: ", result.retcode);
        }
     }
  }

//+------------------------------------------------------------------+
//| Close all open orders                                            |
//+------------------------------------------------------------------+
void CloseAllOrders()
  {
   for(int i = PositionsTotal() - 1; i >= 0; i--)
     {
      if(PositionGetString(POSITION_SYMBOL) == _Symbol && PositionGetInteger(POSITION_MAGIC) == MagicNumber)
        {
         double ClosePrice = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? SymbolInfoDouble(_Symbol, SYMBOL_BID) : SymbolInfoDouble(_Symbol, SYMBOL_ASK);
         MqlTradeRequest request;
         MqlTradeResult result;
         ZeroMemory(request);
         ZeroMemory(result);

         request.action = TRADE_ACTION_DEAL;
         request.position = PositionGetInteger(POSITION_IDENTIFIER);
         request.symbol = _Symbol;
         request.volume = PositionGetDouble(POSITION_VOLUME);
         request.type = (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) ? ORDER_TYPE_SELL : ORDER_TYPE_BUY;
         request.price = ClosePrice;

         if(!OrderSend(request, result) || result.retcode != TRADE_RETCODE_DONE)
           {
            Print("Failed to close order! Error:", result.retcode);
           }
        }
     }
  }

//+------------------------------------------------------------------+
//| Check if spread exceeds maximum                                  |
//+------------------------------------------------------------------+
bool SpreadExceedsMax()
  {
   double Spread = SymbolInfoDouble(_Symbol, SYMBOL_SPREAD) / _Point;
   return (Spread >= MaxSpread);
  }

//+------------------------------------------------------------------+
//| Check if current time is within trading hours                    |
//+------------------------------------------------------------------+
bool IsTradingTime()
  {
   int currentHour = TimeHour(TimeCurrent());
   return (currentHour >= TradingStartTime && currentHour <= TradingEndTime);
  }
//+------------------------------------------------------------------+

errors:

'iMA' - wrong parameters count	GEN AI 001.mq5	135	20
'iMA' - wrong parameters count	GEN AI 001.mq5	136	20
'SymbolInfoDouble' - no one of the overloads can be applied to the function call	GEN AI 001.mq5	244	20
'TimeHour' - undeclared identifier	GEN AI 001.mq5	253	22
'TimeCurrent' - some operator expected	GEN AI 001.mq5	253	31