globale Initialisierung fehlgeschlagen!!!!!!! - Seite 5

 
deysmacro:
Comment() hat meistens keinen Einfluss auf das Diagramm.

  if(ObjectFind(Symbol()+"Lot_Size_Label")==0)
   {         
  int x_check=ObjectGet(Symbol()+"Lot_Size_Label",OBJPROP_XDISTANCE);
  int y_check=ObjectGet(Symbol()+"Lot_Size_Label",OBJPROP_YDISTANCE);
  Comment(x_check+ " , "+y_check); 
   }

Comment(), um zu prüfen, wie die Koordinaten lauten.

Sie sollten sich ändern, wenn das Etikett nach rechts geht, aber das tun sie nicht.

D.h., die Koordinaten sind so, wie sie sein sollten.

Das Label verschwindet nach rechts.

 

Die Koordinaten sind XDISTANCE = 225; YDISTANCE = 27; CORNER = 3;

Erstens, Laden der Indi auf dem Chart, Label an Ort und Stelle:

Zweitens, Schließen von MT4 und erneutes Starten, Label springt nach rechts:

Drittens, nach dem Verschieben der Tf's, springt das Label zurück:

Es hat etwas mit den Ankern im Zusammenhang mit den Corner-Berechnungen zu tun und muss ein Fehler in B646 sein.

 
Was hat das alles mit der fehlgeschlagenen globalen Initialisierung zu tun?
 
SDC:
Was hat das alles mit der fehlgeschlagenen globalen Initialisierung zu tun?

Diese B646 ist ernsthaft fehlerhaft!
 
Dadas:


Danke, ich hatte das gleiche Problem mit den Objekten, die beim Deinit nicht gelöscht wurden.

Ich war dabei, einige Indi zu entwickeln, und bekam diese seltsamen Ergebnisse, dann sah ich in der Liste der Objekte, sie waren immer noch da.

Ich habe das umgangen, wahrscheinlich auf die einfachste Art und Weise, durch ObjectDelete() in der start().

Ja, wenn man init() in OnInit() und deinit() in OnDeinit() ändert, sind die Bezeichnungen wieder richtig! Danke dafür!

Dann, nach einer Weile, war es nicht mehr so!!! Sie führen immer noch den gleichen Tanz auf.


Gern geschehen, Dadas. Ich würde ObjectDelete() allerdings nicht in der Startmethode verwenden. Das macht man am besten in OnDeInit(). Der Grund dafür ist folgender: Wenn Sie den Code in OnStart() oder OnCalculate() einfügen, wird er jedes Mal ausgeführt, wenn ein Tick kommt. Das ist aus zwei Gründen schlecht: 1) Es fügt eine Menge Operationen hinzu, die Zeit verbrauchen, die Sie in einer Echtzeitanwendung nicht verschwenden können, und 2) es macht in den meisten Situationen keinen Sinn, dies zu tun - in der Regel ist es nur von Bedeutung, wenn ein Diagramm de-initialisiert wird. Sie sollten dies nur in den "Startup"-Methoden tun, wenn sich eine Preisänderung in irgendeiner Weise auf Ihre Objekte auswirken wird. Betrachten Sie zum Beispiel das folgende Beispiel (das Teil einer Anwendung ist, die ich verkaufen will, aber es ist cool, das zu teilen :-) ).

// If no trade is progress, there is no Position Value to display
      if (ObjectFind("PositionValue") > 0)
                ObjectDelete("PositionValue");
                
      if (ObjectFind("PipsProfitLoss") > 0)
                ObjectDelete("PipsProfitLoss");
                
      if (ObjectFind("CurrentStop") > 0)
                ObjectDelete("CurrentStop");
                
      if (ObjectFind("PipsLockedIn") > 0)
                ObjectDelete("PipsLockedIn");
                
      if (ObjectFind("ProfitLockedIn") > 0)
                ObjectDelete("ProfitLockedIn");
                
      if (GlobalVariableCheck(CurrentPairPercentageRisk))
         GlobalVariableDel(CurrentPairPercentageRisk);

Dieser Code fängt Objekte ab, die von einem abgeschlossenen Handel übrig geblieben sind, falls sie existieren.

Übrigens - tun Sie das NICHT:

string AcctCurrency = AccountCurrency();
       
      if (AcctCurrency == "")
          return(rates_total);

Sie haben die Absicht des Codes missverstanden. Er ist so konzipiert, dass der Indie NICHT ausgeführt wird, bis sich der Server "beruhigt" hat. Deshalb gebe ich 0 zurück. Auf diese Weise wird der Indie-Code erst ausgeführt, wenn alle benötigten Informationen verfügbar sind. Ich habe ehrlich gesagt noch nicht mit OnCalculate() gearbeitet, weil ich es noch nicht brauchte, aber ich kann sagen, dass das, was Sie tun, eine Einladung zur Katastrophe ist. Sie sagen Ihrem Programm nicht: "Führen Sie diesen Code nicht aus, bevor Sie gültige Daten haben", sondern Sie werfen einfach alles in den Wind und hoffen auf das Beste. Um ehrlich zu sein, weiß ich nicht, was Ihr Code tun würde, wenn er keine verlässlichen Informationen vom Server bekäme. Es sieht für mich so aus, als ob sie unnötigerweise Informationen berechnet und weitergibt, die man selbst berechnen würde, wenn man sie bräuchte, und sich die Rechenzeit spart, indem man sich nicht mit dem beschäftigt, was man nicht braucht. Ich bin mir nicht sicher, was sie damit erreichen wollen.

Viel Spaß beim Codieren!

 
ProfessorMetal:


Gern geschehen, Dadas. Allerdings würde ich ObjectDelete() nicht in der Startmethode verwenden. Das macht man am besten in OnDeInit(). Der Grund dafür ist folgender: Wenn Sie den Code in OnStart() oder OnCalculate() einfügen, wird er jedes Mal ausgeführt, wenn ein Tick kommt. Das ist aus zwei Gründen schlecht: 1) Es fügt eine Menge Operationen hinzu, die Zeit verbrauchen, die Sie in einer Echtzeitanwendung nicht verschwenden können, und 2) es macht in den meisten Situationen keinen Sinn, dies zu tun - in der Regel ist es nur von Bedeutung, wenn ein Diagramm de-initialisiert wird. Sie sollten dies nur in den "Startup"-Methoden tun, wenn sich eine Preisänderung in irgendeiner Weise auf Ihre Objekte auswirken wird. Betrachten Sie zum Beispiel das folgende Beispiel (das Teil einer Anwendung ist, die ich zu verkaufen beabsichtige, aber es ist cool, das zu teilen :-) ).

Dieser Code fängt Objekte ab, die von einem abgeschlossenen Handel übrig geblieben sind, falls sie existieren.

Übrigens - tun Sie das NICHT:

Sie haben die Absicht des Codes missverstanden. Er ist so konzipiert, dass der Indie NICHT ausgeführt wird, bis sich der Server "beruhigt" hat. Deshalb gebe ich 0 zurück. Auf diese Weise wird der Indie-Code erst ausgeführt, wenn alle benötigten Informationen verfügbar sind. Ich habe ehrlich gesagt noch nicht mit OnCalculate() gearbeitet, weil ich es noch nicht brauchte, aber ich kann sagen, dass das, was Sie tun, eine Einladung zur Katastrophe ist. Sie sagen Ihrem Programm nicht: "Führen Sie diesen Code nicht aus, bevor Sie gültige Daten haben", sondern Sie werfen einfach alles in den Wind und hoffen auf das Beste. Um ehrlich zu sein, weiß ich nicht, was Ihr Code tun würde, wenn er keine verlässlichen Informationen vom Server bekäme. Es sieht für mich so aus, als ob sie unnötigerweise Informationen berechnet und weitergibt, die man selbst berechnen würde, wenn man sie bräuchte, und sich die Rechenzeit spart, indem man sich nicht mit dem beschäftigt, was man nicht braucht. Ich bin mir nicht sicher, was sie damit erreichen wollen.

Viel Spaß beim Programmieren!


Nochmals vielen Dank!

Ich habe die Antwort auf die schwebenden Etiketten gefunden.

Es sieht so aus, als müssten wir jetzt den Objektanker im Code selbst binden:

https://docs.mql4.com/en/constants/objectconstants/enum_anchorpoint

Ich muss also etwas wie das Folgende hinzufügen:

if(Corner==0) Anchor=ANCHOR_LEFT;
if(Corner==1) Anchor=ANCHOR_RIGHT;
if(Corner==2) Anchor=ANCHOR_LEFT;
if(Corner==3) Anchor=ANCHOR_RIGHT; 

und dann eine weitere Zeile verwenden, um das Objekt zu setzen:

    ObjectSet(objname,OBJPROP_ANCHOR,Anchor);

Das Leben wird auf jeden Fall nicht einfacher!

Und dann hilft das auch nicht weiter!!!

BTW. Ich sage euch, was sie damit erreichen wollen:

Sie wollen so viele Leute wie möglich davon abhalten, mit Codes herumzuspielen.

Es muss so kommerziell wie möglich sein.

Bis vor kurzem konnte fast jeder mit dem einfachen mql4 herumspielen.

Jetzt ist das Ziel, alles zu kommerzialisieren!

 
Dadas:

Dieser B646 ist wirklich fehlerhaft!
Das kann so sein, aber globale Initialisierung fehlgeschlagen ist ein spezifischer Fehler, der nichts mit dieser Diskussion über Objekte Ankerpunkte.
 
ProfessorMetal:


Ihre neue OnCalculate()-Methode ergibt für mich keinen Sinn. Es sieht für mich so aus, als ob sie unnötigerweise Informationen berechnet und weitergibt, die man selbst machen würde, wenn man sie bräuchte, und sich die Rechenzeit spart, indem man sich nicht mit dem beschäftigt, was man nicht braucht. Ich bin mir nicht sicher, was sie damit erreichen wollen.

Viel Spaß beim Programmieren!

OnCalculate liefert das Ergebnis der Berechnung, wie viele Bars bereits vom Indikator verarbeitet wurden. Sie ersetzt die alte Funktion IndicatorCounted. Sie erreicht auch Kompatibilität mit mql5, da die Serien-Arrays per Referenz übergeben werden, im Gegensatz zur alten mql4-Methode, bei der die globalen Serien-Arrays verwendet werden. Vom Standpunkt der Kodierung aus gesehen gibt es nur einen sehr geringen Unterschied.

 

Noch einmal: Gern geschehen, Dadas. Ich hatte vergessen, die ANCHOR-Eigenschaften zu verwenden, obwohl ich sie in einigen meiner Sachen benutze.

SDC, danke für die Info. In der Dokumentation ist der Zweck nicht wirklich klar. Ich vermute, dass die Bedeutung in der Übersetzung vom Russischen ins Englische verloren gegangen ist. Jetzt macht es mehr Sinn. Ich nehme an, dass es nicht anstelle von OnStart(), sondern anstelle von IndicatorCounted() verwendet werden soll. Es wäre eine gute Ergänzung der Dokumentation, ein Beispiel zu geben, das eine Art "vorher" und "nachher" zeigt, um die Ersetzung von IndicatorCounted() durch OnCalculate() zu demonstrieren. Ich werde mir die Dokumentation im Lichte Ihrer Erklärung noch einmal ansehen und sehen, wie die Teile zusammenpassen. Nochmals vielen Dank.

Prof.

 

Sie verwenden int OnCalculate() anstelle von int start(). Es wird bei jedem Tick wie start() ausgeführt. Ein Vorher-Nachher-Bild würde etwa so aussehen,

int start()
  {
   int i=0, limit=0;
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if(counted_bars < 0) return(-1);
//----
   limit = Bars-counted_bars-1;
   for (i = limit; i >= 0; i--)
   {
//---- indicator calculations
   }
   return(0);
  }

//--------------------------------------------------
//--------------------------------------------------

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
   int i=0, limit=0;
//--- check for possible errors
   if(prev_calculated < 0) return(-1);
//---
   limit = rates_total-prev_calculated;
   for(i = limit; i >= 0; i--)
   {
//--- indicator calculations
   }
   return(rates_total);
  }

Die formalen Parameter von OnCalculate machen es eigenständiger, der Programmierer muss sich nicht darauf verlassen, alle möglichen Globals aufzurufen, was in Op-Kreisen offenbar als böser, schlechter Programmierer gilt. In der Praxis gibt es eigentlich keinen großen Unterschied zwischen den beiden Methoden. Außerdem ist OnCalculate das gleiche wie mql5, so dass Sie die Möglichkeit haben, kompatiblen Code zu schreiben.