Função para Calcular lucro máximo

 
Olá a todos;

Eu criei uma função que calcula meu lucro por dia.

Meus parâmetros de rede são "Maximum Profit" e "Maximum Loss". Eu criei esta função para administrar meu limite de perda e limitar o ganho por dia e quando este limite é atingido, meu EA para de operar.

No entanto, não funciona muito bem. A função parece não estar bem formulada e às vezes minha posição é fechada no momento errado. Alguém pode me ajudar, por favor?
sinput string Maximum; // Maximum Profit/Loss 
input bool UseLimit=true;
input double MaximumProfit=400; // Monetary Value
input double MaximumLoss=-400; // Monetary Value

if(UseLimit==true && CalcProfit()==true)
{
TradeNow = 0;
if(OpenOrders(_Symbol) > 0)
{
CLOSEALL(0);CLOSEALL(1);
}

Print("Profit limit was reached");
Comment("Profit limit was reached");

//+------------------------------------------------------------------+
//|Function Calcprofit                                               |
//+------------------------------------------------------------------+
bool CalcProfit()
  {
// --- determine the time intervals of the required trading history
   datetime end=StringToTime(TimeToString(TimeCurrent(), TIME_DATE) + " " + EndHour); 
   datetime gi_time = StringToTime(TimeToString(TimeCurrent(), TIME_DATE) + " " + StartHour);                                                                                                                      
   datetime start=end-PeriodSeconds(PERIOD_D1);// set the beginning time to 24 hours ago

//--- request in the cache of the program the needed interval of the trading history
   HistorySelect(gi_time,end);
//--- obtain the number of deals in the history
   int deals=HistoryDealsTotal();

   int returns=0;
   double profit=0;
   double loss=0;
//--- scan through all of the deals in the history
   for(int i=0;i<deals;i++)
     {
      //--- obtain the ticket of the deals by its index in the list
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0) // obtain into the cache the deal, and work with it
        
        {
         string symbol             =HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
         datetime time             =HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         ulong order               =HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
         long order_magic          =HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
         long pos_ID               =HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         //--- proceed deal with specified DEAL_MAGIC
         if(order_magic==MagicNumber)
           {
            //... processing of deal with some DEAL_MAGIC
           
            if(symbol==_Symbol)
              {
               if(entry_type==DEAL_ENTRY_OUT)
                 returns++;
                 {
                  double result=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
                  if((result>=MaximumProfit) || (result+Position.Profit()>= MaximumProfit))
                    {
                    return(true);
                    if(result>0)
                    {
                    profit=result;
                   
                    }
                    }
                  if((result<=MaximumLoss) ||  (result+Position.Profit()<=MaximumLoss))
                    {
                    return(true);
                    if(result<0)
                    {
                    loss=result;
                    
                    }
                    }
                 }
              }
           }

        }
      else // unsuccessful attempt to obtain a deal
        {
         PrintFormat("We couldn't select a deal, with the index %d. Error %d",
                     i,GetLastError());
        }
     }
//--- output the results of the calculations
   PrintFormat("The total number of %d deals with a financial result. Profit=%.2f , Loss= %.2f",
               returns,profit,loss);
              
               
   return(false);
  }


 

Dei uma olhada rápida e o problema parece ser o seguinte:

Você deseja encerrar as posições sempre que o seu lucro acumulado exceder MaximumProfit ou o seu prejuízo acumulado exceder MaximumLoss, certo?

Só que a variável "result" está sendo criada dentro do escopo do loop "for" e os resultados dos diferentes deals não estão sendo somados. Você está simplesmente comparando o resultado de cada deal com os limites e fechando as posições no momento em que ALGUM dentre os deals realizados exceder INDIVIDUALMENTE um dos limites.

Com isso, as posições poderão ser fechadas antes do momento desejado (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver lucro de +500, passando a ter um lucro acumulado de +200, a posição será fechada indevidamente).

Pode acontecer também de as posições não serem fechadas no momento em que deveriam (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver prejuízo de -200, passando a ter um prejuízo acumulado de -500, a posição não será fechada, mas deveria ser).

Para resolver esse problema, vc precisa:

1) Declarar  

double result=0;

antes do início do loop (junto com as declarações das variáveis "profit" e "loss").

2) Substituir

double result=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

por

result += HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

para que a variável "result" reflita o resultado acumulado (somatório dos resultados de todos os trades realizados).

Em tempo, percebi um segundo problema: vc colocou instruções "return" antes das cláusulas "if" que atualizam as variáveis "profit" e "loss". Com isso elas nunca serão atualizadas e eu imagino que vc sempre vai ver "Profit = 0.00" e "Loss = 0.00" na mensagem que vc imprime. Para corrigir isso, coloque as instruções "return(true)" APÓS a cláusula "if".

 Pode haver mais problemas, pois infelizmente nosso tempo é escasso e eu olhei muito rápido, mas acredito que os principais problemas sejam estes que descrevi.

Abraços

 
Trader_Patinhas:

Dei uma olhada rápida e o problema parece ser o seguinte:

Você deseja encerrar as posições sempre que o seu lucro acumulado exceder MaximumProfit ou o seu prejuízo acumulado exceder MaximumLoss, certo?

Só que a variável "result" está sendo criada dentro do escopo do loop "for" e os resultados dos diferentes deals não estão sendo somados. Você está simplesmente comparando o resultado de cada deal com os limites e fechando as posições no momento em que ALGUM dentre os deals realizados exceder INDIVIDUALMENTE um dos limites.

Com isso, as posições poderão ser fechadas antes do momento desejado (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver lucro de +500, passando a ter um lucro acumulado de +200, a posição será fechada indevidamente).

Pode acontecer também de as posições não serem fechadas no momento em que deveriam (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver prejuízo de -200, passando a ter um prejuízo acumulado de -500, a posição não será fechada, mas deveria ser).

Para resolver esse problema, vc precisa:

1) Declarar  

double result=0;

antes do início do loop (junto com as declarações das variáveis "profit" e "loss").

2) Substituir

double result=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

por

result += HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

para que a variável "result" reflita o resultado acumulado (somatório dos resultados de todos os trades realizados).

Em tempo, percebi um segundo problema: vc colocou instruções "return" antes das cláusulas "if" que atualizam as variáveis "profit" e "loss". Com isso elas nunca serão atualizadas e eu imagino que vc sempre vai ver "Profit = 0.00" e "Loss = 0.00" na mensagem que vc imprime. Para corrigir isso, coloque as instruções "return(true)" APÓS a cláusula "if".

 Pode haver mais problemas, pois infelizmente nosso tempo é escasso e eu olhei muito rápido, mas acredito que os principais problemas sejam estes que descrevi.

Abraços

Pode crer Trader Patinhas. Estava acontecendo isso mesmo que vc descreveu. Fiz as devidas alterações conforme suas instruções.

Vou verificar se haverá algum problema no código. 

Obrigado pelo suporte.

 
Trader_Patinhas:

Dei uma olhada rápida e o problema parece ser o seguinte:

Você deseja encerrar as posições sempre que o seu lucro acumulado exceder MaximumProfit ou o seu prejuízo acumulado exceder MaximumLoss, certo?

Só que a variável "result" está sendo criada dentro do escopo do loop "for" e os resultados dos diferentes deals não estão sendo somados. Você está simplesmente comparando o resultado de cada deal com os limites e fechando as posições no momento em que ALGUM dentre os deals realizados exceder INDIVIDUALMENTE um dos limites.

Com isso, as posições poderão ser fechadas antes do momento desejado (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver lucro de +500, passando a ter um lucro acumulado de +200, a posição será fechada indevidamente).

Pode acontecer também de as posições não serem fechadas no momento em que deveriam (exemplo: se você estiver com prejuízo acumulado de -300 e um deal obtiver prejuízo de -200, passando a ter um prejuízo acumulado de -500, a posição não será fechada, mas deveria ser).

Para resolver esse problema, vc precisa:

1) Declarar  

double result=0;

antes do início do loop (junto com as declarações das variáveis "profit" e "loss").

2) Substituir

double result=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

por

result += HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

para que a variável "result" reflita o resultado acumulado (somatório dos resultados de todos os trades realizados).

Em tempo, percebi um segundo problema: vc colocou instruções "return" antes das cláusulas "if" que atualizam as variáveis "profit" e "loss". Com isso elas nunca serão atualizadas e eu imagino que vc sempre vai ver "Profit = 0.00" e "Loss = 0.00" na mensagem que vc imprime. Para corrigir isso, coloque as instruções "return(true)" APÓS a cláusula "if".

 Pode haver mais problemas, pois infelizmente nosso tempo é escasso e eu olhei muito rápido, mas acredito que os principais problemas sejam estes que descrevi.

Abraços

O "profit"=0.00" e "Loss=0.00" continua. Eu andei lendo no fórum em inglês que isso acontece quando é utilizado o Magic Number como referência.

Mas por enquanto as operações não estão fechando com erro.

 
tito.vinicius:

O "profit"=0.00" e "Loss=0.00" continua. Eu andei lendo no fórum em inglês que isso acontece quando é utilizado o Magic Number como referência.

Mas por enquanto as operações não estão fechando com erro.

Vc transferiu o "return(true);" pra depois das cláusulas "if" que atualizam "profit" e "loss" com o conteúdo de "result" ?

Se tiver dúvida, me mostra como ficou o seu código. 

 
Trader_Patinhas:

Vc transferiu o "return(true);" pra depois das cláusulas "if" que atualizam "profit" e "loss" com o conteúdo de "result" ?

Se tiver dúvida, me mostra como ficou o seu código. 

Tranquilo irmão. Seguem o código.

//+------------------------------------------------------------------+
//|Function Calcprofit                                               |
//+------------------------------------------------------------------+
bool CalcProfit()
  {
// --- determine the time intervals of the required trading history
   datetime end=StringToTime(TimeToString(TimeCurrent(), TIME_DATE) + " " + EndHour); 
   datetime gi_time = StringToTime(TimeToString(TimeCurrent(), TIME_DATE) + " " + StartHour);                                                                                                                     
   datetime start=end-/*gi_time;*/ PeriodSeconds(PERIOD_D1);// set the beginning time to 24 hours ago

//--- request in the cache of the program the needed interval of the trading history
   HistorySelect(gi_time,end);
//--- obtain the number of deals in the history
   int deals=HistoryDealsTotal();

   double result=0;
   int returns=0;
   double profit=0;
   double loss=0;
//--- scan through all of the deals in the history
   for(int i=0;i<deals;i++)
     {
      //--- obtain the ticket of the deals by its index in the list
      ulong deal_ticket=HistoryDealGetTicket(i);
      if(deal_ticket>0) // obtain into the cache the deal, and work with it
        
        {
         string symbol             =HistoryDealGetString(deal_ticket,DEAL_SYMBOL);
         datetime time             =(datetime)HistoryDealGetInteger(deal_ticket,DEAL_TIME);
         ulong order               =HistoryDealGetInteger(deal_ticket,DEAL_ORDER);
         long order_magic          =HistoryDealGetInteger(deal_ticket,DEAL_MAGIC);
         long pos_ID               =HistoryDealGetInteger(deal_ticket,DEAL_POSITION_ID);
         ENUM_DEAL_ENTRY entry_type=(ENUM_DEAL_ENTRY)HistoryDealGetInteger(deal_ticket,DEAL_ENTRY);
         //--- proceed deal with specified DEAL_MAGIC
         if(order_magic==MagicNumber)
           {
            //... processing of deal with some DEAL_MAGIC
           
            if(symbol==_Symbol)
              {
               if(entry_type==DEAL_ENTRY_OUT)
                 returns++;
                 {
                  result+=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);
                  if((result>=MaximumProfit) || (result+Position.Profit()>= MaximumProfit))
                    {
                   
                    if(result>0)
                    {
                    profit=result;
                    }
                    return(true);
                    }
                  if((result<=MaximumLoss) ||  (result+Position.Profit()<=MaximumLoss))
                    {
                    
                    if(result<0)
                    {
                    loss=result;
                    
                    }
                    return(true);
                    }
                 }
              }
           }

        }
      else // unsuccessful attempt to obtain a deal
        {
         PrintFormat("We couldn't select a deal, with the index %d. Error %d",
                     i,GetLastError());
        }
     }
//--- output the results of the calculations
   PrintFormat("The total number of %d deals with a financial result. Profit=%.2f , Loss= %.2f",
               returns,profit,loss,result);       
              
               
   return(false);
  }
 
tito.vinicius:

Tranquilo irmão. Seguem o código.

Ah, claro, o profit e o loss aparecem sempre com 0.0 porque eles só estão sendo atualizados quando um dos limites é excedido e, nesses casos, a função retorna sem imprimir.

As cláusulas "if" que atualizam o profit e o loss têm que ficar fora (antes) da cláusula "if" que compara "result" com os limites:

result+=HistoryDealGetDouble(deal_ticket,DEAL_PROFIT);

if(result>0)
{
   profit=result;
}
if(result<0)
{
   loss=result;
}

if((result>=MaximumProfit) || (result+Position.Profit()>= MaximumProfit))
{
   return(true);
}
if((result<=MaximumLoss) ||  (result+Position.Profit()<=MaximumLoss))
{
   return(true);
}
 
Trader_Patinhas:

Ah, claro, o profit e o loss aparecem sempre com 0.0 porque eles só estão sendo atualizados quando um dos limites é excedido e, nesses casos, a função retorna sem imprimir.

As cláusulas "if" que atualizam o profit e o loss têm que ficar fora (antes) da cláusula "if" que compara "result" com os limites:

Trader_Patinhas, por enquanto está tudo funcionando perfeitamente.

Obrigado pelo suporte.

Descrição

Abraços.

 

Meus prezados boa tarde!

Penso que esse codigo e o que eu estou precisando para me auxiliar no controle de perdas do meu EA. Porem sou novo nesse mundo da programacao. Sera que alguem pode me auxiliar me ajudando a colar o codigo de forma correta no codigo que eu ja tenho