Petit indicateur de gestion de l'argent ruiné par le nouveau MQL4

 

Salut les codeurs,

J'ai fait un petit indicateur Moneymanagement qui a bien fonctionné pour moi. Mais depuis le nouveau MQL4, il pose des problèmes que je ne peux pas gérer.

Lorsque vous faites glisser cet indicateur sur votre graphique, quelques chiffres sont imprimés sur le côté droit. Le premier nombre signifie le Stoploss en pips et le second est la taille du lot. Dans les options, vous pouvez choisir le risque. Les autres nombres sont les niveaux de Stoploss. Mais lorsque je change de paire de devises, les chiffres ont disparu. À la place, je vois plusieurs fois le mot "Label". Et quand je regarde dans la liste des indicateurs, mon indicateur a également disparu. Donc, en résumé, après avoir changé la paire de devises, l'indicateur a disparu et a laissé des étiquettes à la place des chiffres.

Je suis totalement confus. Cet indicateur fonctionnait auparavant sans aucun problème. Une aide est très appréciée.

Voici le code :

#property indicator_chart_window
//--- input parameters
extern int  Risk=2;
extern int SL_Levels=20;
int multi, exp, SL, i, k;
double MoneyRisk, Spread, _modifySpread, lots;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      if (ObjectFind("SL"+i) == -1)
      {
         ObjectCreate("SL"+i, OBJ_LABEL, 0, 0, 0);
         ObjectSet("SL"+i, OBJPROP_CORNER, 1);
         ObjectSet("SL"+i, OBJPROP_XDISTANCE, 3);
         ObjectSet("SL"+i, OBJPROP_YDISTANCE, k);
         k=k+15;    
      }
   }
   if (ObjectFind("Spread") == -1)
   {
      ObjectCreate("Spread", OBJ_LABEL, 0, 0, 0);
      ObjectSet("Spread", OBJPROP_CORNER, 3);
      ObjectSet("Spread", OBJPROP_XDISTANCE, 3);
      ObjectSet("Spread", OBJPROP_YDISTANCE, 1);
   }
   
//-- 4 / 5 Digit Settings --
   multi   = 1;
   exp     = 0;
   if (Digits==5 || Digits==3)
   {
      _modifySpread = 0.1;
      multi=10;
      exp=1;
   }
//----
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   for(i=1; i<=SL_Levels; i++)
   {
      ObjectDelete("SL"+i);
   }
   ObjectDelete("Spread");
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start()
  {
//----
   Spread     = MarketInfo(Symbol(), MODE_SPREAD)*_modifySpread;
   MoneyRisk  = AccountBalance()*Risk*0.01;
   k=0;
   for(i=1; i<=SL_Levels; i++)
   {
      lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
      ObjectSetText("SL"+i, SL+ " : "+DoubleToStr(lots, 2), 10, "Calibri", Red);
      k=k+15;
      SL = SL+MathFloor(((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1)/2);     
   }
   SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
   ObjectSetText("Spread", DoubleToStr(Spread,1), 10, "Calibri", Red);
   WindowRedraw();
//----
   return(0);
  }
//+------------------------------------------------------------------+
 

d'abord vous ne pouvez pas utiliser "exp" pour un int c' est réservé

ensuite tu exprimes le "SL"

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);

dans la section init, mauvaise idée

parce que si tu obtiens Error 4066 le "SL" = 0

alors vous obtenez une division par zéro sur "lots".

lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);

et l'indicateur s'arrête et vous devez le recharger.

 
Je comprends. Je viens de modifier la variable exp mais pouvez-vous me dire comment vérifier ou éviter l'erreur 4066 ? J'ai lu qu'elle est liée au fait que MetaTrader ne met à jour que les cotations du graphique et de la période en cours. Mais que suggérez-vous de faire pour éviter l'erreur 4066 ?
 

évidemment vous ne pouvez pas éviter la mise à jour ;-) mais vous devez éviter une situation de "zéro divide".

il faut donc vérifier si l'une des variables est égale à 0.... pour éviter le "zero divide".

et parce que vous ne pouvez pas arrêter un indicateur, vous devez trouver une solution.

exemple :

SL = MathFloor((iATR(NULL, PERIOD_D1, 7, 0)*MathPow(10,Digits-exp)+1)*0.1);
if (SL == 0) // because error 4066 (for example)
   {
   SL = Someting;
   }
lots=MoneyRisk/SL/(MarketInfo(Symbol(), MODE_TICKVALUE)*multi);
 

Vous avez raison. Je ne peux pas l'éviter :-)

Ce que je voulais dire, c'est que je peux attendre que la mise à jour soit terminée avant de poursuivre le calcul du SL ? Le problème est que je ne peux pas donner à SL une valeur aléatoire car alors l'indicateur entier est inutile. Je voudrais donc vérifier l 'erreur 4066 et si elle se produit, j'aimerais attendre un peu et vérifier à nouveau avant de continuer.

 

D'ailleurs, j'ai le même problème avec cet indicateur. Mais pourquoi n'était-ce pas un problème dans l'"ancien" MetaTrader ? Ici, je reçois toujours un zéro pour l'ATR(5). POURQUOI ? !?! Cela n'est jamais arrivé avant.. Je déteste ce nouveau MetaTrader... !

int start()
//----
  {
   double Spread = MarketInfo(Symbol(), MODE_SPREAD);
   double ATR = iATR(NULL, PERIOD_D1, 5, 0);
   int exp1 = 0;
   if (Digits==5 || Digits==3)
   {
      Spread=Spread*0.1;
      exp1 = 1;
   }
   Comment  (
            "ADR(5): ",DoubleToStr(ATR*MathPow(10,Digits-exp1),1),
            " || TODAY: ",(iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1),
            " || ", DoubleToStr(((iHigh(NULL, PERIOD_D1, 0)-iLow(NULL, PERIOD_D1, 0))*MathPow(10,Digits-exp1)/(ATR*MathPow(10,Digits-exp1))*100), 2), "%",
            "\n" +
            "SPREAD: ", Spread,
            " || RATIO: ",DoubleToStr((Spread/ATR)*MathPow(10,-(Digits-exp1-2)), 2),"%"
            );
//----
   return(0);
  }
 
Que voulez-vous dire par zéro ? J'ai imprimé tous les commentaires et ATR(5) montre une sortie supérieure à zéro ... au-dessus de 50 en fait ...
 

Je pense avoir trouvé le problème ! Il s'agit bien d'un problème de mise à jour. Lorsque je change maintenant de devise, l'indicateur fonctionne. Mais ensuite, j'ai ouvert une paire de devises que je n'avais pas encore ouverte aujourd'hui. J'ai alors reçu ce message :


Ouvrez une paire que vous n'avez pas encore ouverte aujourd'hui. Passez à l'horizon temporel de votre choix, sauf D1. Puis vous faites glisser l'indicateur sur votre graphique. Le résultat sera une erreur comme ci-dessus. Il me semble que l'ATR(5) du graphique journalier n'est pas correct à cause de l'absence de données journalières. L'ouverture d'un nouveau graphique dans l'intervalle de temps D1 ne pose aucun problème. Et lorsque vous passez à un autre cadre temporel, tout va bien également car l'ATR(5) est correct. J'ai remarqué que je peux passer à n'importe quelle paire tant que je reste dans le graphique D1. Mais passer à d'autres paires dans d'autres cadres temporels que D1 pose des problèmes tant que MetaTrader n'a pas reçu les données quotidiennes. Ma question est donc la suivante : comment puis-je obtenir les données quotidiennes pour que mon calcul d'ATR soit correct lorsque j'ouvre un nouveau graphique dans un cadre temporel autre que D1 ?
 

Vous devez mettre quelque chose comme

if(number==0)dothis; else dothis; 

dans ShowSpread.mq4


Cherchez la ligne où cette division par zéro se produit.

 
mar:

Je pense avoir trouvé le problème ! Il s'agit bien d'un problème de mise à jour. Lorsque je change maintenant de devise, l'indicateur fonctionne. Mais ensuite, j'ai ouvert une paire de devises que je n'avais pas encore ouverte aujourd'hui. J'ai alors reçu ce message :


Ouvrez une paire que vous n'avez pas encore ouverte aujourd'hui. Passez à l'échelle de temps que vous voulez, sauf D1. Puis vous faites glisser l'indicateur sur votre graphique. Le résultat sera une erreur comme ci-dessus. Il me semble que l'ATR(5) du graphique journalier n'est pas correct à cause de l'absence de données journalières. L'ouverture d'un nouveau graphique dans l'intervalle de temps D1 ne pose aucun problème. Et lorsque vous passez à un autre cadre temporel, tout va bien également car l'ATR(5) est correct. J'ai remarqué que je peux passer à n'importe quelle paire tant que je reste dans le graphique D1. Mais passer à d'autres paires dans d'autres cadres temporels que D1 pose problème tant que MetaTrader n'a pas reçu les données quotidiennes. Donc, ma question est maintenant, comment puis-je obtenir les données quotidiennes que mon calcul de l'ATR est correct lorsque j'ouvre un nouveau graphique dans un cadre temporel qui n'est pas D1 ?
qjol vous a déjà dit où se trouve le problème. Pourquoi ne pas suivre ou au moins vérifier ce que les gens vous ont conseillé si vous demandez de l'aide ?
 

angevoyageur, je pense que vous n'avez pas vu ce message de ma part :

mar 2014.04.02 08:16 #

Vous avez raison. Je ne peux pas l'éviter :-)

"Ce que je voulais dire, c'est que je peux attendre que la mise à jour soit terminée avant de poursuivre le calcul de la SL. Le problème est que je ne peux pas donner à SL une valeur aléatoire car alors l'indicateur entier est inutile. Je voudrais donc vérifier l'erreur 4066 et si elle se produit, je voudrais attendre un peu et vérifier à nouveau avant de continuer."

Là, vous pouvez voir que décrit que je ne peux pas suivre le conseil et parce que je suis arrivé à cette solution, vous pouvez également voir que j'ai définitivement vérifié ce que qjol m'a conseillé.