//+------------------------------------------------------------------+
//| 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()
{
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++;
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);

    // Verificar se já existem posições abertas
    bool hasOpenPosition = false;
    for(int i = 0; i < PositionsTotal(); i++)
    {
        ulong posTicket = PositionGetTicket(i);
        if(PositionSelectByTicket(posTicket) && PositionGetString(POSITION_SYMBOL) == _Symbol)
        {
            hasOpenPosition = true;
            break;
        }
    }

    // Sinal de VENDA
    if(!hasOpenPosition && 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
    else if(!hasOpenPosition && 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);
}

//+------------------------------------------------------------------+

adicone um stoloss de 65000