Fechar operações que somam o lucro do alvo

 

Olá, estou com uma dificuldade de montar uma função que feche apenas todas as ordens do par que soma o total de 0.50 USD independente se tiver ordens negativas. 

Usei o código abaixo porém, infelizmente ao ter ordens de um par que atingiu o valor do alvo que é 0.50, todas as ordens são fechadas inclusive de outros pares, mas precisava que feche apenas as ordens desse par que atingiu o alvo, mantendo os outros pares em aberto. Não consegui montar a lógica correta. Podem me auxiliar?


// FUNÇÃO PARA FECHAR OPERAÇÕES DO PAR QUE ATINGIU O ALVO DE LUCRO OU LUCRO ESPECÍFICO
void VerificafecharOperacoesMoeda()
 {  
  for(int i=PositionsTotal();i>=0;i--)
        {
               
               ulong ticket = PositionGetTicket(i);
               string symbol = PositionGetSymbol(i);
               bool meta = ObterLucroTotalPar() < alvo;
            
                 if(meta && symbol == _Symbol)
                    {
                   
                        trade.PositionClose(ticket);
                      
                    }
         }

double ObterLucroTotalPar()
{
    // Verificar negociações abertas
    int totalPositions = PositionsTotal();
    double lucroTotalPar = 0;
    double swap = 0;
    
    for (int i = 0; i < totalPositions; i++)
    {
        
        string symbol = PositionGetSymbol(i);
        
        if (symbol == _Symbol)
        {
            double lucroOperacoesPar = PositionGetDouble(POSITION_PROFIT);
            double swapAux = PositionGetDouble(POSITION_SWAP);
            
            lucroTotalPar += lucroOperacoesPar;
            swap += swapAux;
        }
    }
        return lucroTotalPar+swap;
    
   }
 
Adilson Albino Pereira:

Olá, estou com uma dificuldade de montar uma função que feche apenas todas as ordens do par que soma o total de 0.50 USD independente se tiver ordens negativas. 

Usei o código abaixo porém, infelizmente ao ter ordens de um par que atingiu o valor do alvo que é 0.50, todas as ordens são fechadas inclusive de outros pares, mas precisava que feche apenas as ordens desse par que atingiu o alvo, mantendo os outros pares em aberto. Não consegui montar a lógica correta. Podem me auxiliar?


1) Comece indetando seu código corretamente, muitos erros voce pode acabar percebendo só por identa-lo corretamente;

2) Pelo código postado, ele encerra todas as operações que estão abaixo de um determinado alvo e que case com o ativo do gráfico que voce rodou esse snippet.

 
Ricardo Rodrigues Lucca #:

1) Comece indetando seu código corretamente, muitos erros voce pode acabar percebendo só por identa-lo corretamente;

2) Pelo código postado, ele encerra todas as operações que estão abaixo de um determinado alvo e que case com o ativo do gráfico que voce rodou esse snippet.

Olá, sobre identação reconheço que está em falta, é porque não sou experiente em programação, estou começando agora.

Dei uma olhada nos artigos que forneceu, mas não ajudou, pois os mesmo apresentam a ideia de fechar todas as ordens em aberto independente do par de moeda quando a soma de todas as ordens atingir um valor de lucro específico. Mas não é isso que preciso no momento.

Eu preciso que não feche todas as operação ao mesmo tempo, preciso que feche apenas operações do mesmo par que atingir o lucro de 0.50.

Exemplo: 
se tenho ordem no EURGBP, EURUSD, e 2 ordens no NZDCHF...

Se as duas ordens de NZDCHF a primeira com flutuante igual a 0.70 e segunda igual  a -0,20... No total essas duas operações do NZDCHF terão a soma de 0.50 nesse caso quero fechar as duas operações do NZDCHF e manter as outras ordens do EURGBP,  e EURUSD abertas até atenderem os requisitos.

Tentei uma segunda logica conforme código abaixo, mas tambem não deu certo, continua fechando todas operações de todos os pares quando um par de moeda atinge o valor do alvo.

// Função para fechar todas as operações para um par de moedas específico
void fecharOperacoesPar(string symbol) {
    for (int i = PositionsTotal() - 1; i >= 0; i--) {
        ulong ticket = PositionGetTicket(i);
        string positionSymbol = PositionGetSymbol(i);

        if (positionSymbol == symbol) {
            trade.PositionClose(ticket);
        }
    }
}

void VerificafecharOperacoesMoeda() {
    // Percorre todos os pares de moedas
    for (int i = 0; i < SymbolsTotal(true); i++) {
        string symbol = SymbolName(i, true);

        // Calcula a soma do lucro para o par de moedas atual
        double lucroTotalPar = ObterLucroTotalPar(symbol);

        // Verifica se a soma do lucro atingiu 0.5 USD
        if (lucroTotalPar == 0.5) {
            // Fecha operações apenas para o par de moedas atual
            fecharOperacoesPar(symbol);
        }
    }
}
 
Adilson Albino Pereira #:

Nesse codigo o erro seria provavelmente na ObterLucroTotalPar não mostrada. A unica coisa sobre a postada é que voce colocou um parametro e esse parametro deveria substituir o _Symbol referenciado ali no post. Todo o resto permanencendo seria para estar correto. A fecharOperacoesPar  me parece correta sem nada chamando atenção, o trecho do VerificafecharOperacoesMoeda a unica coisa que chama atenção seria o lucroTotalPar == 0.5 que para mim deveria ser >=. Voce nunca deveria testar um valor double ou float por um valor exato.

Possivelmente o que pode estar ocorrendo seu ObterLucroTotalPar não considera o parametro recebido corretamente e esta a retornar para todos os pares o valor de um unico que "atingiu" o limite e assim chama o fechar para todos os casos. Voce deveria conseguir depurar isso com o depurador ou colocando Print().

EDIT: resolvi colocar a função editada aqui que fica mais claro do que explicar textualmente.

double ObterLucroTotalPar(string s) // nao sei o nome que colocou, mas se foi symbol esta errado que ja tem uma variavel la pra baixo com esse nome 
{
    // Verificar negociações abertas
    int totalPositions = PositionsTotal();
    double lucroTotalPar = 0;
    double swap = 0;
    
    for (int i = 0; i < totalPositions; i++)
    {
        string symbol = PositionGetSymbol(i);
        
        if (symbol == s)
        {
            double lucroOperacoesPar = PositionGetDouble(POSITION_PROFIT);
            double swapAux = PositionGetDouble(POSITION_SWAP);
            
            lucroTotalPar += lucroOperacoesPar;
            swap += swapAux;
        }
    }
        return lucroTotalPar+swap;
}
 
Pessoal obrigado pelo auxilio, consegui resolver a desafio, criando um array com a lista de pares que utilizo e depois fiz a comparação para fechar. Segue pedaço do código.

string lista_pares[] = {"EURUSD","EURGBP", "NZDCHF", "AUDJPY","GBPUSD", 
                        "USDJPY", "AUDUSD", "USDCAD", "USDCHF", "NZDUSD"};

//VERIFICAR PAR DE MOEDA NA LISTA E FECHAR
   if(ObterLucroTotalPar() >= alvo && PositionsTotal()> 0)
     {
     
      // Verificar se o par está na lista
      
         for(int i = 0; i < ArraySize(lista_pares); i++) {
             if(Symbol() == lista_pares[i]) {
             
               fecharTodasAsPosicoes(Symbol());
               Print("Função de fechamento ativada");
                             
             }
              
         } 
     
     }

 //Função para fechar as posições
  void fecharTodasAsPosicoes(string par){
      for(int i=PositionsTotal();i>=0;i--)
        {
            ulong ticket = PositionGetTicket(i);
            string symbol = PositionGetSymbol(i);
            
            if(par == symbol)
              {
               trade.PositionClose(ticket);
              }
        }
  }

Fazendo dessa forma ele fecha apenas as operações do mesmo par mantendo as outras. Usando a função _symborl ou Symbol() direto para verificação ele fechava todas operações independente do par de moeda.
  
 
Adilson Albino Pereira #:

Porque voce não entendeu a finalidade de _Symbol ou Symbol(), ambas devolvem o ativo que o EA/script esta colocado. Então, se voce se guiava somente por isso não iria dar certo porque em todos os ativos voce iria testar somente um par. Se aquele par desse certo, todos iam ser encerrados.

Outro ponto, nessa linha aqui

if(ObterLucroTotalPar() >= alvo && PositionsTotal()> 0)

Se tu inverter a testagem faz mais sentido, se tu não tem nenhuma posição não faz sentido chamar ObterLucro. Ja se tu chamou ObterLucro e eh superior ao alvo não teria sentido testar por PositionsTotal()>0 porque tu ja sabe que será verdadeiro. Além disso, as condições em mql5 e mql4 contam com uma caracteristica chamada curto circuito, digamos que a parte da esquerda (antes do &&) fosse falsa, ele nunca que iria testar a parte da direita (depois do &&). Em algumas linguagens isso não é verdade como VB, então tem que ter atenção.

Razão: