Kleiner Moneymanagement-Indikator durch neuen MQL4 ruiniert

 

Hallo Coder,

ich habe einen kleinen Moneymanagement-Indikator erstellt, der bei mir gut funktioniert hat. Aber seit dem neuen MQL4 macht er Probleme, mit denen ich nicht umgehen kann.

Wenn Sie diesen Indikator auf Ihr Diagramm ziehen, werden einige Zahlen auf der ganz rechten Seite gedruckt. Die erste Zahl steht für den Stoploss in Pips und die zweite für die Lot-Größe. In den Optionen können Sie das Risiko auswählen. Die anderen Zahlen sind die Stoploss-Levels. Aber wenn ich das Währungspaar wechsle, sind die Zahlen verschwunden. Stattdessen sehe ich mehrere Male das Wort "Label". Und wenn ich mir die Indikatorliste ansehe, ist mein Indikator auch weg. Zusammenfassend lässt sich also sagen, dass nach dem Wechsel des Währungspaares der Indikator verschwunden ist und statt der Zahlen nur noch Labels angezeigt werden.

Ich bin total verwirrt. Früher hat dieser Indikator ohne Probleme funktioniert. Für Hilfe bin ich sehr dankbar.

Hier ist der 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);
  }
//+------------------------------------------------------------------+
 

erstens kann man "exp" nicht für einen int verwenden , er ist reserviert

zweitens drückt man den "SL" aus

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

in der Init-Sektion, schlechte Idee

denn wenn du den Fehler 4066 bekommst, ist "SL" = 0

dann erhält man eine Null-Division für "lots"

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

und der Indikator stoppt und Sie müssen den Indikator neu laden.

 
Ich habe verstanden. Ich habe gerade die Variable exp geändert, aber können Sie mir sagen, wie ich den Fehler 4066 überprüfen oder vermeiden kann? Ich habe gelesen, dass es mit der Tatsache zu tun hat, dass MetaTrader nur die Kurse des aktuellen Charts und Zeitrahmens aktualisiert. Aber was würden Sie vorschlagen, um zu tun, um 4066 zu vermeiden?
 

Offensichtlich kann man die Aktualisierung nicht vermeiden ;-) aber man muss eine Situation der "Nullteilung" vermeiden

also muss man prüfen, ob eine der Variablen gleich 0.... ist, um eine Nullteilung zu vermeiden

und da man einen Indikator nicht stoppen kann, muss man sich etwas einfallen lassen

Beispiel:

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);
 

Du hast recht... Ich kann es nicht vermeiden :-)

Was ich meinte, ist, kann ich warten, bis die Aktualisierung abgeschlossen ist, bevor ich mit der SL-Berechnung fortfahre? Das Problem ist, dass ich dem SL keinen zufälligen Wert geben kann, weil dann der ganze Indikator nutzlos ist. Ich würde also gerne auf den Fehler 4066 prüfen, und wenn er auftritt, würde ich gerne etwas warten und erneut prüfen, bevor ich weitermache.

 

Übrigens habe ich das gleiche Problem mit diesem Indikator. Aber warum war das im "alten" MetaTrader kein Problem? Hier erhalte ich immer eine Null für die ATR(5). WARUM?!?! Das ist vorher nie passiert... Ich hasse diesen neuen 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);
  }
 
Was meinen Sie mit Null? Ich drucke alle der Kommentar und ATR(5) zeigt Ausgabe größer als Null ... über 50 in der Tat ...
 

Ich glaube, ich habe das Problem gefunden! Es ist definitiv ein Aktualisierungsproblem. Wenn ich jetzt die Währungen wechsle, funktioniert der Indikator. Aber dann habe ich ein Währungspaar geöffnet, das ich heute noch nicht geöffnet hatte. Dann bekam ich diese Meldung:


Öffnen Sie ein Paar, das Sie heute noch nicht geöffnet haben. Wechseln Sie zu einem beliebigen Zeitrahmen, außer D1. Dann ziehen Sie den Indikator auf Ihren Chart. Das Ergebnis wird ein Fehler wie oben sein. Es scheint mir, dass die ATR(5) des Tagescharts aufgrund fehlender DAILY DATA nicht korrekt ist. Das Öffnen eines "frischen" Charts im D1-Zeitrahmen verursacht keinerlei Probleme. Und wenn man zu einem anderen Zeitrahmen wechselt, ist es auch in Ordnung, weil die ATR(5) korrekt ist. Ich habe festgestellt, dass ich zu jedem Paar wechseln kann, solange ich im D1-Chart bleibe. Aber der Wechsel zu anderen Paaren in anderen Zeitrahmen als D1 verursacht Probleme, solange MetaTrader die täglichen Daten nicht erhalten hat. Meine Frage ist nun, wie kann ich die täglichen Daten erhalten, damit meine ATR-Berechnung korrekt ist, wenn ich einen neuen Chart in einem Zeitrahmen öffne, der nicht D1 ist?
 

Sie müssen etwas eingeben wie

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

in ShowSpread.mq4


Suchen Sie einfach die Zeile, in der diese Nullteilung auftritt.

 
mar:

Ich glaube, ich habe das Problem gefunden! Es ist definitiv ein Aktualisierungsproblem. Wenn ich jetzt die Währungen wechsle, funktioniert der Indikator. Aber dann habe ich ein Währungspaar geöffnet, das ich heute noch nicht geöffnet hatte. Dann bekam ich diese Meldung:


Öffnen Sie ein Paar, das Sie heute noch nicht geöffnet haben. Wechseln Sie zu einem beliebigen Zeitrahmen, außer D1. Dann ziehen Sie den Indikator auf Ihren Chart. Das Ergebnis wird ein Fehler wie oben sein. Es scheint mir, dass die ATR(5) des Tagescharts aufgrund fehlender DAILY DATA nicht korrekt ist. Das Öffnen eines "frischen" Charts im D1-Zeitrahmen verursacht keinerlei Probleme. Und wenn man zu einem anderen Zeitrahmen wechselt, ist es auch in Ordnung, weil die ATR(5) korrekt ist. Ich habe festgestellt, dass ich zu jedem Paar wechseln kann, solange ich im D1-Chart bleibe. Aber das Umschalten auf andere Paare in anderen Zeitrahmen als D1 verursacht Probleme, solange MetaTrader die täglichen Daten nicht erhalten hat. Meine Frage ist nun, wie kann ich die täglichen Daten erhalten, damit meine ATR-Berechnung korrekt ist, wenn ich einen neuen Chart in einem anderen Zeitrahmen als D1 öffne?
qjol hat Ihnen bereits gesagt, wo das Problem liegt. Warum befolgst du nicht, was die Leute dir geraten haben, oder überprüfst es zumindest, wenn du um Hilfe bittest?
 

angevoyageur, ich glaube du hast diesen Beitrag von mir nicht gesehen:

mar 2014.04.02 08:16 #

Du hast recht... Ich kann es nicht vermeiden :-)

"Was ich meinte, ist, kann ich warten, bis das Update abgeschlossen ist, bevor ich mit der SL-Berechnung weitermache? Das Problem ist, dass ich dem SL keinen Zufallswert geben kann, weil dann der ganze Indikator nutzlos ist. Ich möchte also auf den Fehler 4066 prüfen und wenn er auftritt, möchte ich irgendwie warten und erneut prüfen, bevor ich weitermache."

Daran sieht man, dass ich den Ratschlag nicht befolgen kann und weil ich zu dieser Lösung gekommen bin, sieht man auch, dass ich definitiv überprüft habe, was qjol mir geraten hat.