Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 1207

 

mql5 (sebe)

Como implementarum algoritmo de fecho de posições sob duas condições?

1 caso. Se houver 2 posições abertas, então feche a que tiver mais lucro do que... 2 caixas. Se houver 2 ou mais posições em aberto, então fecha-se, calculando a média sobre o valor de...

Agora tenho dois métodos para fechar estas posições,

Para 1 caso, comparar posições por lucro e fechar a que tiver mais lucro, para 2 casos fechar todas as posições por Equidade, calculando a média.

Estes métodos funcionam bem separadamente, mas não em conjunto, porque um de dois eventos recai sobre a distribuição de ambos os métodos.

Não consigo separá-los. Como resultado, ambos os casos são encerrados na sua maioria em Equidade, com o encerramento de todas as posições. Isto leva a que, no primeiro caso, a posição desejada seja eliminada e reaberta.

Como resultado. Dupla propagação, dupla comissão. É frustrante))))

O esquema de fixação de ordens e posições tem este aspecto: Para VENDER (e ainda só para VENDER).

Ordem de limite. SELL_LIMIT

posição. VENDA(sempre entre encomendas)

Parar a ordem.SELL_STOP

Estou a anexar o gráfico.

Encerramento de posições.

1. se uma ordem de paragem for accionada, ou seja, duas ou mais posições aparecem ao mesmo tempo, deve fechar uma posição que tenha um lucro mais elevado do que... (20)

2. Se uma ordem Limitada tiver desencadeado, ou seja, duas ou mais posições forem abertas simultaneamente, o seu valor médio (por Equidade) deve ser fechado... (15)

Pergunta. Como separar estes dois métodos, de modo a que apenas tratassem do seu próprio evento?

Talvez haja algum outro método para lidar com estas duas condições?

Exemplos de métodos que eu utilizo.

//+---------------------------------------------------------------------+
//|  -- ЗАКРЫВАЕМ ОДНУ ИЗ ДВУХ ПОЗИЦИЙ С НИЗУ, ГДЕ ПРОФИТ БОЛЬШЕ ЧЕМ ---|
//+---------------------------------------------------------------------+ 
ulong ticket_n=ULONG_MAX;  double profit=DBL_MIN;

     if(invert_close == true) //Проверка на наличие 2х и более поз.
     {
     int positions=PositionsTotal();
     for(int i=PositionsTotal()-1; i>=0; i--)
     {
     ulong tmp_ticket=PositionGetTicket(i);
     if(ticket_n!=0)
     {
     double tmp_profit=PositionGetDouble(POSITION_PROFIT);
     if(tmp_profit>profit+Prof_eqw_niz)// допустим 20
     {
     ticket_n=tmp_ticket;
     profit=tmp_profit;
     }
     }
     }
//-----------
     if(ticket_n!=ULONG_MAX)
     m_trade.PositionClose(ticket_n);
     invert_close = false;
     Print("------  ЗАКРЫЛИ ТОЛСТУЮ ---------");
     }       

//+---------------------------------------------------------------------+
//|                     Э К В И Т И   ДЛЯ SELL_LIMIT                    |
//+---------------------------------------------------------------------+
   npos_ALL=0; NPos_ALL(npos_ALL);
   if (npos_ALL>=Metod_Eqw && m_account.Equity()>= m_account.Balance()+Prof_eqw)//Допустим 15
   {
   CloseAllPositions();
   Print("------  ЗАКРЫЛИ ВСЕ ---------");
   }
Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Arquivos anexados:
 
Vladpedro:


As posições são abertas pelo símbolo sobre o qual a EA trabalha? É usado o número mágico?
 
Vladimir Karputov:
As posições são abertas pelo símbolo sobre o qual a EA trabalha? O número mágico é utilizado

Sim, pelo símbolo actual. Sim, é utilizado o magik.

 
Vladpedro:

Sim, pelo carácter actual. Sim, é utilizado o magik.

Explicar a segunda condição, o que significa?(Se 2 ou mais posições estiverem abertas, então feche fazendo uma média sobre o valor... )

 
Vladimir Karputov:

Explicar a segunda condição, o que significa?(Se 2 ou mais posições estiverem abertas, fechar fazendo a média sobre o valor... )

Significa: Se duas ou mais posições estiverem abertas e o Património for superior ao saldo por qualquer valor (digamos 15), então todas as posições são fechadas.

Por exemplo, três posições são abertas. A primeira tem uma perda corrente de -10, a segunda tem um lucro de -5, a terceira tem um lucro de +30 e total de +15, todas as posições podem ser fechadas.

Se não tiver sido alcançado um lucro médio de +15, as posições serão fechadas pelas suas próprias SL ou TP pré-definidas. (Esta é uma espécie de terceira condição para fechar posições, mas não há problemas com ela, por isso omiti-a).

 
Vladpedro:

Isto significa: Se duas ou mais posições estiverem abertas e o Património for superior ao saldo por qualquer valor (digamos 15), então todas as posições serão fechadas.

Por exemplo, três posições estão abertas. A primeira tem uma perda corrente de -10, a segunda tem um lucro de -5, a terceira tem um total de +30+ de +15, todas as posições podem ser fechadas.

Se não tiver sido alcançado um lucro médio de +15, as posições serão fechadas pelas suas próprias SL ou TP pré-definidas. (esta é mais ou menos a terceira condição para fechar posições, mas não há problemas com ela, por isso omiti-a).

Aqui está o código completo para duas condições:

//+------------------------------------------------------------------+
//|                                       Closing Two conditions.mq5 |
//|                              Copyright © 2020, Vladimir Karputov |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2020, Vladimir Karputov"
#property version   "1.00"
/*
   barabashkakvn Trading engine 3.116
*/
#include <Trade\PositionInfo.mqh>
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
//---
CPositionInfo  m_position;                   // object of CPositionInfo class
CTrade         m_trade;                      // object of CTrade class
CSymbolInfo    m_symbol;                     // object of CSymbolInfo class
//--- input parameters
input double   InpProfitTarget      = 15;       // Profit target, in deposit money (if Positions > 2)
input ulong    InpDeviation         = 10;       // Deviation, in points (1.00045-1.00055=10 points)
input ulong    InpMagic             = 200;      // Magic number
//---
bool     m_need_close_all           = false;    // close all positions
ulong    m_need_close_ticket        = ULONG_MAX;// close one position
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(!m_symbol.Name(Symbol())) // sets symbol name
     {
      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");
      return(INIT_FAILED);
     }
//---
   m_trade.SetExpertMagicNumber(InpMagic);
   m_trade.SetMarginMode();
   m_trade.SetTypeFillingBySymbol(m_symbol.Name());
   m_trade.SetDeviationInPoints(InpDeviation);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(m_need_close_all)
     {
      if(IsPositionExists())
        {
         CloseAllPositions();
         return;
        }
      else
         m_need_close_all=false;
     }
//---
   if(m_need_close_ticket!=ULONG_MAX)
     {
      //--- close one position
      if(m_position.SelectByTicket(m_need_close_ticket))
        {
         m_trade.PositionClose(m_need_close_ticket); // close a position
         return;
        }
      else
         m_need_close_ticket=ULONG_MAX;
     }
//--- calculate all positions
   int total=0;
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            total++;

   if(total==2)
     {
      //--- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
         if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
            if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
              {
               double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
               if(profit>tmp_profit)
                 {
                  tmp_profit=profit;
                  tmp_ticket=m_position.Ticket();
                 }
              }
      //---
      if(tmp_ticket!=ULONG_MAX)
         m_need_close_ticket=tmp_ticket;
     }
   else
     {
      if(total>2)
        {
         //--- conditon 2
         double profit=0;
         for(int i=PositionsTotal()-1; i>=0; i--)
            if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
               if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
                  profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
         //---
         if(profit>=InpProfitTarget)
            m_need_close_all=true;
        }
     }
  }
//+------------------------------------------------------------------+
//| Is position exists                                               |
//+------------------------------------------------------------------+
bool IsPositionExists(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            return(true);
//---
   return(false);
  }
//+------------------------------------------------------------------+
//| Close all positions                                              |
//+------------------------------------------------------------------+
void CloseAllPositions(void)
  {
   for(int i=PositionsTotal()-1; i>=0; i--) // returns the number of current positions
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
            m_trade.PositionClose(m_position.Ticket()); // close a position by the specified m_symbol
  }
//+------------------------------------------------------------------+
Arquivos anexados:
 
Vladimir Karputov:

Aqui está o código completo para as duas condições:

Obrigado Vladimir. Vou tentar descobrir.

Tentei resolvê-lo à minha maneira, compreendo como se pode separar estas duas condições.

Por exemplo.

Vamos declarar três variáveis lógicas.

Pos_1;

Pos_2_Clos_1;

Pos_2_Clos_All;

1. Verificar o número de posições em aberto.

Se tivermos apenas 1 posição em aberto SELL está definido para :

Pos_1=verdadeiro ; Pos_2_Clos_1=falso; Pos_2_Clos_All=falso;

Se houver 2 posições abertas e o montante de capital próprio for positivo (isto só pode ocorrer quando a ordem SELL_STOP é accionada), atribuir um valor lógico a este evento

Pos_1=falso ; Pos_2_Clos_1=verdadeiro; Pos_2_Clos_All=falso;

Se forem abertas 2 posições e o montante de capital próprio for negativo (isto só pode ocorrer quando uma ordem de SELL_LIMIT é accionada), então

Pos_1=falso ; Pos_2_Clos_1=falso; Pos_2_Clos_All=verdadeiro;

Isso parece ser tudo... Pode verificar variáveis lógicas e atribuí-las ao seu próprio método próximo, mas por alguma razão não funcionou para mim...

Ainda sou um péssimo programador, talvez tenha cometido um erro algures...

Obrigado pela ajuda)

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
 

Vladimir Karputov:

Vladimir, estou a ter problemas com isto. Quando as ordens SELL_STOP são accionadas, tudo está bem. Apenas uma posição com maior lucro está a ser fechada,

Mas quando SELL_LIMIT é accionado, tudo é fechado incorrectamente, não pela soma de todas as posições abertas mas parece que a posição com o lucro mais elevado está a ser fechada.

Tive um erro semelhante antes, agora começo a pensar, talvez a culpa seja minha, talvez não calcule e abra posições correctamente.

Por favor, reveja o meu código pronto a testar e veja se tem erros, mas talvez também haja algumas inconsistências no seu código, ou talvez eu não as tenha explicado correctamente... Qual é o lucro médio para mim?

Comecei agora a analisar o algoritmo e apercebi-me de que é um pouco mais complicado nas suas consequências do que vos tinha dito antes.

A terceira condição quando se fecha uma posição pelo seu SL pode causar erros no algoritmo das duas primeiras condições.

Descreverei mais uma vez o algoritmo completo de fecho de posição apenas para o caso SELL_LIMIT, uma vez que o caso SEL_STOP é executado correctamente. Vamos deixá-lo por agora.

1. Inicialmente temos uma posição aberta SELL que especificou SLL_LIMIT, mas é superior à SELL_LIMIT, o que significa que SL não vai ser activada antes de SELL_LIMIT.

2. SELL_LIMIT desencadeou e há uma segunda posição SELL com o seu próprio SL, que também não poderá fechar antes do próximo SELL_LIMIT

Se a ordem SELL_LIMIT foi accionada, uma nova ordem SELL_LIMIT foi colocada. (sempre)

4. O número de posições em aberto SELL_LIMIT pode ser de1-3 ou mais, tudo depende de quão longe se encontram SL. Considere o caso se houver um máximo de três. (Posso limitar isto ao SL)

Agora os cenários de encerramento de posições.

Se posições em aberto. 2, apenas dois cenários são possíveis para fechar uma ou todas as posições

1. Por Equidade, se for mais do que saldo em 15(todas as posições estão fechadas), (m_account.Equity()>= m_account.Balance()+15) Eu pretendia fechar várias posições calculando a média.

2. Por SL próprio (uma posição é fechada).

3. A restante posição, agora tem de ser libertada das condições de encerramento, se estas foram estabelecidas antes, porque não sabemos qual a condição a aplicar-lhe.

Pode repetir o cenário SELL_LIMIT, ou pode descer a SEL_STOP e ir para outra condição próxima.

4. Se houvesse três posições, também as fecharíamos (m_account.Equity()>= m_account.Balance()+15) ou uma delas desencadeará SL e duas posições permanecerão.

Aplicar esta regra até restar uma posição, para a qual não tenham sido definidas condições de fecho.

Совершение сделок - Торговые операции - Справка по MetaTrader 5
Совершение сделок - Торговые операции - Справка по MetaTrader 5
  • www.metatrader5.com
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Arquivos anexados:
 
Vladpedro:

Vladimir Karputov:

Vladimir, estou a ter problemas com isto. Quando as ordens SELL_STOP são accionadas, tudo está bem. Apenas uma posição com maior lucro está a ser fechada,

Mas quando SELL_LIMIT é accionado, a ordem está a fechar incorrectamente, não pela soma de todas as posições abertas, mas parece estar a fechar a posição com o maior lucro.

Tive um erro semelhante antes, agora começo a pensar, talvez a culpa seja minha, talvez não calcule e abra posições correctamente.

Por favor, reveja o meu código pronto a testar e veja se consegue encontrar erro, mas talvez haja inconsistência no seu código e condições. Ou talvez eu não as tenha explicado correctamente... qual é o lucro médio para mim.

Em geral, não importa qual a ordem pendente que desencadeia - de facto, acabamos por ter uma posição e depois calculamos o lucro da posição.

 
Vladimir Karputov:

Não faz qualquer diferença que a ordem pendente tenha desencadeado - afinal de contas, obtemos uma posição e depois contamos o lucro da posição

Não faz qualquer diferença. Tenho uma suspeita de que existe uma diferença porque ao estabelecer ordens e posições, atribuí-lhes "comentários" meus a posições e os meus a ordens. Como resultado, quando uma ordem passa para uma posição, ela herda o comentário da ordem.

Depois, quando verificámos as posições através de comentários, houve uma confusão... os comentários eram diferentes. Eu corrigi isso.

Não encontrei no vosso código, ou não compreendo como as posições estão fechadas para a condição SELL_LIMIT desencadeada pela Equidade.

if(total==2)
   {
//-------------------------------------------------------- conditon 1
      ulong tmp_ticket=ULONG_MAX;
      double tmp_profit=DBL_MIN;
      for(int i=PositionsTotal()-1; i>=0; i--)
      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
      if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
      {
      double profit=m_position.Commission()+m_position.Swap()+m_position.Profit();
      if(profit>tmp_profit)
      {
      tmp_profit=profit;
      tmp_ticket=m_position.Ticket();
      }
      }
      //---
      if(tmp_ticket!=ULONG_MAX)
      m_need_close_ticket=tmp_ticket;
      }
      else
      {
      if(total==2)
        {
//--------------------------------------------------------- conditon 2
        double profit=0;
        for(int i=PositionsTotal()-1; i>=0; i--)
        if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties
        if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)
        profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();
//--------
       if(profit>=InpProfitTarget)
        m_need_close_all=true;
        }
        }

Parece que verificámos se todas as posições podem ser fechadas, e se a bandeira está colocada para o efeito

mas noCloseAllPositions();

if(m_need_close_all)
   {
   if(IsPositionExists())
   {
   CloseAllPositions();
   return;
   }
   else
   m_need_close_all=false;
   }

falta qualquer coisa.

 if(m_account.Equity()>= m_account.Balance()+15)

Não há verificação para fechar todas as posições para o caso - SELL_LIMIT desencadeou

Talvez esta mesmam_account.Equity()>= m_account.Balance()+15é implementada de alguma outra forma?

Ou talvez seja porque interpretei mal o que eu quis dizer com "média".

Razão: