Questions des débutants MQL5 MT5 MetaTrader 5 - page 1207

 

mql5 (couverture)

Comment mettre en œuvreun algorithme de clôture des positions sous deux conditions ?

1 caisse. S'il y a 2 positions ouvertes, alors fermez celle qui a plus de profit que... 2 cas. S'il y a 2 positions ouvertes ou plus, alors fermez en faisant la moyenne de la valeur de...

J'ai maintenant deux méthodes pour fermer ces positions,

Pour le cas 1, comparez les positions en fonction des bénéfices et fermez celle qui a le plus de bénéfices, pour le cas 2, fermez toutes les positions en fonction de l'équité, en faisant la moyenne.

Ces méthodes fonctionnent bien séparément, mais pas ensemble, car l'un des deux événements tombe sous la distribution des deux méthodes.

Je n'arrive pas à les séparer. En conséquence, les deux cas sont fermés principalement sur l'équité avec la fermeture de toutes les positions. Cela conduit au fait que, dans le premier cas, la position souhaitée est supprimée et rouverte.

En conséquence. Double écart, double commission. C'est frustrant))))

Le schéma d'établissement des ordres et des positions se présente comme suit Pour VENDRE (et ensuite seulement pour VENDRE).

Ordre limite. SELL_LIMIT

position. VENDRE(toujours entre deux ordres)

Ordre d'arrêt.SELL_STOP

Je joins le tableau.

Fermeture de postes.

Si un ordre stop est déclenché, c'est-à-dire si deux positions ou plus apparaissent en même temps, vous devez fermer une position dont le bénéfice est supérieur à celui de la position... (20)

2. si un ordre Limit s'est déclenché, c'est-à-dire que deux positions ou plus sont ouvertes simultanément, leur valeur moyenne (par Equity) doit être fermée... (15)

Question. Comment séparer ces deux méthodes, afin qu'elles ne traitent que leur propre événement ?

Peut-être existe-t-il une autre méthode pour gérer ces deux conditions ?

Exemples de méthodes que j'utilise.

//+---------------------------------------------------------------------+
//|  -- ЗАКРЫВАЕМ ОДНУ ИЗ ДВУХ ПОЗИЦИЙ С НИЗУ, ГДЕ ПРОФИТ БОЛЬШЕ ЧЕМ ---|
//+---------------------------------------------------------------------+ 
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
Торговая деятельность в платформе связана с формированием и отсылкой рыночных и отложенных ордеров для исполнения брокером, а также с управлением текущими позициями путем их модификации или закрытия. Платформа позволяет удобно просматривать торговую историю на счете, настраивать оповещения о событиях на рынке и многое другое. Открытие позиций...
Dossiers :
 
Vladpedro:


Les positions sont-elles ouvertes par le symbole sur lequel l'EA fonctionne ? Le numéro magique est-il utilisé ?
 
Vladimir Karputov:
Les positions sont-elles ouvertes par le symbole sur lequel l'EA fonctionne ? Le numéro magique est utilisé

Oui, par le symbole actuel. Oui, la magie est utilisée.

 
Vladpedro:

Oui, par le personnage actuel. Oui, la magie est utilisée.

Expliquez la deuxième condition, qu'est-ce qu'elle signifie ?(Si 2 positions ou plus sont ouvertes, alors fermez en faisant la moyenne de la valeur... )

 
Vladimir Karputov:

Expliquez la deuxième condition, qu'est-ce qu'elle signifie ?(Si 2 positions ou plus sont ouvertes, fermez en faisant la moyenne sur la valeur... )

Cela signifie que si deux positions ou plus sont ouvertes et que l'équité est supérieure au solde par une valeur quelconque (disons 15), alors toutes les positions sont fermées.

Par exemple, trois positions sont ouvertes. La première a une perte actuelle de -10, la deuxième a un profit de -5, la troisième a un profit de +30 et un total de +15, toutes les positions peuvent être fermées.

Si un profit moyen de +15 n'a pas été atteint, les positions seront fermées par leur propre SL ou TP prédéfini. (Il s'agit en quelque sorte de la troisième condition de fermeture des positions, mais comme elle ne pose aucun problème, je l'ai omise).

 
Vladpedro:

Cela signifie que si deux positions ou plus sont ouvertes et que l'équité est supérieure au solde d'une valeur quelconque (disons 15), alors toutes les positions seront fermées.

Par exemple, trois positions sont ouvertes. La première a une perte actuelle de -10, la deuxième a un bénéfice de -5, la troisième a un total de +30+ de +15, toutes les positions peuvent être fermées.

Si un profit moyen de +15 n'a pas été atteint, les positions seront fermées par leur propre SL ou TP prédéfini. (il s'agit en quelque sorte de la troisième condition pour la fermeture des positions, mais elle ne pose aucun problème, c'est pourquoi je l'ai omise).

Voici le code complet pour deux conditions :

//+------------------------------------------------------------------+
//|                                       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
  }
//+------------------------------------------------------------------+
Dossiers :
 
Vladimir Karputov:

Voici le code complet pour les deux conditions :

Merci Vladimir, je vais essayer de trouver une solution.

J'ai essayé de le résoudre à ma façon, je comprends comment on peut séparer ces deux conditions.

Par exemple.

Déclarons trois variables logiques.

Pos_1 ;

Pos_2_Clos_1 ;

Pos_2_Clos_All ;

1. Vérifiez le nombre de postes ouverts.

Si nous n'avons qu'une seule position ouverte, SELL est réglé sur :

Pos_1=true ; Pos_2_Clos_1=false; Pos_2_Clos_All=false;

S'il y a 2 positions ouvertes et que le montant des capitaux propres est positif (cela ne peut se produire que lorsque l'ordre SELL_STOP se déclenche), attribuez une valeur logique à cet événement.

Pos_1=false ; Pos_2_Clos_1=true; Pos_2_Clos_All=false ;

Si 2 positions sont ouvertes et que le montant des capitaux propres est négatif (cela ne peut se produire que lorsqu'un ordre SELL_LIMIT se déclenche), alors

Pos_1=false ; Pos_2_Clos_1=false; Pos_2_Clos_All=true;

Cela semble être tout... Vous pouvez vérifier les variables logiques et les affecter à votre méthode de fermeture, mais cela n'a pas fonctionné pour moi...

Je suis pourtant un piètre programmeur, j'ai peut-être fait une erreur quelque part...

Merci pour votre aide)

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

Vladimir Karputov:

Vladimir, j'ai des problèmes avec cela. Lorsque les ordres SELL_STOP se déclenchent, tout est OK. Seule une position avec un plus grand profit est fermée,

Mais lorsque SELL_LIMIT est déclenché, tout est fermé de manière incorrecte, pas par la somme de toutes les positions ouvertes, mais il semble que la position avec le plus grand profit soit fermée.

J'avais une erreur similaire avant, maintenant je commence à penser, peut-être que c'est ma faute, peut-être que je ne calcule pas et n'ouvre pas les positions correctement.

Veuillez examiner mon code prêt à être testé et voyez si vous avez des erreurs, mais peut-être y a-t-il aussi des incohérences dans votre code, ou peut-être ne les ai-je pas expliquées correctement... Quel est le bénéfice moyen pour moi ?

J'ai commencé à analyser l'algorithme maintenant et je me suis rendu compte qu'il est un peu plus compliqué dans ses conséquences que ce que je vous ai dit auparavant.

La troisième condition, lorsque vous fermez une position par son SL, peut provoquer des erreurs dans l'algorithme des deux premières conditions.

Je vais à nouveau décrire l'algorithme complet de fermeture de position uniquement pour le cas SELL_LIMIT puisque le cas SEL_STOP est exécuté correctement. Laissons cela pour l'instant.

1. Nous avons initialement une position ouverte SELL qui a un SL spécifié mais qui est supérieur à SELL_LIMIT, ce qui signifie que le SL ne sera pas activé avant SELL_LIMIT.

2. SELL_LIMIT s'est déclenché et il existe une deuxième position SELL avec sa propre SL, qui ne pourra pas non plus être clôturée avant la prochaine SELL_LIMIT.

Si l'ordre SELL_LIMIT a été déclenché, un nouvel ordre SELL_LIMIT a été placé. (toujours)

4. Le nombre de positions ouvertes SELL_LIMIT peut être de1 à 3 ou plus, tout dépend de la distance qui sépare les positions SL. Envisagez le cas où il y a un maximum de trois. (Je peux limiter cela à SL)

Maintenant, les scénarios de fermeture des positions.

Si des postes sont ouverts. 2, seuls deux scénarios sont possibles pour fermer une ou toutes les positions

1. Par Equity, s'il est supérieur au solde de 15(toutes les positions sont fermées), (m_account.Equity()>= m_account.Balance()+15) je voulais dire fermer plusieurs positions en faisant la moyenne.

2. Par propre SL (une position est fermée).

3. la position restante doit maintenant être libérée des conditions de fermeture si elles ont été fixées auparavant, car nous ne savons pas quelle condition lui appliquer.

Il peut répéter le scénario SELL_LIMIT, ou descendre à SEL_STOP et aller vers une autre condition de clôture.

4. S'il y avait trois positions, nous les fermons également (m_compte.Equity()>= m_compte.Balance()+15) ou l'une d'entre elles déclenchera le SL et il restera deux positions.

Appliquez cette règle jusqu'à ce qu'il reste un poste pour lequel aucune condition de clôture n'a été définie...

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

Vladimir Karputov:

Vladimir, j'ai un problème avec cela. Lorsque mon ordre SELL_STOP se déclenche, tout est OK. Seule une position avec un plus grand profit est fermée,

Mais lorsque SELL_LIMIT est déclenché, l'ordre se ferme de manière incorrecte, non pas en fonction de la somme de toutes les positions ouvertes, mais semble fermer la position avec le bénéfice le plus élevé.

J'avais une erreur similaire avant, maintenant je commence à penser, peut-être que c'est ma faute, peut-être que je ne calcule pas et n'ouvre pas les positions correctement.

Veuillez examiner mon code prêt à tester et voir si vous avez des erreurs, mais peut-être que votre code ne remplit pas les conditions. Ou peut-être que je ne les ai pas expliquées correctement... quel est le profit moyen pour moi.

En général, l'ordre en suspens qui se déclenche n'a pas d'importance - en fait, nous nous retrouvons avec une position et nous calculons ensuite le profit de la position.

 
Vladimir Karputov:

Cela ne fait aucune différence de savoir quel ordre en attente a été déclenché - après tout, nous obtenons une position et nous comptons ensuite le bénéfice de la position.

Cela ne fait aucune différence. Je soupçonne qu'il y a une différence, car lors de la définition des ordres et des positions, je leur ai attribué des "commentaires" propres aux positions et propres aux ordres. Par conséquent, lorsqu'un ordre se déplace vers une position, il hérite du commentaire de l'ordre.

Ensuite, lorsque nous avons vérifié les positions à travers les commentaires, il y avait un désordre... les commentaires étaient différents. J'ai corrigé cela.

Je n'ai pas trouvé dans votre code, ou ne comprends pas comment les positions sont fermées pour la condition SELL_LIMIT déclenchée par Equity.

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;
        }
        }

Il semble que nous ayons vérifié si toutes les positions peuvent être fermées, et que le drapeau soit activé pour cela.

mais dans leCloseAllPositions() ;

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

il manque quelque chose.

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

Il n'y a pas de vérification de la fermeture de toutes les positions pour le cas - SELL_LIMIT s'est déclenché.

Peut-être que ce mêmem_compte.Equity()>= m_compte.Balance()+15est implémenté d'une autre manière ?

Ou peut-être que c'est parce que je n'ai pas expliqué la moyenne de la mauvaise manière.

Raison: