Martingale não volta para valor inicial

 

bom dia pessoal quando o martingale entra em ação o valor do lote não reinicia quando ganho a operação, parece que não esta validando a função martingale = false, alguém pode me ajudar se tem alguma outra forma de fazer, pois estou iniciando na programação

#include <Trade\Trade.mqh>

// Declaração do objeto de negociação
CTrade trade;

// Entradas do usuário
input double LotSize = 0.01;          // Volume da ordem
input int slippage = 3;               // Derrapagem máxima permitida
input int stopLoss = 50;              // Sem stop loss
input int takeProfit = 100;           // Sem take profit
input double martingaleFactor = 2;    // Fator de Martingale
input double martingaleMax = 3;       // Limite máximo de Martingale

// Variáveis globais
double initialLotSize;                // Tamanho do lote inicial
double LoteAtual = LotSize;           // Lote atual
bool martingaleActive = false;        // Flag para indicar se o martingale está ativo

// Função OnInit: Executada uma vez no início da execução do programa
int OnInit()
{
    // Inicialização do tamanho do lote
    LoteAtual = LotSize;
    
    // Verifica se o stop loss é válido
    if(stopLoss < 0)
    {
        Print("O Stoploss não pode ser Menor que Zero");
        return INIT_FAILED;
    }

    // Verifica se o take profit é válido
    if(takeProfit < 0)
    {
        Print("O Takeprofit não pode ser Menor que Zero");
        return INIT_FAILED;
    }

    return INIT_SUCCEEDED;
}

// Função OnDeinit: Executada quando o programa é desativado
void OnDeinit(const int reason)
{
    // Você pode adicionar procedimentos de limpeza aqui, se necessário
}

// Função OnTick: Executada a cada tick (mudança de preço)
void OnTick()
{
    // Verifica se é uma nova barra
    if (isNewBar())
    {
        // Obtém os preços de abertura e fechamento
        double openPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
        double closePrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);

        // Obtém os preços de abertura e fechamento da barra anterior
        double openPriceAnterior = iOpen(_Symbol, Period(), 1);
        double closePriceAnterior = iClose(_Symbol, Period(), 1);

        // Variáveis para determinar os sinais de compra e venda
        bool sinalVenda = false;
        bool sinalCompra = false;

        // Verifica se o preço de fechamento é menor que o preço de abertura da barra anterior
        if(closePriceAnterior < openPriceAnterior)
        {
            sinalVenda = true;
            Print("Sinal de Venda: Verdadeiro");
        }
        // Verifica se o preço de fechamento é maior que o preço de abertura da barra anterior
        else if(closePriceAnterior > openPriceAnterior)
        {
            sinalCompra = true;
            Print("Sinal de Compra: Verdadeiro");
        }

        // Realiza operações com base nos sinais de compra e venda
        if (sinalVenda)
        {
            // Calcula os níveis de stop loss e take profit
            double sl = openPrice + stopLoss * _Point;
            double tp = openPrice - takeProfit * _Point;

            // Executa a venda no mercado
            if (!martingaleActive)
                trade.Sell(LoteAtual, _Symbol, closePrice, sl, tp, "Venda a Mercado");
            else
            {
                // Ativa o Martingale se necessário
                LoteAtual *= martingaleFactor;
                if (LoteAtual > martingaleMax * LotSize)
                    LoteAtual = martingaleMax * LotSize;
                trade.Sell(LoteAtual, _Symbol, closePrice, sl, tp, "Venda a Mercado");
                martingaleActive = false;
            }
            Print("Executando Venda a mercado");
        }
        else if (sinalCompra)
        {
            // Calcula os níveis de stop loss e take profit
            double sl = openPrice - stopLoss * _Point;
            double tp = openPrice + takeProfit * _Point;

            // Executa a compra no mercado
            if (!martingaleActive)
                trade.Buy(LoteAtual, _Symbol, closePrice, sl, tp, "Compra a Mercado");
            else
            {
                // Ativa o Martingale se necessário
                LoteAtual *= martingaleFactor;
                if (LoteAtual > martingaleMax * LotSize)
                    LoteAtual = martingaleMax * LotSize;
                trade.Buy(LoteAtual, _Symbol, closePrice, sl, tp, "Compra a Mercado");
                martingaleActive = false;
            }
            Print("Executando Compra a mercado");
        }
    }
}

// Função isNewBar: Verifica se é uma nova barra
bool isNewBar()
{
    static datetime last_time=0;

    datetime lastbar_time=(datetime)SeriesInfoInteger(Symbol(), Period(), SERIES_LASTBAR_DATE);

    if (last_time == 0)
    {
        last_time = lastbar_time;
        return(false);
    }

    if (last_time != lastbar_time)
    {
        last_time = lastbar_time;
        return(true);
    }

    return (false);
}

// Função OnTrade: Executada quando ocorre uma negociação
void OnTrade()
{
    if (PositionsTotal() > 0)
    {
        for (int i = 0; i < PositionsTotal(); i++)
        {
            ulong ticket = PositionGetTicket(i);
            int type = PositionGetInteger(POSITION_TYPE);
            double profit = PositionGetDouble(POSITION_PROFIT);

            // Verifica se a posição é de compra
            if (type == POSITION_TYPE_BUY)
            {
                double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                double takeProfitLevel = openPrice + takeProfit * _Point;

                // Verifica se a posição atingiu o nível de stop loss
                if (profit <= -stopLoss * _Point)
                {
                    martingaleActive = true;
                    Print("Posição de Compra atingiu Stop Loss. Ativando Martingale.");
                }
                // Verifica se a posição atingiu o nível de take profit
                else if (profit >= takeProfitLevel)
                {
                    martingaleActive = false;
                    LoteAtual = LotSize; // Reiniciar o tamanho do lote para o valor inicial
                    Print("Posição de Compra atingiu Take Profit. Redefinindo o tamanho do lote.");
                    trade.PositionClose(ticket); // Fechar a posição
                }
            }
            // Verifica se a posição é de venda
            else if (type == POSITION_TYPE_SELL)
            {
                double openPrice = PositionGetDouble(POSITION_PRICE_OPEN);
                double takeProfitLevel = openPrice - takeProfit * _Point;

                // Verifica se a posição atingiu o nível de stop loss
                if (profit <= -stopLoss * _Point)
                {
                    martingaleActive = true;
                    Print("Posição de Venda atingiu Stop Loss. Ativando Martingale.");
                }
                // Verifica se a posição atingiu o nível de take profit
                else if (profit >= takeProfitLevel)
                {
                    martingaleActive = false;
                    LoteAtual = LotSize; // Reiniciar o tamanho do lote para o valor inicial
                    Print("Posição de Venda atingiu Take Profit. Redefinindo o tamanho do lote.");
                    trade.PositionClose(ticket); // Fechar a posição
                }
            }

            // Verifica o motivo do fechamento da posição
            int reason = PositionGetInteger(POSITION_REASON);
            if (reason == 4)
            {
                Print("Posição fechada devido a Take Profit");
            }
            else if (reason == POSITION_SL)
            {
                Print("Posição fechada devido a Stop Loss");
            }
        }
    }
}
 
O seu tópico foi movido para a secção: Expert Advisors e Negociação Automatizada.
Por favor ter em conta a secção adequada quando criar tópicos — https://www.mql5.com/pt/forum/421109/page6#comment_49385139 
 
Paulo Henrique Da Silva Soares:

bom dia pessoal quando o martingale entra em ação o valor do lote não reinicia quando ganho a operação, parece que não esta validando a função martingale = false, alguém pode me ajudar se tem alguma outra forma de fazer, pois estou iniciando na programação

Voce tem certeza que seu stopLevel e takeProfitLevel são valores monetarios? Olhando rapidamente aqui eu acho confuso isso. Se voce quer 100 dolares de ganho e 50 dolares de perda porque simplesmente não compara isso contra a variavel profit?

 
Ricardo Rodrigues Lucca #:

Voce tem certeza que seu stopLevel e takeProfitLevel são valores monetarios? Olhando rapidamente aqui eu acho confuso isso. Se voce quer 100 dolares de ganho e 50 dolares de perda porque simplesmente não compara isso contra a variavel profit?

Olá Ricardo, talvez eu tenha errado no código, pois é meu primeiro EA, mas o valor 100 e 50 são pontos, não sei como fazer validar o Takeprofit para reiniciar o valor do Lote.

 
Paulo Henrique Da Silva Soares #:

Olá Ricardo, talvez eu tenha errado no código, pois é meu primeiro EA, mas o valor 100 e 50 são pontos, não sei como fazer validar o Takeprofit para reiniciar o valor do Lote.

Certo, o uso da _Point eu não conheço bem deixar pra outra pessoa comentar. Se tu esta informando em pontos porque não simplesmente soma nos levels sem a multiplicação? Além disso pra comparar precisa trocar uso do POSITION_PROFIT (valor monetario de prejuizo/ganho) por POSITION_PRICE_CURRENT (preço do ativo). Além disso, seria interessante chamar uma função de normalização do preço se fosse informar o preço no fechamento, o uso do PositionClose() torna isso desnecessario e contorna esse problema que poderia existir.

Fora isso, eu não tinha dado atenção a parte do POSITION_REASON no final. Vejá que voce esta com uma posição aberta selecionada, ali não lhe informa o motivo de encerramento porque voce não tem garantia que ele já ocorreu. Se ele ocorreu, a posição não existe mais e deve ser selecionada do historico de deals usando as funcoes History* .

 
Paulo Henrique Da Silva Soaresbom dia pessoal quando o martingale entra em ação o valor do lote não reinicia quando ganho a operação, parece que não esta validando a função martingale = false, alguém pode me ajudar se tem alguma outra forma de fazer, pois estou iniciando na programação

Bom dia, Paulo Henrique!! Caso você resolva alterar o seu código e utilizar o histórico de operações encerradas para calcular o lote (como o Ricardo mencionou no comentário anterior), segue o exemplo de uma função que você poderá utilizar como base para construir a sua, de acordo com a sua estratégia: Grade e martingale: o que são e como usá-los - Função CalcLot()

 
Obrigado Vinicius vou tentar alterar sim, agradeço pela ajudar forte abraço a todos.
Razão: