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

 
Vitaly Muzichenko:

Eh bien, vous avez montré les erreurs non critiques.

Comment fonctionne la fonction, vous avez répondu vous-même :


Dans le testeur, tout va bien. C'est ainsi que cela fonctionne dans la pratique.
Dossiers :
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
Dans le testeur, c'est bon. C'est ainsi que cela fonctionne dans la pratique.

Dans ce cas, vous devez traiter le code, imprimer( Print(...) ) toutes les valeurs et voir d'où provient l'erreur.

 
Tigerfreerun:
Dans le testeur, tout va bien. C'est ainsi que cela fonctionne dans la pratique.

Tu viens d'avoir ta réponse :

Forum sur le trading, les systèmes de trading automatisés et les tests de stratégies de trading

Toutes les questions des débutants sur MQL4, aide et discussion sur les algorithmes et les codes

Alexey Viktorov, 2018.09.06 21:00

Sens de la réflexion : Si le bénéfice est inférieur à zéro... quelle sera la taille du tableau lors du tri ? ??

Et quelle est la taille du tableau s'il n'y a pas d'ordres du tout ???
Pensez à ce que serait la taille du tableau triable a[][2] dans la première dimension si tous les bénéfices ne sont PAS supérieurs à zéro.
 

Bonjour, l'EA s'appelle "Rollover", mais il ne fonctionne pas comme prévu. Il double le lot s'il ferme en moins, mais la fermeture ultérieure du TP pour une raison quelconque ne permet pas de retourner les trades en moins, qui ont été fermés avant. Veuillez me dire ce qui ne va pas, je n'arrive pas à comprendre. Je voudrais poser ma question en espagnol.

extern string TimeStart    = "04:00";  //Время начала контрольного периода
extern string TimeEnd      = "09:00";  //Время окончания контрольного периода
extern string TimeCloseOrder = "23:30";//Время в которое происходит закрытие всех ордеров
extern double LOT          = 0.1;
extern int    Magic        = 777;
extern double K_martin     = 2;
extern bool   No_Loss      = true;
int slippage = 3;
double marga,Lot,SL,TP;
int tip,Orders,tipOrders,TradeDey;
//-------------------------------------------------------------------+
int init()
{
   if (Digits==5 || Digits==3) slippage = 30;
}
int start()
{
   datetime Time_Start      = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeStart,     ":00"));
   datetime Time_End        = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeEnd,       ":00"));
   datetime Time_CloseOrder = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeCloseOrder,":00"));

   if (Time_CloseOrder>Time_End) if (CurTime()>=Time_CloseOrder) CLOSEORDERS();

   int tip;
   if (Orders>OrdersTotal()) tip=CloseOrder();
   Orders=OrdersTotal();

   if (ORDERS(0)==0 && tip==0 && (CurTime()<Time_CloseOrder || Time_CloseOrder<=Time_End) && TradeDey!=TimeDay(CurTime()))
   {
      int BarStart = iBarShift(NULL,0,Time_Start,false);
      int BarEnd   = iBarShift(NULL,0,Time_End  ,false);
      double Max_Price=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,BarStart-BarEnd,BarEnd));
      double Min_Price=iLow (NULL,0,iLowest (NULL,0,MODE_LOW, BarStart-BarEnd,BarEnd));
   
      if (TimeCurrent()>Time_End && ObjectFind("bar0"+Time_End)==-1)
      {
         ObjectCreate("bar0"+Time_End, OBJ_RECTANGLE, 0, 0,0, 0,0);
         ObjectSet   ("bar0"+Time_End, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet   ("bar0"+Time_End, OBJPROP_COLOR, Blue);
         ObjectSet   ("bar0"+Time_End, OBJPROP_BACK,  true);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME1 ,Time_Start);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE1,Max_Price);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME2 ,Time_End);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE2,Min_Price);
      }
      
      if (Bid>Max_Price) OrderSend(Symbol(),OP_BUY,LOT,Bid,slippage,Min_Price,
         NormalizeDouble(Ask + Max_Price-Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      if (Bid<Min_Price) OrderSend(Symbol(),OP_SELL,LOT,Bid,slippage,Max_Price,
         NormalizeDouble(Bid - Max_Price+Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      return;
   }
   if (No_Loss) No_Loss();
   if (tip==1 && TradeDey!=TimeDay(CurTime()))
   {
      Lot=Lot*K_martin;
      if (tipOrders==0) OrderSend(Symbol(),OP_SELL,Lot,Bid,slippage,SL,TP,"Nevalyashka",Magic,Blue);
      if (tipOrders==1) OrderSend(Symbol(),OP_BUY ,Lot,Ask,slippage,SL,TP,"Nevalyashka",Magic,Blue);
   }
   return(0);
}
//-------------------------------------------------------------------+
int CloseOrder()
{
   string txt;
   double loss;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
      {
         tipOrders=OrderType();
         Lot=OrderLots();
         loss = MathAbs(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)/Lot/K_martin);
         if (tipOrders==0)
         {
            TP=NormalizeDouble(Bid - loss*Point,Digits);
            SL=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (tipOrders==1)
         {
            SL=NormalizeDouble(Bid - loss*Point,Digits);
            TP=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (OrderClosePrice()==OrderTakeProfit() || OrderProfit()>=0) TradeDey=TimeDay(CurTime());
         if (OrderClosePrice()==OrderStopLoss()) return(1);
      }
   }  
   return(0);
}
//+-----------------------------------------------------------------+
int ORDERS(int tip)
{
   int N_Sell,N_Buy;
   for (int i=0; i<OrdersTotal(); i++)
   {                                               
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
         {
            if (OrderType()==OP_BUY ) N_Buy++;
            if (OrderType()==OP_SELL) N_Sell++;
         }
      }   
   }
if (tip== 0) return(N_Buy+N_Sell);
if (tip== 1) return(N_Buy);
if (tip==-1) return(N_Sell);
}                  
//-------------------------------------------------------------------+
void No_Loss()
{
   int tip;
   double TP,OOP;
   for (int i=OrdersTotal()-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS)==true)
      {
         tip = OrderType();
         if (tip<2 && OrderSymbol()==Symbol())
         {
            if (OrderMagicNumber()!=Magic) continue;
            TP = OrderTakeProfit();
            OOP = OrderOpenPrice();
            if (tip==0) //Bay               
            {  
               if (OrderStopLoss()>OrderOpenPrice()+Ask-Bid) return;
               if ((TP-OOP)/2+OOP<=Bid)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP+Ask-Bid,Digits),TP,0,White);
            }                                         
            if (tip==1) //Sell               
            {                                         
               if (OrderStopLoss()<OrderOpenPrice()-Ask+Bid) return;
               if (OOP-(OOP-TP)/2>=Ask)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP-Ask+Bid,Digits),TP,0,White);
            } 
         }
      }
   }
}
//------------------------------------------------------------------+
void CLOSEORDERS()
{
   bool error;
   int err;
   while (true)
   {  error=true;
      for (int i=OrdersTotal()-1; i>=0; i--)
      {                                               
         if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
         {
            if (OrderSymbol()!=Symbol()||Magic!=OrderMagicNumber()) continue;
            if (OrderType()==OP_BUY)
               error=OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);
            if (OrderType()==OP_SELL)
               error=OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);
         }   
      }
      if (!error) {err++;Sleep(2000);RefreshRates();}
      if (error || err >5) return;
   }
}
//-------------------------------------------------------------------+
 
Tigerfreerun:
Je ne comprends pas vraiment ce que fait exactement cette fonction. Mais, comme l'a dit l'auteur, son but est de couvrir les ordres perdants par des ordres profitables entre les symboles. Je serais heureux si vous pouviez m'aider à corriger et à comprendre la fonction
void MaxMinProfit()
{
int i, N, MaxTic, MinTic;
double   MinProf=0, MaxProf=0, OP, g, a[][2];
string MinSym, MaxSym;
ArrayResize(a, 0);
 
for (i=OrdersTotal()-1; i>=0; i--) 
  {    
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
    { 
     if (OrderType()==OP_SELL ||  OrderType()==OP_BUY )
      {
       OP = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
       
      if (MinProf>OP) 
      {
       
          MinProf=OP;
          MinTic=OrderTicket();
          MinSym=OrderSymbol();
          
         }
         
      if (OP>0) 
      {
       
          N++;
            ArrayResize(a, N);
            a[N-1][0]=OP;
            a[N-1][1]=OrderTicket();
          
         }
         
         }
         }
         
         }
         
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);//MODE_ASCEND);
      
      for (i=0; i<Level; i++) 
       {
     
     g+=a[i][0];
     //int ti=a[i-2][1];
     }
         
         
     
     if(MinProf <0 && (g+MinProf)>=ProcMax)
      {
       for (i=0; i<Level; i++) 
       {
       if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
        {
        //Alert(a[i][1]);
         if (OrderType()== OP_BUY)
         {
          OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }
         }
          
          
          
          if (OrderSelect(MinTic, SELECT_BY_TICKET, MODE_TRADES))
        {
         if (OrderType()== OP_BUY)
         {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }}       
return;
}

Vous ne comprenez pas, et je ne veux pas comprendre ce que fait cette fonction. Vous l'utilisez. Vous l'avez choisi pour vous-même. Comment pouvez-vous utiliser quelque chose sans comprendre à quoi il sert.

Je viens de vous dire d'où vient l'erreur, pour quelle raison.

Une précision supplémentaire :

Un tableau est déclaré. Il est mis en évidence en vert. Il a une longueur nulle dans la première dimension. La ligne en bleu n'est pas claire. Si vous voulez réinitialiser la taille du tableau, il y a ArrayFree() Mais même cette fonction sera inutile, puisque le tableau dynamique qui vient d'être déclaré a une longueur nulle.

2. S'il n'y a pas d'ordres, le code marqué en rouge ne sera pas exécuté. Par conséquent, la taille du tableau restera nulle.

3. Le triage des tableaux est assuré sur chaque tique. Cela découle du code. Et que peut-on trier dans une poche vide ? A moins que ce ne soit 2 œufs de caille... ?


Et voici le texte de l'erreur... Qu'est-ce que je peux dire ? Les développeurs n'ont pas prévu que quelqu'un pourrait essayer de trier un tableau vide. Ils n'ont pas inventé un message spécial pour ça.

ArrayFree - Операции с массивами - Справочник MQL4
ArrayFree - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически...
 
Alexey Viktorov:

Vous ne comprenez pas, et je ne veux pas comprendre ce que fait cette fonction. Vous l'utilisez. Vous l'avez choisi pour vous-même. Comment pouvez-vous utiliser quelque chose sans comprendre à quoi il sert.

Je viens de vous dire d'où vient l'erreur, pour quelle raison.

Une précision supplémentaire :

1. un tableau est déclaré. Il est mis en évidence en vert dans le code. Il a une longueur nulle dans la première dimension. La ligne surlignée en bleu n'est pas claire. Si nous voulons remettre à zéro la taille du tableau, il existe ArrayFree() , mais même cette fonction sera inutile, puisque le tableau dynamique que nous venons de déclarer a une longueur nulle.

2. S'il n'y a pas d'ordre, le code marqué en rouge ne sera pas exécuté. Par conséquent, la taille du tableau restera nulle.

3. Le triage des tableaux est assuré sur chaque tique. Cela découle du code. Et que peut-on trier dans une poche vide ? A moins que ce ne soit 2 œufs de caille... ?


Et voici le texte de l'erreur... Qu'est-ce que je peux dire ? Les développeurs n'ont pas prévu que quelqu'un pourrait essayer de trier un tableau vide. Ils n'ont pas inventé un message spécial pour ça.

Alexey, tu as tort. ArrayFree() sert à libérer la mémoire du tableau lorsqu'elle n'est plus nécessaire, ce qui est très rarement le cas, et certainement pas dans ce cas.

ZeroMemory(a), ArrayInitialize(a,xxx) doit être utilisé pour remettre le tableau à zéro, et ArrayResize(a,xxx) doit être utilisé pour le redimensionner dans la première dimension.

Toutefois, cet amendement n'affecte pas votre raisonnement - il est correct.

 
Artyom Trishkin:

Alexey, ce n'est pas correct. ArrayFree() est utilisé pour libérer la mémoire d'un tableau lorsque ce tableau n'est plus nécessaire, ce qui est très rare, et certainement pas dans ce cas.

ZeroMemory(a), ArrayInitialize(a,xxx) doit être utilisé pour mettre à zéro le tableau, et ArrayResize(a,xxx) doit être utilisé pour le redimensionner dans la première dimension.

Cependant, cet amendement n'affecte pas votre raisonnement - il est correct.

Selon la documentation

ArrayFree .

libère le tampon de tout tableau dynamique et fixe la taille de la dimension zéro à 0.

Peut-être que je ne me suis pas exprimé assez correctement et que vous m'avez mal compris.
 
Alexey Viktorov:

Selon la documentation

Peut-être que je ne me suis pas exprimé assez correctement et que vous m'avez mal compris.

Et plus loin derrière :


Note

L'utilisation de la fonction ArrayFree() dans les scripts et les indicateurs n'est pas très souvent nécessaire, car toute la mémoire utilisée est immédiatement libérée après l'arrêt du script. Dans les indicateurs personnalisés, la plupart des opérations avec les tableaux sont des accès aux tampons des indicateurs, dont les tailles sont automatiquement gérées par le sous-système exécutif du terminal client.

Si un programme doit gérer la mémoire de manière indépendante dans des conditions dynamiques complexes, la fonction ArrayFree() permettra de libérer explicitement et immédiatement la mémoire occupée par un tableau dynamique inutile.


Libère le tampon de tout tableau dynamique et fixe la taille de la dimension zéro à 0

Vous comprenez ? Vous avez lu la deuxième partie et manqué la première partie - importante - ? Il libère la mémoire allouée au tableau. C'est... parti... L'espace mémoire alloué au tableau est libéré et peut alors être occupé par d'autres données. Pourquoi, à chaque fois que vous entrez à nouveau dans la fonction, la mémoire doit-elle être réaffectée à ce tableau ? Vous êtes celui qui est censé le libérer. Il suffit de modifier la taille - ArrayResize() ou de mettre le tableau à zéro - ArrayInitialize(), ZeroMemory(). Et l'espace mémoire pour le tableau ne sera pas libéré, et il restera réservé pour ce tableau jusqu'à ce que le programme soit terminé.

 
Artyom Trishkin:

Et puis il y a la même chose :


Note

L'utilisation de la fonction ArrayFree() dans les scripts et les indicateurs n'est pas très souvent nécessaire, car toute la mémoire utilisée est immédiatement libérée après l'arrêt du script. Dans les indicateurs personnalisés, la plupart des opérations avec les tableaux sont des accès aux tampons des indicateurs, dont les tailles sont automatiquement gérées par le sous-système exécutif du terminal client.

Si un programme doit gérer la mémoire de manière indépendante dans des conditions dynamiques complexes, la fonction ArrayFree() permettra de libérer explicitement et immédiatement la mémoire occupée par un tableau dynamique inutile.


Elle libère le tampon de tout tableau dynamique et fixe la taille de la dimension zéro à 0.

Vous comprenez ? Vous avez lu la deuxième partie et manqué la première partie importante, n'est-ce pas ? Il libère la mémoire allouée au tableau. C'est tout... parti... L'espace mémoire alloué au tableau est libéré et peut être occupé par d'autres données. Pourquoi, à chaque fois que vous entrez à nouveau dans la fonction, la mémoire doit-elle être réaffectée à ce tableau ? Vous êtes celui qui est censé le libérer. Il suffit de modifier la taille - ArrayResize() ou de mettre le tableau à zéro - ArrayInitialize(), ZeroMemory(). Et l'espace mémoire pour le tableau ne sera pas libéré, et il restera réservé pour ce tableau jusqu'à ce que le programme soit terminé.

Ok... Et si un tableau local est déclaré à chaque appel d'une fonction ou, plus improbable, à chaque tic... Mais la mémoire du tableau est allouée à chaque fois que le tableau est défini. N'est-ce pas ? Et quelle différence cela fait-il que la mémoire soit libérée ou non, mais la mémoire est allouée à chaque fois...

Mon idée principale était que tu ne devrais pas faire ça... et si vous le faites, vous feriez mieux de le faire par ArrayFree().

Voici ce qui est intéressant : si un tableau local est déclaré chaque fois qu'une fonction est appelée, la mémoire lui est réservée à chaque fois. Mais quelles adresses sont utilisées pour ce faire ? La même chose que lors de la première déclaration du tableau, ou ce qui sera utilisé ?

 
Denis Danilov:

Bonjour, l'EA s'appelle "Rollover", mais il ne fonctionne pas comme prévu. Il double le lot s'il ferme en moins, mais la fermeture ultérieure du TP pour une raison quelconque ne permet pas de retourner les trades en moins, qui ont été fermés avant. Veuillez me dire ce qui ne va pas, je n'arrive pas à comprendre. Je tiens à remercier d'avance tous ceux qui ont fait des commentaires.

Essayez de vérifier le doublage avant le lot initial. Regardez la fermeture par temps.

Raison: