Limite diário no MT5

 

Pessoal, boa tarde!

Estou tentando implementar no meu código o limite de ganho e perda diário. Alguém poderia dar alguma dica?

Segue parte do código:


//-----------------------

#include  <Trade\Trade.mqh>

CTrade trade;


input double lote = 1.0;
input double stoploss = 200;
input double takeProfit = 200;



input ulong magicNum = 123456;
input ulong desvPts = 50;
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;

double PRC;
double STL;
double TKP;

MqlTick ultimoTick;

bool posAberta;
bool ordPendente;


//-------------------



void OnTick()


{


if( LogicaCompra() && !posAberta && !ordPendente)  
      {
      PRC = NormalizeDouble(ultimoTick.ask, _Digits);
      STL = NormalizeDouble(PRC - stoploss, _Digits);
      TKP = NormalizeDouble(PRC + takeProfit, _Digits);
      if(trade.Buy(lote, _Symbol, PRC, STL, TKP, ""))
     
         {
         Print ("Ordem de compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
       else
         {
         Print ("Ordem de compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
      }
   else if( LogicaVenda() && !posAberta && !ordPendente )   
      {
       PRC = NormalizeDouble(ultimoTick.bid, _Digits); 
       STL = NormalizeDouble(PRC + stoploss, _Digits);
       TKP = NormalizeDouble(PRC - takeProfit, _Digits);
       if(trade.Sell(lote, _Symbol, PRC, STL, TKP, ""))
         {
       ;
         Print ("Ordem de venda - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
       else
         {
         Print ("Ordem de venda - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }    
      }


}


.... e boas operações para todos!

 
fabriciopduarte:

Pessoal, boa tarde!

Estou tentando implementar no meu código o limite de ganho e perda diário. Alguém poderia dar alguma dica?

Segue parte do código:


//-----------------------

#include  <Trade\Trade.mqh>

CTrade trade;


input double lote = 1.0;
input double stoploss = 200;
input double takeProfit = 200;



input ulong magicNum = 123456;
input ulong desvPts = 50;
input ENUM_ORDER_TYPE_FILLING preenchimento = ORDER_FILLING_RETURN;

double PRC;
double STL;
double TKP;

MqlTick ultimoTick;

bool posAberta;
bool ordPendente;


//-------------------



void OnTick()


{


if( LogicaCompra() && !posAberta && !ordPendente)  
      {
      PRC = NormalizeDouble(ultimoTick.ask, _Digits);
      STL = NormalizeDouble(PRC - stoploss, _Digits);
      TKP = NormalizeDouble(PRC + takeProfit, _Digits);
      if(trade.Buy(lote, _Symbol, PRC, STL, TKP, ""))
     
         {
         Print ("Ordem de compra - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
       else
         {
         Print ("Ordem de compra - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
      }
   else if( LogicaVenda() && !posAberta && !ordPendente )   
      {
       PRC = NormalizeDouble(ultimoTick.bid, _Digits); 
       STL = NormalizeDouble(PRC + stoploss, _Digits);
       TKP = NormalizeDouble(PRC - takeProfit, _Digits);
       if(trade.Sell(lote, _Symbol, PRC, STL, TKP, ""))
         {
       ;
         Print ("Ordem de venda - sem falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }
       else
         {
         Print ("Ordem de venda - com falha. ResultRetcode: ", trade.ResultRetcode(), ", RetcodeDescription: ", trade.ResultRetcodeDescription());
         }    
      }


}


.... e boas operações para todos!

No seu topico de stoploss ti mostraram uma função PrintOnLoss() tu poderia adaptar ela para fazer o que voce quer com limites diarios de perda e ganho dado que ela vasculha o historico de ordens fechadas. Mas pelo visto voce não estudou aquele codigo com atenção.

 

Primeiramente gostaria de agradecer pela dica. 

Segui sua orientação, e vi que no "profit" retorna o resultado de gain ou loss.Então pensei em criar a variável profitLOSS para acumular os valores do profit<0, mas o loop retornou o seguinte

CS    0    00:02:22.982        2024.02.22 09:22:40   profitLOSS..............: 5.0
CS    0    00:02:22.983        2024.02.22 09:22:59   profitLOSS..............: 10.0
CS    0    00:02:22.983        2024.02.22 09:23:00   profitLOSS..............: 15.0

...
CS    0    00:02:23.987    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:20   profitLOSS..............: -4120.0
CS    0    00:02:23.987    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:40   profitLOSS..............: -4130.0
CS    0    00:02:23.992    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:59   profitLOSS..............: -4140.0
...
CS    0    00:30:45.136       >>> RESULTADO totalProfit .............:  -16240.0


A determinado intervalo de segundo, foi somando até chegar em -16240.0


Ainda não entendi bem a lógica do que ocorreu.

Ricardo Rodrigues Lucca
Ricardo Rodrigues Lucca
  • 2023.12.24
  • www.mql5.com
Perfil do Trader
 
fabriciopduarte #:

Primeiramente gostaria de agradecer pela dica. 

Segui sua orientação, e vi que no "profit" retorna o resultado de gain ou loss.Então pensei em criar a variável profitLOSS para acumular os valores do profit<0, mas o loop retornou o seguinte

CS    0    00:02:22.982        2024.02.22 09:22:40   profitLOSS..............: 5.0
CS    0    00:02:22.983        2024.02.22 09:22:59   profitLOSS..............: 10.0
CS    0    00:02:22.983        2024.02.22 09:23:00   profitLOSS..............: 15.0

...
CS    0    00:02:23.987    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:20   profitLOSS..............: -4120.0
CS    0    00:02:23.987    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:40   profitLOSS..............: -4130.0
CS    0    00:02:23.992    ROBO_FAB_T2_ADX 001 teste combinado Willians03 financeiro (WINJ24,M2)    2024.02.22 12:10:59   profitLOSS..............: -4140.0
...
CS    0    00:30:45.136       >>> RESULTADO totalProfit .............:  -16240.0


A determinado intervalo de segundo, foi somando até chegar em -16240.0


Ainda não entendi bem a lógica do que ocorreu.

Não entendo o que voce fez simplesmente pela saída, voce teria que postar o código para ajudar melhor. Voce colocar o profit em uma variavel e loss em outra não parece ser problema, seria jeito de escrever o código.
 
Ricardo Rodrigues Lucca #:
Não entendo o que voce fez simplesmente pela saída, voce teria que postar o código para ajudar melhor. Voce colocar o profit em uma variavel e loss em outra não parece ser problema, seria jeito de escrever o código.
void PrintOnLoss(const string& symbol, uint ea_magic)

{

        if(HistorySelect(0,TimeCurrent())==false) return; // seleciona todo o período dentro do histórico de trades

        int deals_total=HistoryDealsTotal(); // obtém o total de trades do período
        
        for(int i = deals_total-1; i >=0; --i) // loop por todo o histórico, desde o trade mais atual, até achar o último trade no símbolo e com o magic number do EA
        {
                ulong ticket = HistoryDealGetTicket(i);
                string tmp_symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);

                if(tmp_symbol==_Symbol)
                {
                        ulong magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);

                        if(magic==magicNum)
                        {
                               
                                double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT); // obtém o lucro do trade de index i
                                int reason=HistoryDealGetInteger(ticket,DEAL_REASON); // obtém a razão de execução do trade de index i
                                double price=HistoryDealGetDouble(ticket,DEAL_PRICE); // obtém o preço de saída

                                if(profit<0)
                                {
                                        Print(">>> Trade encerrado com prejuízo: R$ ", profit, " - preço: ", price);
                                totalProfit = profit + totalProfit;
                                Print(">>> RESULTADO totalProfit .............:  ", totalProfit);
                                }

                                if(reason==DEAL_REASON_SL)
                                {
                                        Print(">>> Trade encerrado com execução no stop loss - preço: ", price);
                                }             
                                return;  
                        }
                }
        }
}
 
fabriciopduarte #:
void PrintOnLoss(const string& symbol, uint ea_magic)

{

        if(HistorySelect(0,TimeCurrent())==false) return; // seleciona todo o período dentro do histórico de trades

        int deals_total=HistoryDealsTotal(); // obtém o total de trades do período
        
        for(int i = deals_total-1; i >=0; --i) // loop por todo o histórico, desde o trade mais atual, até achar o último trade no símbolo e com o magic number do EA
        {
                ulong ticket = HistoryDealGetTicket(i);
                string tmp_symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);

                if(tmp_symbol==_Symbol)
                {
                        ulong magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);

                        if(magic==magicNum)
                        {
                               
                                double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT); // obtém o lucro do trade de index i
                                int reason=HistoryDealGetInteger(ticket,DEAL_REASON); // obtém a razão de execução do trade de index i
                                double price=HistoryDealGetDouble(ticket,DEAL_PRICE); // obtém o preço de saída

                                if(profit<0)
                                {
                                        Print(">>> Trade encerrado com prejuízo: R$ ", profit, " - preço: ", price);
                                totalProfit = profit + totalProfit;
                                Print(">>> RESULTADO totalProfit .............:  ", totalProfit);
                                }

                                if(reason==DEAL_REASON_SL)
                                {
                                        Print(">>> Trade encerrado com execução no stop loss - preço: ", price);
                                }             
                                return;  
                        }
                }
        }
}

Algum moderador vai pegar no seu pé porque precisaria o código ser postado dentro das tags de codigo (fica do lado esquerdo de um botão tipo umas velas e 3 a esquerda do negrito). Mas enfim, eu vi ai que tu tá somando totalProfit, mas voce nunca volta esse valor para zero. Antes de fazer a passagem para contar os valores negativados voce deveria colocar a variavel no estado inicial (zero), se não a cada vez que voce passa nesse código ele vai decrementando com o negativo atual.

Alterei alem da linha da variavel totalProfit, o select do historico para ser o valor do dia com isso cortei o return.

void PrintOnLoss(const string& symbol, uint ea_magic)

{
        if(HistorySelect(iTime(NULL, PERIOD_D1,0),TimeCurrent())==false) return; // LINHA ALTERADA

        int deals_total=HistoryDealsTotal(); // obtém o total de trades do período
        totalProfit = 0; // LINHA INSERIDA
        for(int i = deals_total-1; i >=0; --i) // loop por todo o histórico, desde o trade mais atual, até achar o último trade no símbolo e com o magic number do EA
        {
                ulong ticket = HistoryDealGetTicket(i);
                string tmp_symbol=HistoryDealGetString(ticket,DEAL_SYMBOL);

                if(tmp_symbol==_Symbol)
                {
                        ulong magic = HistoryDealGetInteger(ticket,DEAL_MAGIC);

                        if(magic==magicNum)
                        {
                               
                                double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT); // obtém o lucro do trade de index i
                                int reason=HistoryDealGetInteger(ticket,DEAL_REASON); // obtém a razão de execução do trade de index i
                                double price=HistoryDealGetDouble(ticket,DEAL_PRICE); // obtém o preço de saída

                                if(profit<0)
                                {
                                        Print(">>> Trade encerrado com prejuízo: R$ ", profit, " - preço: ", price);
                                totalProfit = profit + totalProfit;
                                Print(">>> RESULTADO totalProfit .............:  ", totalProfit);
                                }

                                /*if(reason==DEAL_REASON_SL)
                                {
                                        Print(">>> Trade encerrado com execução no stop loss - preço: ", price);
                                }             
                                return; */ // REMOVI TODO o bloco
                        }
                }
        }
} 
 
Ricardo Rodrigues Lucca #:

Algum moderador vai pegar no seu pé porque precisaria o código ser postado dentro das tags de codigo (fica do lado esquerdo de um botão tipo umas velas e 3 a esquerda do negrito). Mas enfim, eu vi ai que tu tá somando totalProfit, mas voce nunca volta esse valor para zero. Antes de fazer a passagem para contar os valores negativados voce deveria colocar a variavel no estado inicial (zero), se não a cada vez que voce passa nesse código ele vai decrementando com o negativo atual.

Alterei alem da linha da variavel totalProfit, o select do historico para ser o valor do dia com isso cortei o return.

Preciso entender melhor como funcionam as regras por aqui.

Anteriormente inclui a variável como sugeriu, mas ficava retornando 0.0. Muito provável que fiz isso no local errado do código. Sua orientação funcionou perfeitamente.  Muito obrigado pela dica!!!
Você oferece curso de MQL5 ou poderia sugerir um curso? Tem alguns na internet, mas o conteúdo era fraco.

Hoje fui para conta real, e apresentou erro na abertura das ordens. É recomendado abrir novo tópico ou devo seguiu o assunto por aqui?


 
fabriciopduarte #:

Preciso entender melhor como funcionam as regras por aqui.

Anteriormente inclui a variável como sugeriu, mas ficava retornando 0.0. Muito provável que fiz isso no local errado do código. Sua orientação funcionou perfeitamente.  Muito obrigado pela dica!!!
Você oferece curso de MQL5 ou poderia sugerir um curso? Tem alguns na internet, mas o conteúdo era fraco.

Hoje fui para conta real, e apresentou erro na abertura das ordens. É recomendado abrir novo tópico ou devo seguiu o assunto por aqui?


Segue o assunto por aqui, provavelmente foi erro de requote ou invalid stop/price/etc. Basicamente faltaria arredondar os valores de preço que voce informa da maneira a estarem alinhados corretamente. Poderia estudar CSymbol::NormalizePrice para ver como normaliza certinho o preço.

Sobre a outra pergunta, organizar o material de maneira logica é bem complicado e as vezes o iniciante é bem... iniciante. Ao inves de perguntar sobre algum termo que falta ele fica calado e joga no google pra ver. Dai não da pra melhorar o fluxo... Outras vezes da impressão que o cara ta fazendo so pra irritar, dai não sirvo não nem pra video no youtube kkkk. Se procurar acho que disseram no forum algo sobre um tal de vilella, nunca vi. Mas talvez te ajude.

 

Boa tarde a todos;

estou iniciando no ramo e estou buscando auxilio do chatgpt. Meu código não executa as ordens, e a IA não consegue me ajudar kkk.


se poderem me socorrer ficarei imensamente grato.


// Declarações Globais

input double LotSize = 0.1;                // Tamanho do lote

input double StopLoss = 300;              // Stop Loss (pontos)

input double TakeProfit = 100;            // Take Profit (pontos)

input int RSI_Period = 14;                // Período do RSI

input double RSI_Overbought = 70;         // Nível de sobrecompra

input double RSI_Oversold = 30;           // Nível de sobrevenda


int rsiHandle;                            // Manipulador do indicador RSI


// Inicialização

int OnInit()

{

    // Criação do manipulador do RSI

    rsiHandle = iRSI(Symbol(), PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);

    if (rsiHandle == INVALID_HANDLE)

    {

        Print("Erro ao criar o indicador RSI: ", GetLastError());

        return INIT_FAILED;

    }

    Print("Robô inicializado com sucesso.");

    return INIT_SUCCEEDED;

}


// Função principal

void OnTick()

{

    static datetime lastCandleTime = 0; // Controle de velas

    datetime currentCandleTime = iTime(Symbol(), PERIOD_CURRENT, 0);


    // Só executa quando uma nova vela for fechada

    if (currentCandleTime == lastCandleTime) return; 

    lastCandleTime = currentCandleTime;


    double rsiValue[]; // Array para armazenar valores do RSI

    if (CopyBuffer(rsiHandle, 0, 0, 1, rsiValue) <= 0)

    {

        Print("Erro ao copiar buffer do RSI: ", GetLastError());

        return;

    }


    // Exibe valor do RSI no terminal para debug

    Print("RSI Atual: ", rsiValue[0]);


    // Verifica sinais de compra e venda

    if (rsiValue[0] > RSI_Overbought) // Se o RSI estiver acima do nível de sobrecompra

    {

        Print("RSI acima de sobrecompra: ", rsiValue[0]);

        if (!PosicaoAberta(ORDER_TYPE_SELL)) // Se não houver uma posição de venda aberta

        {

            Print("Abrindo ordem de venda...");

            AbrirOrdem(ORDER_TYPE_SELL); // Chama a função para abrir a ordem de venda

        }

    }

    else if (rsiValue[0] < RSI_Oversold) // Se o RSI estiver abaixo do nível de sobrevenda

    {

        Print("RSI abaixo de sobrevenda: ", rsiValue[0]);

        if (!PosicaoAberta(ORDER_TYPE_BUY)) // Se não houver uma posição de compra aberta

        {

            Print("Abrindo ordem de compra...");

            AbrirOrdem(ORDER_TYPE_BUY); // Chama a função para abrir a ordem de compra

        }

    }

}


// Função para verificar se já existe uma posição aberta

bool PosicaoAberta(int type)

{

    // Percorre todas as posições abertas e verifica se há uma posição do tipo especificado

    for (int i = 0; i < PositionsTotal(); i++)

    {

        if (PositionSelect(Symbol())) 

        {

            if (PositionGetInteger(POSITION_TYPE) == type) // Se já existir posição aberta do tipo especificado

            {

                Print("Já existe uma posição aberta do tipo ", (type == ORDER_TYPE_BUY ? "Compra" : "Venda"));

                return true; // Retorna 'true' se já houver uma posição aberta do tipo

            }

        }

    }

    Print("Não há posição aberta do tipo ", (type == ORDER_TYPE_BUY ? "Compra" : "Venda"));

    return false; // Retorna 'false' se não houver uma posição aberta

}


// Função para abrir uma ordem de compra ou venda

void AbrirOrdem(int type)

{

    MqlTradeRequest request;

    MqlTradeResult result;


    double price = (type == ORDER_TYPE_BUY) ? SymbolInfoDouble(Symbol(), SYMBOL_ASK) : SymbolInfoDouble(Symbol(), SYMBOL_BID);

    double sl = (type == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point;

    double tp = (type == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;


    // Preenchendo a estrutura de pedido de negociação

    request.action = TRADE_ACTION_DEAL;

    request.symbol = Symbol();

    request.volume = LotSize;

    request.type = type;

    request.price = price;

    request.sl = NormalizeDouble(sl, _Digits); // Normaliza o Stop Loss

    request.tp = NormalizeDouble(tp, _Digits); // Normaliza o Take Profit

    request.deviation = 10; // Slippage permitido

    request.type_filling = ORDER_FILLING_FOK; // Ordem de preenchimento completa (Fill or Kill)


    // Envia o pedido de negociação

    if (OrderSend(request, result))

    {

        Print("Ordem enviada com sucesso. Ticket: ", result.order); // Sucesso

    }

    else

    {

        Print("Erro ao enviar ordem: ", GetLastError()); // Erro ao enviar ordem

    }

}


 
rodineisantiago santiago #:

Boa tarde a todos;

estou iniciando no ramo e estou buscando auxilio do chatgpt. Meu código não executa as ordens, e a IA não consegue me ajudar kkk.


se poderem me socorrer ficarei imensamente grato.

Primeiro chatgpt não é saber programar robo, recomendo voce começar lendo o livro que tem aqui no topo que ele tem várias explicações úteis de se saber e exemplos de código para executar.

Segundo, tem que aprender a colocar o código aqui no forum que tem um botãozinho que deixa ele bonito, colorido e fácil de ver.