//+------------------------------------------------------------------+
//| AI Ichimoku Scalper.mq5 |
//| Alfr5d |
//| https://www.49design.co.za |
//+------------------------------------------------------------------+

#property copyright "Copyright 2023, Alfred Mandala."
#property description "www.billionairebulls.co.za\n"
#property version "1.5"
#property description "Ichimoku Scalping EA, TIMEFRAME = M5 \nLOW RISK SETTINGS"

#include <Trade/Trade.mqh>

// ---- INPUTS ----
input group "--- Trading Inputs ---";
input double Lots = 0.01; // Lot Size
input int TpPoints = 50; // Take Profit in points [m5-50p, h1-200p]
input ENUM_TIMEFRAMES IchimokuTimeFrame = PERIOD_CURRENT; // Timeframe (will use current timeframe)

// ---- Ichimoku Inputs ----
input int TenkanPeriod = 9; // Tenkan-sen Period
input int KijunPeriod = 26; // Kijun-sen Period
input int SenkouSpanBPeriod = 52; // Senkou Span B Period
input int Displacement = 26; // Displacement

// ---- Stochastic Inputs ----
input int StochasticKPeriod = 14; // %K period
input int StochasticDPeriod = 3; // %D period
input int StochasticSlowing = 3; // Slowing for the Stochastic

// ---- Parabolic SAR Inputs ----
input double SARStep = 0.02; // Parabolic SAR Step
input double SARMaximum = 0.2; // Parabolic SAR Maximum

// ---- GLOBAL VARIABLES ----
int handleIchimoku;
int handleStochastic;
int handleSAR;
double Tenkan[], Kijun[], SenkouSpanA[], SenkouSpanB[], Chikou[];
double StochasticK[], StochasticD[];
double SAR[];

CTrade trade;

int barsTotal;

// ---- EXPERT INIT ----

int OnInit()
{
// Usando o timeframe atual
handleIchimoku = iIchimoku(_Symbol, Period(), TenkanPeriod, KijunPeriod, SenkouSpanBPeriod);
handleStochastic = iStochastic(_Symbol, Period(), StochasticKPeriod, StochasticDPeriod, StochasticSlowing, MODE_SMA, STO_LOWHIGH);
handleSAR = iSAR(_Symbol, Period(), SARStep, SARMaximum);

return(INIT_SUCCEEDED);
}

// ---- EXPERT DEINIT ----

void OnDeinit(const int reason)
{
IndicatorRelease(handleIchimoku);
IndicatorRelease(handleStochastic);
IndicatorRelease(handleSAR);
}

// ---- ON TICK FUNCTION ----

void OnTick()
{
int bars = iBars(_Symbol, Period());
if(barsTotal != bars)
{
barsTotal = bars;


  double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
  double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

  // Copiar os dados do Ichimoku
  CopyBuffer(handleIchimoku, 0, 0, 1, Tenkan); // Tenkan-sen
  CopyBuffer(handleIchimoku, 1, 0, 1, Kijun);  // Kijun-sen
  CopyBuffer(handleIchimoku, 2, 0, 1, SenkouSpanA); // Senkou Span A
  CopyBuffer(handleIchimoku, 3, 0, 1, SenkouSpanB); // Senkou Span B
  CopyBuffer(handleIchimoku, 4, 0, 1, Chikou); // Chikou Span

  // Copiar os dados do Estocástico
  CopyBuffer(handleStochastic, 0, 0, 1, StochasticK); // %K
  CopyBuffer(handleStochastic, 1, 0, 1, StochasticD); // %D

  // Copiar os dados do Parabolic SAR
  CopyBuffer(handleSAR, 0, 0, 1, SAR);

  // Sinal de VENDA com base no Ichimoku, Stochastic e Parabolic SAR
  if(Tenkan[0] < Kijun[0] && bid < SenkouSpanA[0] && StochasticK[0] > StochasticD[0] && StochasticK[0] > 80 && bid > SAR[0])
  {
     Print(__FUNCTION__, " > SELL Signal...");
     trade.Sell(Lots);
  }
  // Sinal de COMPRA com base no Ichimoku, Stochastic e Parabolic SAR
  else if(Tenkan[0] > Kijun[0] && bid > SenkouSpanA[0] && StochasticK[0] < StochasticD[0] && StochasticK[0] < 20 && bid < SAR[0])
  {
     Print(__FUNCTION__, " > BUY Signal...");
     trade.Buy(Lots);
  }
}

// Loop para verificar as posições abertas e o Take Profit
int pointsBuy = 0;
int pointsSell = 0;
for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong posTicket = PositionGetTicket(i);
if(PositionSelectByTicket(posTicket))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);
double posOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);


     double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
     double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
     if(posType == POSITION_TYPE_BUY)
        pointsBuy += (int)((bid - posOpenPrice) / _Point);
     else if(posType == POSITION_TYPE_SELL)
        pointsSell += (int)((posOpenPrice - ask) / _Point);
  }
}

for(int i = PositionsTotal() - 1; i >= 0; i--)
{
ulong posTicket = PositionGetTicket(i);
if(PositionSelectByTicket(posTicket))
{
ENUM_POSITION_TYPE posType = (ENUM_POSITION_TYPE) PositionGetInteger(POSITION_TYPE);


     if(pointsBuy > TpPoints)
     {
        // Fechar posições de compra
        if(posType == POSITION_TYPE_BUY)
           trade.PositionClose(posTicket);
     }
     if(pointsSell > TpPoints)
     {
        // Fechar posições de venda
        if(posType == POSITION_TYPE_SELL)
           trade.PositionClose(posTicket);
     }
  }
}

Comment("\nTenkan-sen: ", DoubleToString(Tenkan[0], 5),
"\nKijun-sen: ", DoubleToString(Kijun[0], 5),
"\nSenkou Span A: ", DoubleToString(SenkouSpanA[0], 5),
"\nSenkou Span B: ", DoubleToString(SenkouSpanB[0], 5),
"\nChikou: ", DoubleToString(Chikou[0], 5),
"\nStochastic %K: ", DoubleToString(StochasticK[0], 5),
"\nStochastic %D: ", DoubleToString(StochasticD[0], 5),
"\nParabolic SAR: ", DoubleToString(SAR[0], 5),
"\nPoints Buy: ", pointsBuy,
"\nPoints Sell: ", pointsSell);
}

o robo precisa abrir apenas uma ordem por vez

me entregue o codigo completo