converta esse codigo para MQL4:

#include <Trade\Trade.mqh>

input double lotSize = 0.1;          // Tamanho do lote
input double dailyTarget = 20.0;     // Meta de lucro diário
// Remover o `input` da variável initialBalance
double initialBalance = 0.0;         // Saldo inicial para cálculo de lucro
input bool resetDailyTarget = true;  // Reseta a meta de lucro diariamente

// Variáveis globais para controle de ordens
bool orderOpened = false;
ulong orderTicket = 0;
double profitToday = 0.0;           // Lucro acumulado do dia

// Variáveis para armazenar rompimento anterior
bool lastBreakoutAlta = false;
bool lastBreakoutBaixa = false;
double breakoutHigh = 0.0;
double breakoutLow = 0.0;

// Configurações de trailing stop
input int TslTriggerPoints = 15;  // Pontos de lucro antes do trailing stop ser ativado
input int TslPoints = 10;         // Trailing stop em pips

CTrade trade;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
{
    // Armazena o saldo inicial no início do dia
    initialBalance = AccountInfoDouble(ACCOUNT_BALANCE);
    profitToday = 0.0;

    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // Função de finalização
}

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
{
    // Verifica se a meta de lucro diário foi atingida
    double currentBalance = AccountInfoDouble(ACCOUNT_BALANCE);
    profitToday = currentBalance - initialBalance;

    if (profitToday >= dailyTarget)
    {
        // Fechar todas as posições abertas ao atingir a meta
        for (int i = PositionsTotal() - 1; i >= 0; i--)
        {
            ulong ticket = PositionGetTicket(i);
            if (ticket > 0)
            {
                trade.PositionClose(ticket);
                Print("Meta de lucro diário atingida. Fechando todas as posições. Ticket: ", ticket);
            }
        }

        // Evitar abertura de novas ordens
        return;
    }

    // Variáveis para bandas de Bollinger
    double bollingerUpper[], bollingerLower[], bollingerMiddle[];

    // Configurações das Bandas de Bollinger (período 20, desvio 2)
    int bbPeriod = 20;
    double bbDeviation = 2.0;
    double slippage = 3 * _Point;

    // Obtenção das Bandas de Bollinger
    int bbHandle = iBands(_Symbol, PERIOD_M2, bbPeriod, bbDeviation, 0, PRICE_CLOSE);

    if (bbHandle == INVALID_HANDLE)
    {
        Print("Erro ao obter handle das Bandas de Bollinger: ", GetLastError());
        return;
    }

    // Inicializar os buffers das bandas de Bollinger
    ArraySetAsSeries(bollingerUpper, true);
    ArraySetAsSeries(bollingerMiddle, true);
    ArraySetAsSeries(bollingerLower, true);

    // Preencher os buffers
    if (CopyBuffer(bbHandle, 0, 0, 1, bollingerUpper) <= 0 ||
        CopyBuffer(bbHandle, 1, 0, 1, bollingerMiddle) <= 0 ||
        CopyBuffer(bbHandle, 2, 0, 1, bollingerLower) <= 0)
    {
        Print("Erro ao copiar buffer das Bandas de Bollinger: ", GetLastError());
        return;
    }

    // Preço atual e range da vela
    double priceHigh = iHigh(_Symbol, PERIOD_M2, 0);
    double priceLow = iLow(_Symbol, PERIOD_M2, 0);
    double priceClose = iClose(_Symbol, PERIOD_M2, 0);
    double range = priceHigh - priceLow;

    // Fechar ordens de compra se o preço romper a banda inferior
    if (lastBreakoutBaixa && priceClose < bollingerLower[0])
    {
        for (int i = PositionsTotal() - 1; i >= 0; i--)
        {
            ulong positionTicket = PositionGetTicket(i);
            if (positionTicket > 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
            {
                if (trade.PositionClose(positionTicket))
                {
                    Print("Ordem de compra fechada devido a rompimento de baixa. Ticket: ", positionTicket);
                }
            }
        }
    }

    // Fechar ordens de venda se o preço romper a banda superior
    if (lastBreakoutAlta && priceClose > bollingerUpper[0])
    {
        for (int i = PositionsTotal() - 1; i >= 0; i--)
        {
            ulong positionTicket = PositionGetTicket(i);
            if (positionTicket > 0 && PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
            {
                if (trade.PositionClose(positionTicket))
                {
                    Print("Ordem de venda fechada devido a rompimento de alta. Ticket: ", positionTicket);
                }
            }
        }
    }

    // Atualizar informações de rompimento e confirmação
    if (lastBreakoutAlta && priceClose > breakoutHigh)
    {
        double slBuy = priceClose - 10 * _Point; 
        if (trade.Buy(lotSize, _Symbol, slBuy))
        {
            orderOpened = true;
            orderTicket = trade.ResultOrder();
            Print("Ordem de compra aberta com sucesso após confirmação! Ticket: ", orderTicket);
            lastBreakoutAlta = false; 
        }
        else
        {
            Print("Erro ao abrir ordem de compra: ", trade.ResultRetcode(), " - ", GetLastError());
        }
    }

    if (lastBreakoutBaixa && priceClose < breakoutLow)
    {
        double slSell = priceClose + 10 * _Point; 
        if (trade.Sell(lotSize, _Symbol, slSell))
        {
            orderOpened = true;
            orderTicket = trade.ResultOrder();
            Print("Ordem de venda aberta com sucesso após confirmação! Ticket: ", orderTicket);
            lastBreakoutBaixa = false;
        }
        else
        {
            Print("Erro ao abrir ordem de venda: ", trade.ResultRetcode(), " - ", GetLastError());
        }
    }

    // Verificar rompimento de alta
    if (range >= 30 * _Point && priceClose > bollingerUpper[0])
    {
        lastBreakoutAlta = true;
        breakoutHigh = priceHigh;
        Print("Possível rompimento de alta detectado.");
    }

    // Verificar rompimento de baixa
    if (range >= 30 * _Point && priceClose < bollingerLower[0])
    {
        lastBreakoutBaixa = true;
        breakoutLow = priceLow;
        Print("Possível rompimento de baixa detectado.");
    }

    // Gerenciamento de trailing stop
    TrailStop();
}

//+------------------------------------------------------------------+
//| Gerenciamento de trailing stop                                   |
//+------------------------------------------------------------------+
void TrailStop()
{
    double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
    double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);

    for (int i = PositionsTotal() - 1; i >= 0; i--)
    {
        if (PositionGetTicket(i) > 0 && PositionSelectByTicket(PositionGetTicket(i)))
        {
            ulong ticket = PositionGetTicket(i);
            double currentSL = PositionGetDouble(POSITION_SL);
            double tp = PositionGetDouble(POSITION_TP);

            if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY)
            {
                if (bid - PositionGetDouble(POSITION_PRICE_OPEN) > TslTriggerPoints * _Point)
                {
                    double newSL = bid - TslPoints * _Point;

                    if (newSL > currentSL || currentSL == 0)
                    {
                        trade.PositionModify(ticket, newSL, tp);
                        Print("Trailing Stop atualizado para posição de compra.");
                    }
                }
            }
            else if (PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL)
            {
                if (PositionGetDouble(POSITION_PRICE_OPEN) - ask > TslTriggerPoints * _Point)
                {
                    double newSL = ask + TslPoints * _Point;

                    if (newSL < currentSL || currentSL == 0)
                    {
                        trade.PositionModify(ticket, newSL, tp);
                        Print("Trailing Stop atualizado para posição de venda.");
                    }
                }
            }
        }
    }
}