erreur: '{' - unbalanced parenthèses. aider moi par pitié !! - page 2

 
William Yamindi #:

Un immense merci pour ton aide, c’est vraiment très gentil de ta part ! Grâce à toi. Tous tes conseils sont désormais bien ancrés dans ma tête, et je sais que je pourrai les appliquer pour les prochaines fois avec beaucoup plus de facilité. C’est rare de rencontrer des gens aussi généreux dans leur partage de connaissances.


Si tu as un peu de temps, j’aimerais bien avoir ton avis sur le codage que j’ai réalisé jusqu’à maintenant. Je travaille dessus pour l’améliorer, mais ton regard extérieur serait vraiment le bienvenu afin de m’assurer que je vais dans la bonne direction…

Merci aussi à toi, pour ton retour reconnaissant.

Alors, pour ce qui est de ton codage jusque là, je pense que tu es dans le bon, pour quelqu'un qui est encore dans ses débuts en programmation Mql5/4. Et, sois-en sûr, nous y sommes tous passés ! Seulement, au fur et à mesure que tu évolueras dans le monde du code, que ce soit en Mql5/4 ou dans n'importe quel autre langage de programmation, tu devras toujours veiller à ces deux aspects : avoir une structure de code (a) la plus optimisée possible et (b) la moins redondante possible. Cela permet au compilateur du code (ou interpréteur, dans le cas de python par exemple) d'analyser et exécuter ton code beaucoup plus rapidement. Et puisqu'on parle rapidité, comme tu le sais, dans le trading, algorithmique comme manuel d'ailleurs, la rapidité d'exécution est le nerf de la guerre.

Alors, pour mieux t'illustrer cette notion d'optimisation et de non-redondance, je reprends ci-dessous un morceau de ton code, que je trouve peu optimisé et redondant, et te propose en face une structure que je trouve optimisée et pas du tout redondante.

Alors, il est vrai que cela peut paraître peu utile pour des projets qui font à peine quelques lignes de code... Mais plus un projet commencera à croître en termes du nombre de lignes de code, et bien, optimiser sa structure et la rendre moins redondante pourrait bien avoir tout son intérêt.

Ainsi, je reprends ici ce bloc de code :

// VERSION QUE JE TROUVE PEU OPTIMISÉE ET REDONDANTE
 
void TesterSignal()
 {      // Récupération des valeurs actuelles et précédentes des EMA
  double emaFastPrev = emaFast[1];
  double emaFastNow = emaFast[0];
  double emaSlowPrev = emaSlow[1];
  double emaSlowNow = emaSlow[0];
       // Vérification des conditions d'achat : EMA rapide croise au-dessus de l'EMA lente
  if (emaFastPrev < emaSlowPrev && emaFastNow > emaSlowNow)
    {
     // Calcul du lot en fonction du stop loss
     double lotSize = CalculateLotSize(stopLossPoints);
     // Passer un ordre d'achat avec stop loss et take profit
     trade.Buy(lotSize, _Symbol, 0, stopLossPoints * Point(), takeProfitPoints * Point(), "Shallow Buy");
    }
   
    // Vérification des conditions de vente : EMA rapide croise en-dessous de l'EMA lente
  if (emaFastPrev > emaSlowPrev && emaFastNow < emaSlowNow)
    {
     // Calcul du lot en fonction du stop loss
     double lotSize = CalculateLotSize(stopLossPoints);
     // Passer un ordre de vente avec stop loss et take profit
     trade.Sell(lotSize, _Symbol, 0, stopLossPoints * _Point, takeProfitPoints * _Point, "Shallow Sell");
    } 
 }

// ________________________________________________________________________

void TesterSignal2()
 {      // Récupération des valeurs actuelles et précédentes des EMA
  double emaFastPrev = emaFast[1], emaFastNow = emaFast[0], emaSlowPrev = emaSlow[1], emaSlowNow = emaSlow[0],
         lotSize = CalculateLotSize(stopLossPoints); // Calcul du lot en fonction du stop loss
       
        // Vérification des conditions d'achat : EMA rapide croise au-dessus de l'EMA lente
  if (emaFastPrev < emaSlowPrev && emaFastNow > emaSlowNow)
    {
     // Passer un ordre d'achat avec stop loss et take profit
     trade.Buy(lotSize, _Symbol, 0, stopLossPoints * Point(), takeProfitPoints * Point(), "Shallow Buy");
    }
  else 
    {// Vérification des conditions de vente : EMA rapide croise en-dessous de l'EMA lente
     if (emaFastPrev > emaSlowPrev && emaFastNow < emaSlowNow)
       {
        // Passer un ordre de vente avec stop loss et take profit
        trade.Sell(lotSize, _Symbol, 0, stopLossPoints * _Point, takeProfitPoints * _Point, "Shallow Sell");
       }
    } 
 }

Ainsi, quels sont alors les petits conseils sur l'optimisation et la non-redondance à retenir de cette deuxième version de la fonction "TesterSignal" ?

1. Puisque toutes mes variables ici étaient de type double, alors j'ai utilisé ce mot clé, double donc, une seule fois et lui ai lié toutes ces variables, en les séparant juste des virgules (et j'ai utilisé un seul point-virgule à la fin de la déclaration de toutes ces variables).
 Oui, c'est aussi de l'optimisation, et même de la non-redondance. D'ailleurs, se faisant, j'ai dû réduire aussi le nombre de lignes de code à ce niveau.

2] J'ai appelé la fonction "CalculateLotSize" une seule fois. He oui, ça ne servait à rien de devoir l'appeler deux fois ici. Et ainsi, j'ai dû éviter la redondance.

3] Enfin, j'ai ajouté l'operateur Else dans cette structure conditionnelle. Et ça, c'est vraiment de l'optimisation. Puisque, de toutes façons, il est impossible en temps normal, d'assister à un scénario où une condition d'achat et une de vente viennent se valider pile poil au même moment. Cela n'est juste pas possible. On a soit nos conditions d'achat qui se valident à un moment donné, et on achète, soit nos conditions d'achat ne sont pas réunies, et c'est seulement dans ce cas, qu'on passe à vérifier celles de vente. Si elles, elles sont là, on vend, sinon, on attend le prochain tick pour reprendre infiniment ce processus. Et donc, l'idée, ici, c'est de comprendre que lorsque nos conditions d'achat, qui sont ici testées en premier, sont réunies, il est inutile de faire perdre au compilateur le temps de tester encore nos conditions de vente à ce tick-ci, car elles ne seront forcément pas là.

Et, très important pour terminer, afin d'éviter de te retrouver avec un EA qui te prend 1000 trades chaque 5 minutes, tu devrais impérativement penser à intégrer un filtre destiné de vérifier toujours que ton nombre maximum de trades en cours autorisé n'est pas encore atteint avant éventuellement d'ouvrir toute nouvelle position !!!

Et pour ajouter un tel filtre, ta structure peut par exemple devenir quelque chose comme suit :

 void TesterSignal2()
 {      // Récupération des valeurs actuelles et précédentes des EMA
  double emaFastPrev = emaFast[1], emaFastNow = emaFast[0], emaSlowPrev = emaSlow[1], emaSlowNow = emaSlow[0], lotSize;
         
       // Vérification des conditions d'achat : EMA rapide croise au-dessus de l'EMA lente
  
  if (PositionsTotal() <= 5)     // POUR LIMITER PAR EXEMPLE LE NOMBRE DE TRADES EN COURS A SEULEMENT 5 MAXIMUM
    {
     lotSize = CalculateLotSize(stopLossPoints); // Calcul du lot en fonction du stop loss
     
     if (emaFastPrev < emaSlowPrev && emaFastNow > emaSlowNow)
       {
        // Passer un ordre d'achat avec stop loss et take profit
        trade.Buy(lotSize, _Symbol, 0, stopLossPoints * Point(), takeProfitPoints * Point(), "Shallow Buy");
       }
     else 
       {// Vérification des conditions de vente : EMA rapide croise en-dessous de l'EMA lente
        if (emaFastPrev > emaSlowPrev && emaFastNow < emaSlowNow)
          {
           // Passer un ordre de vente avec stop loss et take profit
           trade.Sell(lotSize, _Symbol, 0, stopLossPoints * _Point, takeProfitPoints * _Point, "Shallow Sell");
          }
       }
    } 
 }
 
Vous avez bien faire comme si je n'étais pas là, mais utiliser le terme structure qui est une forme de type est une erreur flagrante 
 
Gerard William G J B M Dinh Sy #:
Vous avez bien faire comme si je n'étais pas là, mais utiliser le terme structure qui est une forme de type est une erreur flagrante 

Vraiment !!!  Merci je vois ce que tu veux dire. Seulement, lorsqu'on suis bien l'esprit derrière mon texte, on comprend rapidement que, parlant de structure, je fais allusion à la structure architecturale du code, et non à la structure comme effectivement l'un des types de données disponibles en mql5/4. Je vois, merci.

 
https://www.mql5.com/fr/docs/constants/structures

Sans parler de celles qui peuvent être créer
 
J M #:

Bonjour William !

Alors, après réexamen de ton code, j'ai de nouveau réussi à identifier tous les points qui posaient problème, et je vais essayer de te les détailler un à un:

1] Tu sembles confondre du code python au code Mql5. En python, tu peux sans aucun problème utiliser les Opérateurs Conditionnel If-Else dans la portée globale de ton code, c'est-à-dire en  dehors d'une fonction, ce qui n'est pas possible en Mql5/4. En Mql4/5 donc, les Opérateurs Conditionnel If-Else ne peuvent être utilisés qu'à l'intérieur d'une fonction, pas en dehors. Ce qui posait problème avec tout l'ensemble de ton bloc de code ci-dessous:

2] En Mql4/5, lors de la déclaration d'une fonction, tu ne peux pas directement lui passer comme argument par défaut une variable définie à la portée globale comme input. Ce qui posait donc un deuxième problème ici :

3] Tu procédais mal pour pouvoir récupérer la balance du compte, à ce niveau:

4] Tu confonds les fonctions Mql5 "_Point et Point()": La première notation, avec un underscore, s'appelle sans les parenthèses, alors que la deuxième, sans underscore donc, s'appelle, quant à elle, avec les parenthèses. Ce qui posait donc problème à ce niveau ici:

5] Et voilà ! Apres donc toutes ces remarques, voici donc la version corrigée complète que je te propose (tu remarqueras que j'ai dû ajouter des séparateurs (_____) pour renforcer la visualité de tes blocs de code. Et pour le bloc où tu utilisais les operateurs If-Else en dehors d'une fonction, j'ai dû créer pour toi une fonction que j'ai nommée arbitrairement "TesterSignal()" et j'y ai placée tout ce bloc de code là. Et cette nouvelle fonction, TesterSignal() donc, devrait être appelée en permanence dans la fonction OnTick(). Tu noteras également que, dans la version de code corrigée que je te propose, j'ai dû aussi réviser le style d'indentation des accolades. Je les ai donc bien alignées verticalement !. Et cela, toujours dans le souci de rendre rapidement repérable le début et la fin de tes  blocs de code pour encore une fois renforcer sa lisibilité. Enfin, tu n'as donc qu'à bien observer ce code pour identifier tous les amendements que j'ai dû y apporter par rapport à ta version. Merci. :

Incroyable, merci pour toutes ces remarques et ses conseils, j'en ferai très bonne usage

Désolée de répondre que maintenant, en tout cas vous m'avez énormément aidé à mieux comprendre certaines choses et je vous en remercie. Merci d'avoir pris le temps et je vous souhaite plein de bonnes choses.

 
William Yamindi #:

Incroyable, merci pour toutes ces remarques et ses conseils, j'en ferai très bonne usage

Désolée de répondre que maintenant, en tout cas vous m'avez énormément aidé à mieux comprendre certaines choses et je vous en remercie. Merci d'avoir pris le temps et je vous souhaite plein de bonnes choses.

Je t'en prie. Merci.

 
J M #:

Je t'en prie. Merci.

Bonjour J M, je vous ai envoyé un message en privé, je sais pas si c’est un bug ou si vous avez tout simplement pas reçu… si vous pouvez me donner une petite suite svp
 
William Yamindi #:
Bonjour J M, je vous ai envoyé un message en privé, je sais pas si c’est un bug ou si vous avez tout simplement pas reçu… si vous pouvez me donner une petite suite svp

Salut William ! Désolé vraiment pour le retard. Parce que d'habitude je consulte rarement, mais vraiment rarement, ma messagerie ici dans cette plateforme.

Ici aussi sur cette file de discussions, je n'y revenais plus, car je considérais déjà la discussion comme clôturée étant donné qu'on était venu déjà à se remercier (signe pour moi que l'essentiel a été fait, et que par voie de conséquence, il n'y avait plus de raisons que je revienne de temps en temps sur cette file).

Sinon, je suis là. Merci