Calcular Lucro Diário, Semanal e Mensal

 

Boa noite galera,

Estou desenvolvendo um EA e estou com dificuldade:

Gostaria de realizar a  soma dos lucros/perdas diárias e dividir em lucro/perda semanal e  lucro/perda mensal, pois estou criando um painel e gostaria de apresentar esses resultados na tela.

Só consegui fazer a soma do lucro diário, criando uma função que soma todas as operações do dia, com o HistorySelect do dia para zerar no dia seguinte os valores e somando com o HistoryDealGetDouble, que fica chamando no OnTick();

Até tentei fazer algo dentro dessa função, mas como ela é chamada no OnTick() fica em loop infinito rs!

O que queria:

- Calcular Lucro Semanal. Virou a semana, esse valor zera e começa de novo.
- Calcular Lucro Mensal. Virou o mês, esse valor zera e começa de novo.

Alguém conseguiria me ajudar como posso fazer?

Documentação sobre MQL5: Funções de Negociação / HistoryDealGetDouble
Documentação sobre MQL5: Funções de Negociação / HistoryDealGetDouble
  • www.mql5.com
HistoryDealGetDouble - Funções de Negociação - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 
Diogo Silva:

Boa noite galera,

Estou desenvolvendo um EA e estou com dificuldade:

Gostaria de realizar a  soma dos lucros/perdas diárias e dividir em lucro/perda semanal e  lucro/perda mensal, pois estou criando um painel e gostaria de apresentar esses resultados na tela.

Só consegui fazer a soma do lucro diário, criando uma função que soma todas as operações do dia, com o HistorySelect do dia para zerar no dia seguinte os valores e somando com o HistoryDealGetDouble, que fica chamando no OnTick();

Até tentei fazer algo dentro dessa função, mas como ela é chamada no OnTick() fica em loop infinito rs!

O que queria:

- Calcular Lucro Semanal. Virou a semana, esse valor zera e começa de novo.
- Calcular Lucro Mensal. Virou o mês, esse valor zera e começa de novo.

Alguém conseguiria me ajudar como posso fazer?

Boa noite!


Se quiser, você pode testar a função abaixo. Acredito que para pegar os resultado semanais / mensais, basta apenas alterar a data inicial da busca do histórico de operações [pode até passar como parâmetro (ou usar as 3 funções)]:

//--- Semanal
datetime time_start = iTime(_Symbol, PERIOD_W1, 0);



//--- Mensal
datetime time_start = iTime(_Symbol, PERIOD_MN1, 0);


Segue a função:

//+------------------------------------------------------------------+
//| Calcula o lucro / prejuízo do dia atual                          |
//+------------------------------------------------------------------+
double CurrentDayResults()
  {
   datetime time_start = iTime(_Symbol, PERIOD_D1, 0);
   double   result = 0.0;
   ulong    ticket;
   int      cnt;

   if(HistorySelect(time_start, TimeCurrent()))
     {
      for(cnt = HistoryDealsTotal() - 1; cnt >= 0; cnt--)
        {
         ticket = HistoryDealGetTicket(cnt);
         if(ticket != 0)
           {
            if(HistoryDealGetInteger(ticket, DEAL_MAGIC) == EA_MAGIC)
              {
               result += HistoryDealGetDouble(ticket, DEAL_PROFIT);
              }
           }
         else
           {
            Print("Error getting deal ticket in history ...");
            result = EMPTY_VALUE;
            break;
           }
        }
     }
   else
     {
      Print("Error getting operations history ...");
      result = EMPTY_VALUE;
     }

   return(result);
  }


Se resolver testar, informe o resultado (ok | erro) ou alterações realizadas para auxiliar pessoas com a mesma dúvida. 👍



Obs.: Em caso de erro, a função retorna EMPTY_VALUE. Isso deve ser verificado também.

 
Vinicius de Oliveira:

Boa noite!


Se quiser, você pode testar a função abaixo. Acredito que para pegar os resultado semanais / mensais, basta apenas alterar a data inicial da busca do histórico de operações [pode até passar como parâmetro (ou usar as 3 funções)]:


Segue a função:


Se resolver testar, informe o resultado (ok | erro) ou alterações realizadas para auxiliar pessoas com a mesma dúvida. 👍



Obs.: Em caso de erro, a função retorna EMPTY_VALUE. Isso deve ser verificado também.


Caraca funcionou!!! Era isso mesmo o que precisava! Obrigado mesmo!

Tinha até feito uma função semelhante mas não sabia desse lance do PERIOD_D1, PERIOD_W1, PERIOD_MN1 e o que você me passou está mais clean. Fiz só uma adaptação, removi o if do EA_MAGIC pois tava dando erro e não vou utilizá-lo, pois estou fazendo mais pra scalp e entrada única.

Só percebi que no modo testador de estratégia, o PERIOD_MN1 retorna o saldo em conta + os resultados. Não sei se isso se trata do testador ou se ele pega mesmo e soma com o que entrar.

O que fiz:

- Passo uma variável dentro da função:

double Results(datetime data) {
   datetime time_start = data;
   double   result = 0.0;
   ulong    ticket;
   int      cnt;

   if(HistorySelect(time_start, TimeCurrent()))
     {
      for(cnt = HistoryDealsTotal() - 1; cnt >= 0; cnt--)
        {
         ticket = HistoryDealGetTicket(cnt);
         if(ticket != 0)
           {
               result += HistoryDealGetDouble(ticket, DEAL_PROFIT);
           }
         else
           {
            Print("Error getting deal ticket in history ...");
            result = EMPTY_VALUE;
            break;
           }
        }
     }
   else
     {
      Print("Error getting operations history ...");
      result = EMPTY_VALUE;
     }
   return(result);
}

Dai depois no OnTick() eu chamo conforme me passou:

   ganhos_semana  = Results(iTime(_Symbol, PERIOD_W1, 0));
   ganhos_mes     = Results(iTime(_Symbol, PERIOD_MN1, 0));

O ganhos_semana ficou OK, só o ganhos_mes que vem junto o saldo inicial da conta. Não sei se isso é só no modo testador ou na primeira entrada do robô. Fiz o teste na virada do mês e ele funcionou!

 
Vou aproveitar agora e usar para a Diária também, o que tinha feito ficou bem poluído
 
Diogo Silva:


Caraca funcionou!!! Era isso mesmo o que precisava! Obrigado mesmo!

Tinha até feito uma função semelhante mas não sabia desse lance do PERIOD_D1, PERIOD_W1, PERIOD_MN1 e o que você me passou está mais clean. Fiz só uma adaptação, removi o if do EA_MAGIC pois tava dando erro e não vou utilizá-lo, pois estou fazendo mais pra scalp e entrada única.

Só percebi que no modo testador de estratégia, o PERIOD_MN1 retorna o saldo em conta + os resultados. Não sei se isso se trata do testador ou se ele pega mesmo e soma com o que entrar.

O que fiz:

- Passo uma variável dentro da função:

Dai depois no OnTick() eu chamo conforme me passou:

O ganhos_semana ficou OK, só o ganhos_mes que vem junto o saldo inicial da conta. Não sei se isso é só no modo testador ou na primeira entrada do robô. Fiz o teste na virada do mês e ele funcionou!

Beleza Diogo! Valeu também pelas observações!


Duas coisas:

- Lembrando novamente de verificar se o retorno da função é diferente de EMPTY_VALUE (erro);

- Como você não utiliza a verificação do Magic Number, precisa ver outra forma de confirmar se cada lançamento que está sendo adicionado ao resultado da função se trata realmente de um trade, senão ela vai adicionar lançamentos como depósitos, saques, possíveis lançamentos realizados pela corretora, . . . Deve ser por isso que está ocorrendo o erro que você identificou em PERIOD_MN1 . . . Outras formas que você pode usar para verificação: DEAL_TYPE, DEAL_REASON, ...


Bons negócios!!!

 
Vinicius de Oliveira:

Beleza Diogo! Valeu também pelas observações!


Duas coisas:

- Lembrando novamente de verificar se o retorno da função é diferente de EMPTY_VALUE (erro);

- Como você não utiliza a verificação do Magic Number, precisa ver outra forma de confirmar se cada lançamento que está sendo adicionado ao resultado da função se trata realmente de um trade, senão ela vai adicionar lançamentos como depósitos, saques, possíveis lançamentos realizados pela corretora, . . . Deve ser por isso que está ocorrendo o erro que você identificou em PERIOD_MN1 . . . Outras formas que você pode usar para verificação: DEAL_TYPE, DEAL_REASON, ...


Bons negócios!!!

Opa Vinícius, estou tentando fazer o que você falou...mas ainda não consegui.

Essa verificação, como eu poderia fazer, caso eu não utilize o Magic Number?

 
Diogo Silva:

Opa Vinícius, estou tentando fazer o que você falou...mas ainda não consegui.

Essa verificação, como eu poderia fazer, caso eu não utilize o Magic Number?

Opa, Diogo!


Veja se uma dessas dá certo no seu caso:

if(HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_BUY || HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_SELL)



//--- Caso todas as posições sejam abertas por EAs
if(HistoryDealGetInteger(ticket, DEAL_REASON) == DEAL_REASON_EXPERT)



//--- Caso todas as posições sejam encerradas por SL ou TP
if(HistoryDealGetInteger(ticket, DEAL_REASON) == DEAL_REASON_SL || HistoryDealGetInteger(ticket, DEAL_REASON) == DEAL_REASON_TP)


Ficaria assim, por exemplo:

double Results(datetime time_start)
  {
   double result = 0.0;
   ulong  ticket;
   int    cnt;

   if(HistorySelect(time_start, TimeCurrent()))
     {
      for(cnt = HistoryDealsTotal() - 1; cnt >= 0; cnt--)
        {
         ticket = HistoryDealGetTicket(cnt);
         if(ticket != 0)
           {
            if(HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_BUY || HistoryDealGetInteger(ticket, DEAL_TYPE) == DEAL_TYPE_SELL)
              {
               result += HistoryDealGetDouble(ticket, DEAL_PROFIT);
              }
           }
         else
           {
            Print("Error getting deal ticket in history ...");
            result = EMPTY_VALUE;
            break;
           }
        }
     }
   else
     {
      Print("Error getting operations history ...");
      result = EMPTY_VALUE;
     }

   return(result);
  }
 
Vinicius de Oliveira:

Opa, Diogo!


Veja se uma dessas dá certo no seu caso:

Opa Vinícius, todas funcionaram! Vou ver qual a melhor se enquadra no meu caso, caso eu queira fazer outra verificação, por exemplo, a do SL e TP posso contar a quantidade de SL e TP, acho que vou usar essa.

Cara, obrigado mesmo, me ajudou demais!

 
Diogo Silva:

Opa Vinícius, todas funcionaram! Vou ver qual a melhor se enquadra no meu caso, caso eu queira fazer outra verificação, por exemplo, a do SL e TP posso contar a quantidade de SL e TP, acho que vou usar essa.

Cara, obrigado mesmo, me ajudou demais!

De nada!! 👍

 
Vinicius de Oliveira #:

Boa noite!


Se quiser, você pode testar a função abaixo. Acredito que para pegar os resultado semanais / mensais, basta apenas alterar a data inicial da busca do histórico de operações [pode até passar como parâmetro (ou usar as 3 funções)]:


Segue a função:


Se resolver testar, informe o resultado (ok | erro) ou alterações realizadas para auxiliar pessoas com a mesma dúvida. 👍



Obs.: Em caso de erro, a função retorna EMPTY_VALUE. Isso deve ser verificado também.

Opa beleza, essa função serve para conta netting ou hedge?

 
David.fdl #:

Opa beleza, essa função serve para conta netting ou hedge?

Bom dia!


Fiz considerando a minha conta, que é hedge, mas deve funcionar nos dois tipos. Faça os testes, beleza?

Razão: