Toute question des nouveaux arrivants sur MQL4 et MQL5, aide et discussion sur les algorithmes et les codes. - page 1920

 
MrBrooklin #:

Merci pour le conseil, Alexey ! Je vais d'abord attendre une réponse dans ce fil de discussion, mais si rien ne se passe, je me tournerai vers le fil de discussion Erreurs, bugs, questions.

Sincèrement, Vladimir.

Vous n'obtiendrez aucune réponse des développeurs dans ce fil de discussion. Si vous avez trouvé une erreur, si vous vous êtes assuré qu'il s'agissait bien d'une erreur, signalez-la à la branche représentée par Alexey. Il n'est pas nécessaire d'attendre des modérateurs qu'ils agissent sur ce point - nous sommes aussi des êtres humains, et nous n'avons parfois pas le temps.

 
Artyom Trishkin #:

Il est peu probable que vous obteniez des réponses des développeurs dans ce fil de discussion. Si vous trouvez une erreur, assurez-vous qu'il s'agit bien d'une erreur, signalez-la à la branche d'Alexey. Il n'est pas nécessaire d'attendre des actions de la part des modérateurs à cette occasion - nous sommes aussi des personnes, et nous n'avons pas le temps.

Salut Artem !

Tout est clair.

Sincèrement, Vladimir.

 

Bonjour !!!!

Voici deux fonctions pour le conseiller de la grille : la première fonction est le calcul du profit, en tenant compte de la clôture partielle des ordres perdants.

//+----------------------------------------------------------------------------+
//| Калькуляция сетки ордеров                                                  |
//+----------------------------------------------------------------------------+
bool CalculiteProfit()
  {
   double oProfit=0,oLoss=0,percent;
   int i;
   nOrd=0;
   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic || OrderType()>OP_SELL)
         continue;
      if(OrderProfit()>=0)
         oProfit += OrderProfit();
      else
        {
         oLoss+=OrderProfit();
         Ord_ticket[nOrd]=OrderTicket();
         Ord_lot[nOrd]=OrderLots();
         nOrd++;
        }
     }
   oLoss = MathAbs(oLoss+GetOrderSwap()+GetOrderCommission());
   if(oLoss>0)
      percent=oProfit/oLoss*100;
   else
      percent=100;
   if(percent<MinPercentForClose) //MinPercentForClose переменная из настроек 
      return(false);
   for(i=0; i<nOrd; i++)
     {
      Ord_lot[i]=(MathCeil((Ord_lot[i]*RowLots)*percent)/100)/RowLots;
     }
   return(true);
  }

La deuxième fonction est la fermeture des ordres avec fermeture partielle des ordres non rentables.

//+----------------------------------------------------------------------------+
//| Закрытие сетки ордеров при заданной команде с учетом части ордеров         |
//+----------------------------------------------------------------------------+
void ClosseAll()
  {
   int i,j,tkt;

   for(i = OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i, SELECT_BY_POS, MODE_TRADES) || OrderSymbol()!=Symbol() || OrderMagicNumber()!=Magic)
         continue;
      tkt=OrderTicket();
      RefreshRates();
      if(OrderProfit()>=0)
        {
         if(OrderType() == OP_BUY)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, slip))
               Print("Не удалось закрыть ордера на покупку!");
           }
         else
            if(OrderType() == OP_SELL)
              {
               if(!OrderClose(OrderTicket(), OrderLots(), Ask, slip))
                  Print("Не удалось закрыть ордер на продажу!");
              }
        }
      else
         for(j=0; j<nOrd; j++)
            if(tkt==Ord_ticket[j])
              {
               if(OrderLots()<Ord_lot[j])
                  Ord_lot[j]=OrderLots();
               Ord_lot[j]=NRL(Ord_lot[j]);
               if(OrderType() == OP_BUY)
                 {
                  if(!OrderClose(OrderTicket(), Ord_lot[j], Bid, slip))
                     Print("Не удалось закрыть ордера на покупку!");
                 }
               else
                  if(OrderType() == OP_SELL)
                    {
                     if(!OrderClose(OrderTicket(), Ord_lot[j], Ask, slip))
                        Print("Не удалось закрыть ордер на продажу!");
                    }
               break;
              }
     }
  }

La situation est la suivante : si je ferme une grille d'ordres en tenant compte de la fermeture partielle des ordres perdants, j'obtiens une perte en raison de l'arrondi au plus grand côté de certains lots qui doivent être fermés.

La question est de savoir si vous pouvez utiliser ces deux fonctions pour écrire une fonction de calcul des ordres perdants, ou plutôt une partie d'un ordre à clôturer.

Si oui, aidez-moi à l'écrire.

Merci.

 
EVGENII SHELIPOV #:

Bonjour !!!!

Si oui, aidez-moi à l'écrire.

Ce n'est pas le bon moment.

Vous voulez dire l'écrire pour vous ?

 
Andrey Sokolov #:

Ce n'est pas une bonne époque.

Vous voulez dire écrire pour vous ?

Ne te déchire pas Alexandre

 

perdu dans les affaires élémentaires :

comment organiser une pose de chalut - co-directed, pour une raison quelconque, il trawl une pose, c'est-à-dire qu'il ne trawl pas... MT5

for (i=0; i<PositionsTotal(); i++)   
     if (a_position.Select(_Symbol))       
     if (PositionSelect(_Symbol)) if(Symbol()==PositionGetSymbol(i))  
     if (Magic==PositionGetInteger(POSITION_MAGIC))  
   //  magic = myposition.Magic();   
      {
         //  ------------   перевод в бу  BUY   ------------    
         //if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 
         if (a_position.PositionType() == POSITION_TYPE_BUY)
          if (NLb_fun > 0)
            {
                Print(" перевод в безубыток BUY, _SL = ", _SL, " POSITION_PRICE_OPEN: ",
                     NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits),
                     " NLb_fun = ", NormalizeDouble(NLb_fun,_Digits));
               Modify = true;
 if(Modify)
              {
               Print(" серия рыночных позиций BUY назначена к переводу в безубыток, текущией позы POSITION_PRICE_OPEN = ",
               NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),_Digits)," тикет = ",PositionGetInteger(POSITION_TICKET));
                
               trade.PositionModify(_Symbol,SymbolInfoDouble(_Symbol, SYMBOL_BID) - 50*_Point,PositionGetDouble(POSITION_TP));
               Print(" Перенос в бу стоп лосса позиции Buy № ",  PositionGetInteger(POSITION_TICKET));
    ...
           } // к if(Modify)
        }    // к if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY) 

...

je peux utiliser une simple section de code comme une énumération de positions pour un chalutage avec des positions de marché HEDGE - merci.

le problème est résolu ! Félicitations encore une fois à Vladimir Karputov ! !!

avec son chalut !

https://www.mql5.com/ru/code/17263

l'astuce clé est de regarder l'index dans la boucle et de le modifier avec l'option ticket !!!

//--- при таком методе мы будет сюда попадать на каждом тике.
   for(int i=PositionsTotal()-1;i>=0;i--)
      if(m_position.SelectByIndex(i))
         if(m_position.Symbol()==Symbol() && m_position.Magic()==m_magic)
           {
            //--- TrailingStop -> подтягивание StopLoss у ПРИБЫЛЬНОЙ позиции
            if(m_position.PositionType()==POSITION_TYPE_BUY)
              {
               //--- когда у позиции ещё нет StopLoss
               if(m_position.StopLoss()==0)
                 {
                  //--- пока StopLoss равен 0.0, TrailingStep не учитываем
                  if(m_symbol.Bid()-ExtTrailingStop>m_position.PriceOpen())
                    {
                     //--- модификация позиции
                     m_trade.PositionModify(m_position.Ticket(),m_position.PriceOpen(),0.0);
                    }
                 } 
TrailingStop
TrailingStop
  • www.mql5.com
Пример советника с реализацией Trailing Stop.
 

Une tâche simple : vous devez supprimer tous les éléments du tableau J qui ont le même indice et la même valeur que les éléments du tableau I:

int OnInit()
  {
   int CommonArray[]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 13, 13, 13, 13, 13, 13, 13};
   int ArrayI[20]=   {0, 0, 0, 0, 0, 0, 0, 8, 9, 10,  0, 12, 13, 13, 13, 13,  0,  0, 13,  0};
   int ArrayJ[];

   for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayResize(ArrayJ,j+1);
      ArrayJ[j]=CommonArray[j];
   }

   ArrayPrint(ArrayI);
   ArrayPrint(ArrayJ);

   for(int i=0; i<ArraySize(ArrayI); i++)
      if(ArrayI[i])
         for(int j=0; j<ArraySize(ArrayJ); j++)
            if(ArrayI[i]==ArrayJ[j])
               ArrayRemove(ArrayJ,j,1);

   ArrayPrint(ArrayJ);
//---
   return(INIT_SUCCEEDED);
  }

La chaîne de touches est mise en évidence. Résultat :

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7 11

Attendu :

2022.02.26 13:56:48.489 test (NZDUSD,H4)         0  0  0  0  0  0  0  8  9 10  0 12 13 13 13 13  0  0 13  0
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7  8  9 10 11 12 13 13 13 13 13 13 13 13
2022.02.26 13:56:48.489 test (NZDUSD,H4)         1  2  3  4  5  6  7          11                13 13    13

ArrayJ est dynamique, il semble y avoir quelque chose qui cloche... Mais je n'ai pas besoin non plus d'une statique.

Ça m'a brisé l'esprit. QUOI DE NEUF ? Ou est-ce l'équivalent de la vieille chanson :

https://www.mql5.com/ru/forum/1111/page3141#comment_27152680

и

https://www.mql5.com/ru/forum/1111/page3142#comment_27371998

à propos des constantes nommées ?

Ошибки, баги, вопросы
Ошибки, баги, вопросы
  • 2022.01.28
  • www.mql5.com
Общее обсуждение: Ошибки, баги, вопросы
 
x572intraday éléments du tableau I:

La chaîne de touches est mise en évidence. Résultat :

Attendu :

ArrayJ est dynamique, il semble y avoir quelque chose qui cloche... Mais je n'ai pas besoin non plus d'une statique.

1. il serait préférable de déplacer ArrayResize hors de la boucle.

ArrayResize(ArrayJ,ArraySize(ArrayI));
for(int j=0; j<ArraySize(ArrayI); j++)
   {
      ArrayJ[j]=CommonArray[j];
   }

2. ArrayRemove ne rend pas un élément du tableau "vide", il "déplace" les éléments suivants à sa place. Par conséquent, la correspondance des éléments dans les index ultérieurs est rompue.

 
JRandomTrader #:

1. ArrayResize devrait être déplacé hors de la boucle

2. ArrayRemove ne rend pas un élément du tableau "vide", mais "déplace" les éléments suivants à sa place. Par conséquent, la correspondance des éléments dans les index ultérieurs est rompue.

Il n'y a aucun doute sur le point 2, j'ai juste mis les intervalles ici pour que ce soit plus clair. De plus, dans Help, il est dit à propos d'un tableau statique :"Si la fonction est utilisée pour un tableau de taille fixe, la taille du tableau lui-même ne change pas : la "queue" restante est physiquement copiée à la position de départ."L'exemple dans l'aide utilise également un tableau de taille fixe, alors que j'en ai un dynamique.

Re 1. Nous ne pouvons pas le mettre en dehors d'une boucle, car dans une tâche réelle, nous ne connaissons pas à l'avance la taille de ArrayJ ou ArrayI, et encore moins celle de CommonArray, puisqu'ils ne coïncident pas tous.

J'ai aussi un exemple où le fait de mélanger les éléments ne casse pas la moitié du chemin, comme dans cet exemple :

int OBJTFVArray[]={1, 2, 3, 4, 5, 6, 10, 12, 1520, 30, 16385, 16386, 16387, 16388, 16390, 16392, 16396, 16408, 32769, 49153, 49154, 49155, 49156, 49157, 49158, 49159, 49160};
int PArray[20]={0, 0, 0, 0, 0, 00, 16390, 16392, 163960, 32769, 49153, 49153, 49153, 49153, 0, 0, 49153, 0};
int PArray_[];

int OnInit()
  {
   for(int p_=0; p_<ArraySize(PArray); p_++)
   {
      ArrayResize(PArray_,p_+1);
      PArray_[p_]=OBJTFVArray[p_+8];
   }

   ArrayPrint(PArray);
   ArrayPrint(PArray_);

   for(int p=0; p<ArraySize(PArray); p++)
      if(PArray[p])
         for(int p_=0; p_<ArraySize(PArray_); p_++)
            if(PArray[p]==PArray_[p_])
               ArrayRemove(PArray_,p_,1);

   ArrayPrint(PArray_);

   return(INIT_SUCCEEDED);
  }

Le résultat est bon :

 0     0     0     0     0     0     0 16390 16392 16396     0 32769 49153 49153 49153 49153     0     0 49153     0
15    20    30 16385 16386 16387 16388 16390 16392 16396 16408 32769 49153 49154 49155 49156 49157 49158 49159 49160
15    20    30 16385 16386 16387 16388                   16408             49154 49155 49156 49157 49158 49159 49160

Mais vous avez besoin de cette variante pour fonctionner. Le problème se produit apparemment si des éléments ayant la même valeur (voir le message précédent) se trouvent dans la queue à droite - ce qui est similaire au problème auquel je faisais référence ci-dessus.

 
x572intraday #:

Il n'y a pas de questions sur le 2, je mets les intervalles pour plus de clarté. En outre, dans l'aide, il est dit à propos des tableaux statiques :"Si la fonction est utilisée pour un tableau de taille fixe, la taille du tableau lui-même ne change pas : elle copie physiquement la "queue" restante à la position de départ."L'exemple dans l'aide utilise également un tableau de taille fixe, alors que j'en ai un dynamique.

Re 1. Nous ne pouvons pas le mettre en dehors d'une boucle, car dans une tâche réelle, nous ne connaissons pas à l'avance la taille de ArrayJ ou ArrayI, et encore moins celle de CommonArray, puisqu'ils ne coïncident pas tous.

J'ai également un exemple où le fait de mélanger les éléments ne casse pas la moitié du chemin, comme dans cet exemple :

Le résultat est bon :

Mais j'ai besoin de cette variante pour fonctionner. Le problème se produit apparemment s'il y a des éléments avec la même valeur dans la queue à droite (voir le post précédent) - ce qui est similaire au problème que j'ai mentionné ci-dessus.

1. Vous pouvez et devez le retirer de la boucle, comme je l'ai montré. Sauf si la taille de l'ArrayI change au cours de la boucle.

2. Puis quelque chose comme ceci

int k=0; // объявляем до цикла - чтобы использовать после
for(int i=0; i<ArraySize(ArrayI); i++) // после предыдущего кода (1) размеры ArrayI и ArrayJ равны
  if(ArrayI[i]!=ArrayJ[i])
    {
     ArrayJ[k++]=ArrayI[i];
    }
ArrayResize(ArrayJ,k);