Le problème du transfert de MT4 à MT5. Ou, plus précisément, l'impossibilité d'exécuter certains algorithmes dans MT5 sans "err". - page 9

 
Vict:

Oui, le code avec des exceptions est beaucoup plus simple et plus propre, la vérification constante des erreurs le transforme en désordre. Mais il y a beaucoup de problèmes en µl sans exception. Les développeurs n'ont pas retiré les croix.

À mon avis, il n'y a pas de différence.

Avec les codes de retour, vous devez écrire une macro comme RETURN_IF_BAD_RESULT() et la placer dans toutes les fonctions qui renvoient des résultats.

Sauf exception - vous devez rédiger des sections TRY-CACTH. De plus, vous devez vous souvenir des fonctions qui lèvent une exception et de celles qui ne le font pas, ajoutez des commentaires // exception à votre code.

Quelque chose est un jeu d'enfant, quelque chose est...

 
Vict:

Oui, le code avec des exceptions est beaucoup plus simple et plus propre, la vérification constante des erreurs le transforme en un fouillis. Mais il y a beaucoup de problèmes en µl sans exception. Les développeurs n'ont pas pu tirer les croix.

Non, je ne parle même pas des exceptions... sinon, il pourrait y avoir un "cordonnier maléfique"... qui transformera tous les voyages hors du tableau en exceptions ))))

imho, vous avez juste besoin d'un moyen de briser tous les retours avec exit dans OS ... que ce soit un Exit(), vous avez eu l'idée juste, je ne veux pas multiplier les spools de code sans fin - il n'y a aucun sens de toujours envelopper tous les appels de fonction en

void OnStart()
{
if(!MyFuncReadOHLC_1()) return;
if(!MyFuncReadOHLC_2()) return;
....
}
 
Georgiy Merts:

À mon avis, il n'y a pas de différence.

Avec les codes de retour, vous devez écrire une macro comme RETURN_IF_BAD_RESULT() et la placer dans toutes les fonctions qui renvoient des résultats.

Sauf exception - vous devez rédiger des sections TRY-CACTH. De plus, souvenez-vous des fonctions qui lèvent une exception et de celles qui ne le font pas, ajoutez des commentaires // exception à votre code.

C'est le bordel, c'est le bordel...

Avec les exceptions, je n'ai pas besoin de me souvenir de quoi que ce soit, souvent même TRY-CACTH n'est pas nécessaire (il suffit de mettre fin au crash du programme), c'est une situation EXCLUSIVE et normalement ne se produit pas, ne les transformez pas en blocs if-else. Par exemple - j'ai écrit un vector-like (pathétique), au lieu de lancer une exception sur les allocations infructueuses, j'ai dû baiser operator ! et le tirer à chaque insertion (bien que je l'oublie), bénéfice douteux.

 
Igor Makanu:

imho, il faut juste être capable de tout casser avec l'OS...

Oui, c'est bon aussi, c'est étrange qu'il ne soit pas là...

 
Vict:

Oui, rien aussi, étrange qu'il ne soit pas présent ...

Je ne trouve pas pratique de transformer des programmes courts avec un code lisible en une sorte de monstre, voici un modèle typique pour MQL4 - vérifier la "nouvelle barre", vérifier les indicateurs - travailler ou non avec les ordres :

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   ENUM_CMD CMD1,CMD2,CMD3;
   CMD1 = ind1();
   CMD2 = ind2();
   CMD3 = ind3();
   if(NewBar())
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }
//+------------------------------------------------------------------+

dans cet exemple, les indicateurs "tirent chaque tick" car ils travaillent sur des TFs différents... cela n'a pas vraiment d'importance.

J'utilise les données OHLC dansind1(),ind2(),ind3() et dansNewBar().

si j'obtiens une erreur d'accès aux séries temporelles dans un appel de fonction, quel est l'intérêt de continuer à exécuter ce code ? - J'ai besoin de sortir de l'OS et d'attendre un nouveau tick, c'est-à-dire que dans n'importe quelind1(),ind2(),ind3() et dansNewBar(), je vérifie GetLastError() et si je reçois une erreur, je sors immédiatement de l'OS en écrivant dans le journal EA.

 
Vict:

Avec les exceptions, je ne dois rien retenir, souvent même le TRY-CACTH n'est pas nécessaire (le programme se terminera simplement en cas d'urgence), il s'agit d'une situation EXCLUSIVE et qui n'arrive pas normalement, ne les transformez pas en blocs if-else. Par exemple - j'ai écrit un vector-like (pathétique), au lieu de lancer une exception sur les allocations infructueuses, j'ai dû baiser operator ! et le tirer à chaque insertion (bien que je l'oublie), bénéfice douteux.

Eh bien, allez, mon pote...

Vous dites "vous n'avez pas besoin de vous souvenir de quoi que ce soit", puis vous poursuivez : souvent, même TRY-CATCH n'est pas nécessaire. Ce même "souvent" signifie qu'un bloc est nécessaire quelque part et qu'un autre n'est pas nécessaire, et que vous devez vous en souvenir. La situation est la même qu'avec les codes de retour - si vous demandez une certaine ressource et qu'une exception se produit (une erreur est renvoyée), les ressources doivent être rejetées. C'est-à-dire que, dans tous les cas, vous devez vous souvenir de la fonction qui lève une exception et de celle qui ne le fait pas.

Oh, et à propos de "situation exceptionnelle"... Eh bien, comment puis-je dire... L'absence de guillemets semble être une raison raisonnable pour lancer une exception, mais s'agit-il d'une "situation exceptionnelle" ?

 
Igor Makanu:

Je ne trouve pas pratique de transformer des programmes courts avec un code lisible en une sorte de monstre, voici un modèle typique pour MQL4 - vérifier la "nouvelle barre", vérifier les indicateurs - travailler ou non avec les ordres :

dans cet exemple, les indicateurs "tirent chaque tick" car ils travaillent sur des TFs différents... cela n'a pas vraiment d'importance.

J'utilise les données OHLC dansind1(),ind2(),ind3() et dansNewBar().

si j'obtiens une erreur d'accès aux séries temporelles dans un appel de fonction, quel est l'intérêt de continuer à exécuter ce code ? - J'ai besoin de sortir de l'OS et d'attendre un nouveau tick, c'est-à-dire que dans n'importe quel ind1(),ind2(),ind3() et dansNewBar() je vérifie GetLastError() et après avoir obtenu une erreur, je sors immédiatement de l'OS avec un enregistrement dans le journal EA.

Quel est le problème de l'appel à return(iErrrCode) ?

 
Georgiy Merts:

Et quel est le problème pour appeler return(iErrrCode) ?

Hm, je vais essayer de le montrer dans le code, j'ai réécrit le code avec une sortie si les données OHLC ont été traitées incorrectement, cela ressemblera à ceci :

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   bool nb;
   ENUM_CMD CMD1,CMD2,CMD3;
   if(!ind1( CMD1 )) return;
   if(!ind2( CMD2 )) return;
   if(!ind3( CMD3 )) return;
   if(!NewBar( nb )) return;
   
   if( nb )
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }

maintenant je récupère les valeurs de la fonction par référence et je me retire si la fonction a été traitée de manière incorrecte (dans le contexte de la discussion - le terminal n'a pas préparé lesdonnées historiques par TF)

 
Georgiy Merts:

Eh bien, allez, mon pote...

Vous dites "vous n'avez pas besoin de vous souvenir de quoi que ce soit", puis vous poursuivez : souvent, même TRY-CATCH n'est pas nécessaire. Ce même "souvent" signifie qu'un bloc est nécessaire quelque part et qu'un autre n'est pas nécessaire, et que vous devez vous en souvenir. La situation est la même qu'avec les codes de retour - si vous demandez une certaine ressource et qu'une exception se produit (une erreur est renvoyée), les ressources doivent être rejetées. C'est-à-dire que, dans tous les cas, vous devez vous souvenir de la fonction qui lève une exception et de celle qui ne le fait pas.

Oh, et à propos de "situation exceptionnelle"... Eh bien, comment puis-je dire... L'absence de guillemets est un élément raisonnable pour déclencher une exception, mais s'agit-il d'une "situation exceptionnelle" ?

Vous avez en quelque sorte utilisé les exceptions à votre manière, à tort, apparemment. En général, ne vous souciez pas de savoir si cette fonction lève une exception ou non. L'utilisation de TRY-CATCH est facultative. Et pour éviter les problèmes de ressources, obtenez RAIIhttps://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%B0_%D0%B5%D1%81%D1%82%D1%8C_%D0%B8%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F, le fait de faire tourner la pile nettoiera tout.

Et à propos de la "situation exceptionnelle"... Eh bien, comment puis-je le dire... Le manque de citations semble être une excuse raisonnable pour faire une exception, mais s'agit-il d'une "situation exceptionnelle" ?
L'exclusivité dépend de l'auteur du code, mais les exceptions ne doivent pas être analogues à if-else, bien sûr.
 

Bizarrement, je n'y avais pas pensé avant :

// Немедленное завершение, деструкторы не вызываются
void abort() {Alert(1/(uint)MathAbs(0));}

Il se débarrasse de certaines masses de vérification d'erreurs, comme l'allocation de mémoire.