Função para obter soma líquida de volume em aberto resultando erro

 

Boa noite.

Estou depurando uma função que escrevi para varrer a posições abertas e somar o volume considerando valor (+) para compra e (-) para venda com objetivo de obter o valor líquido do volume aberto..

No entanto em determinados momentos a função está retornando um valor que não condiz com as posições abertas.

Vejam o caso do print em anexo: na lista de posições em aberto na tela do Metatrader mostra o ticket #10 com volume de 0,05 mas no depurador do mql5 a função está puxando o volume do mesmo ticket (#10) e o volume que está lendo é de 2,65... não estou entendendo de onde está vindo este valor... alguém já passou por algo assim? ou sabe onde estou errando?

Segue meu código:

double volumeaberto()
{
   double result = 0;
   int posTotal = PositionsTotal();

   for(int posIndex = posTotal - 1; posIndex >= 0; posIndex--)
   {
      ulong ticket = PositionGetTicket(posIndex);

      if(PositionSelectByTicket(ticket)) 
      {
         int positionType = PositionGetInteger(POSITION_TYPE);
         double positionVolume = PositionGetDouble(POSITION_VOLUME);

         if(positionType == POSITION_TYPE_BUY)
         {
            result += positionVolume;
         }
         else if(positionType == POSITION_TYPE_SELL)
         {
            result -= positionVolume;            
         }
      }
   }

   return result;
}
Código formatado incorrectamente editado pelo moderador.

Print:


 

Por favor, utilize o botão do CÓDIGO (Alt -S) ao inserir o seu código.

Botão de código no editor

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 

 
Ricardo Alexandre Laurentino: Estou depurando uma função que escrevi para varrer a posições abertas e somar o volume considerando valor (+) para compra e (-) para venda com objetivo de obter o valor líquido do volume aberto.. No entanto em determinados momentos a função está retornando um valor que não condiz com as posições abertas.Vejam o caso do print em anexo: na lista de posições em aberto na tela do Metatrader mostra o ticket #10 com volume de 0,05 mas no depurador do mql5 a função está puxando o volume do mesmo ticket (#10) e o volume que está lendo é de 2,65... não estou entendendo de onde está vindo este valor... alguém já passou por algo assim? ou sabe onde estou errando?

Pela sua imagem, o depurador ainda não executou a linha no qual obtém o volume.

O depurador indica a linha a seguir a qual já executou, mas não executa a linha na qual indica. Terá de depurar mais o passo/linha para ver o resultado.

 

Sr. Fernando obrigado por responder e realocar meu post.

Eu segui com o depurador passo a passo até chegar ao fim da função e agora veja o print com o depurador já na última linha da função.

O resultado, somando as posições abertas deveria ser = 0. Acompanhando o passo a passo até parece que está somando certo, mas na hora de executar o "return result;" parece que o valor se perde e ele retorna esse valor errado! (-2,77...)


 
Ricardo Alexandre Laurentino #: Sr. Fernando obrigado por responder e realocar meu post. Eu segui com o depurador passo a passo até chegar ao fim da função e agora veja o print com o depurador já na última linha da função. O resultado, somando as posições abertas deveria ser = 0. Acompanhando o passo a passo até parece que está somando certo, mas na hora de executar o "return result;" parece que o valor se perde e ele retorna esse valor errado! (-2,77...)

Desconheço o resto do seu código, e como tal será difficult comentar os resultados. No entanto, aqui segue uma versão simplificada do código que apresentou, na qual corrigi dois pontos (ver mais abaixo).

double volumeaberto() {
   double result = 0;
   for( int posIndex = PositionsTotal() - 1; posIndex >= 0; posIndex-- ) {
      if( PositionGetTicket( posIndex ) > 0 ) {
         double positionVolume = PositionGetDouble( POSITION_VOLUME );
         if( positionVolume > 0 ) {
            switch( (ENUM_POSITION_TYPE) PositionGetInteger( POSITION_TYPE ) ) {
               case POSITION_TYPE_BUY:  result += positionVolume; break;
               case POSITION_TYPE_SELL: result -= positionVolume; break;
            };
         };
      };
   };
   return result;
};
  1. Não é necessário utilizar PositionSelectByTicket, visto que PositionGetTicket já selecciona a posição.
  2. Deve testar o valor devolvido por PositionGetDouble, pois no caso de falha, a função retorna o valor de zero.
Reduzi também o número de atribuições de variáveis meramente para ser mais eficiente na sua execução, mas caso necessite de utilizar o valor mais do que uma vez, deve atribuir o valor a uma variável como fez no seu código original.

    No entanto, como para efeitos de depuramento necessitará as variáveis, aqui segue uma verão para tal.

    double volumeaberto() {
       double result = 0;
       int posTotal = PositionsTotal();
       for( int posIndex = posTotal - 1; posIndex >= 0; posIndex-- ) {
          ulong ticket = PositionGetTicket( posIndex );
          if( ticket > 0 ) {
             double positionVolume = PositionGetDouble( POSITION_VOLUME );
             if( positionVolume > 0 ) {
                ENUM_POSITION_TYPE positionType = PositionGetInteger( POSITION_TYPE );
                switch( positionType ) {
                   case POSITION_TYPE_BUY:  result += positionVolume; break;
                   case POSITION_TYPE_SELL: result -= positionVolume; break;
                };
             };
          };
       };
       return result;
    };