Eindeutiger ID-Generator für einen bestimmten Indikator

 

Ich möchte eine eindeutige ID im Indikatorcode erhalten, um sicherzustellen, dass sich die Indikatoren in einem Diagramm nicht gegenseitig stören.

Ursprünglich habe ich die Funktion MathRand() verwendet, die leider keine eindeutigen Zahlen zurückgibt, wie ich erwartet hatte. Wahrscheinlich läuft der Zufallsgenerator in jedem Indikator unabhängig und erhält den gleichen Anfangswert (ich vermute, es könnte GetTickCount sein), weil mehrere Indikatoren die gleiche ID erhalten.

Daher leite ich die ID derzeit aus dem Namen des Indikators und dem Unterfenster ab, was eine eindeutige Kombination sein könnte. Dennoch ist die Terminal-Implementierung in letzter Zeit instabil, so dass ich gerne eine ID finden würde, die unabhängig von einer Subwindow-Nummer ist.

Hat jemand eine Idee?

 
Ovo:

Haben Sie eine Idee?


... Es kommt darauf an, ob Sie eine ID wollen, die über Neustarts von MT4 hinweg bestehen bleibt. Wahrscheinlich nicht, da Sie versucht haben, MathRand() zu verwenden.

Wenn Sie eine robuste eindeutige ID wollen, können Sie das Betriebssystem mit dem Aufruf CoCreateGuid() um eine Guid bitten. Wenn Sie eine Option wünschen, die keine DLL-Importe erfordert, könnten Sie etwas wie die Inkrementierung eines Zählers in einer globalen MT4-Variablen versuchen: Der erste Indikator erhält den Wert 0 und erhöht den Zähler auf 1; der zweite Indikator erhält den Wert 1 und erhöht den Zähler auf 2 usw.

 
Ovo:

Ich möchte eine eindeutige ID im Indikatorcode erhalten, um sicherzustellen, dass sich die Indikatoren in einem Diagramm nicht gegenseitig stören.

Ursprünglich habe ich die Funktion MathRand() verwendet, die leider keine eindeutigen Zahlen zurückgibt, wie ich erwartet hatte. Wahrscheinlich läuft der Zufallsgenerator in jedem Indikator unabhängig und erhält den gleichen Anfangswert (ich vermute, es könnte GetTickCount sein), weil mehrere Indikatoren die gleiche ID erhalten.

Daher leite ich die ID derzeit aus dem Namen des Indikators und dem Unterfenster ab, was eine eindeutige Kombination sein könnte. Dennoch ist die Terminal-Implementierung in letzter Zeit instabil, so dass ich gerne eine ID finden würde, die unabhängig von einer Subwindow-Nummer ist.

Hat jemand eine Idee?


Haben Sie MathSRand() verwendet, bevor Sie MathRand() verwendet haben?
 
angevoyageur:
Haben Sie MathSRand() verwendet, bevor Sie MathRand() verwendet haben?

Wird dadurch das Problem nicht aufgeschoben? Womit setzen Sie MathSRand() ein? Wenn Sie eine Kopie von MT4 mit Indikatoren starten, die bereits an Charts angehängt sind, dann ist es sehr wahrscheinlich, dass sie denselben Wert für etwas wie GetTickCount() erhalten. Sie brauchen immer noch einen eindeutigen Bezeichner, aber jetzt brauchen Sie einen eindeutigen Bezeichner, den Sie an MathSRand() übergeben können...
 
gchrmt4:
Wird dadurch nicht das Problem aufgeschoben? Womit setzen Sie MathSRand() ein? Wenn Sie eine Kopie von MT4 mit Indikatoren haben, die bereits an Charts angehängt sind, dann ist es sehr wahrscheinlich, dass sie denselben Wert für etwas wie GetTickCount() erhalten. Sie brauchen immer noch einen eindeutigen Bezeichner, aber jetzt brauchen Sie einen eindeutigen Bezeichner, den Sie an MathSRand() übergeben können...

Wenn Indikatoren bereits mit Charts verbunden sind, nehme ich an, dass sie bereits eine eindeutige ID haben, die auf die eine oder andere Weise gespeichert ist. Wahrscheinlich verstehe ich den Zweck dieser eindeutigen ID nicht.

 
gchrmt4:


... Kommt darauf an, ob Sie eine ID wollen, die über Neustarts von MT4 hinweg bestehen bleibt. Wahrscheinlich nicht, da Sie es mit MathRand() versucht haben.

Wenn Sie eine robuste eindeutige ID wollen, können Sie das Betriebssystem mit dem Aufruf CoCreateGuid() um eine Guid bitten. Wenn Sie eine Option wünschen, die keine DLL-Importe erfordert, könnten Sie etwas wie das Inkrementieren eines Zählers in einer globalen MT4-Variablen versuchen: der erste Indikator erhält den Wert 0 und erhöht den Zähler auf 1; der zweite Indikator erhält den Wert 1 und erhöht den Zähler auf 2 usw.


Danke. Ich habe verstanden. Ja, ich möchte eine DLL vermeiden, und ich möchte vermeiden, dass ich Müll hinterlasse - ich benutze den GV-Pool hauptsächlich für globale Einstellungen, und Müll macht meine Übersicht schwieriger. Nichtsdestotrotz kann der gleiche Trick mit einem Label-Objekt durchgeführt werden - ich werde es in Betracht ziehen.

Der Zweck der eindeutigen ID ist es, Objekte in einem Diagramm zu unterscheiden, die durch mehrere Instanzen eines einzelnen Indikators (in verschiedenen Unterfenstern) erstellt wurden. Ich glaube, ich bin nicht der erste, der damit konfrontiert ist. Sie müssen nicht persistent sein, da die Objekte beim Deinit verschwinden.

Eine andere einfache Möglichkeit wäre, auf den zweiten Wert von GetTickCount zu warten... wenn ich den Zeitverlust in Kauf nehme. Oder mit DLL-Zugriff kann ich die Systemzeitstruktur lesen, da sie eine Auflösung von Nanosekunden hat. Aber keine DLL mehr für diese einfache Aufgabe :)

 
angevoyageur:

Wenn Indikatoren bereits an Charts angehängt sind, nehme ich an, dass sie bereits eine eindeutige ID haben, die auf die eine oder andere Weise gespeichert ist. Wahrscheinlich verstehe ich den Zweck dieser eindeutigen ID nicht.

... Ein weiteres Szenario wäre die Anwendung einer Vorlage, die mehrere Kopien desselben Indikators enthält.

Ich persönlich würde dafür die Windows-API verwenden, aber der folgende Code scheint im Hinblick auf die Zuweisung einer eindeutigen Nummer für jeden Indikator pro MT4-Sitzung zu funktionieren:

   GlobalVariableTemp("IndicatorGV");
   GlobalVariableTemp("IndicatorGVMutex");
   while (!GlobalVariableSetOnCondition("IndicatorGVMutex", 1, 0)) {
      // In theory this can enter a 100%-processor-usage loop
      // while waiting for another indicator to free the mutex
      // but in practice this never happens because indicators
      // all run in the same thread (and the mutex is therefore
      // only a safeguard)
   }
   double myVal = GlobalVariableGet("IndicatorGV");
   GlobalVariableSet("IndicatorGV", myVal + 1);
   GlobalVariableSet("IndicatorGVMutex", 0);
 
Ovo:

Danke. Ich verstehe. Ja, ich möchte DLL vermeiden, und ich möchte vermeiden, Müll zu hinterlassen - ich benutze den GV-Pool hauptsächlich für globale Einstellungen, und Müll macht meine Übersicht schwieriger. Nichtsdestotrotz kann der gleiche Trick mit einem Label-Objekt durchgeführt werden - ich werde es in Betracht ziehen.

... versuchen Sie, ein verstecktes Objekt mit der ID xxxx1 zu erstellen, und wenn das nicht klappt, versuchen Sie es mit xxxx2, und dann xxxx3 usw.? So erhalten Sie die ID, die Sie für andere Objekte verwenden können - allerdings entsteht dabei temporärer Müll in Form von Diagrammobjekten und nicht von globalen Variablen.
 
gchrmt4:
... Versuchen Sie, ein verstecktes Objekt mit der ID xxxx1 zu erstellen, und wenn das fehlschlägt, versuchen Sie xxxx2, und dann xxxx3 usw.? Dadurch erhalten Sie die ID, die Sie für andere Objekte verwenden können - allerdings entsteht dadurch temporärer Müll in Form von Diagrammobjekten und nicht in Form von globalen Variablen.
Wenn Sie weniger sichtbaren Müll wollen, könnten Sie versuchen, die Datei xxxx1 mit exklusivem Zugriff zu öffnen, und dann xxxx2 und dann xxxx3 usw.
 
Ovo:

Ich möchte eine eindeutige ID im Indikatorcode erhalten, um sicherzustellen, dass sich die Indikatoren in einem Diagramm nicht gegenseitig stören.

Ursprünglich habe ich die Funktion MathRand() verwendet, die leider keine eindeutigen Zahlen zurückgibt, wie ich erwartet hatte. Wahrscheinlich läuft der Zufallsgenerator in jedem Indikator unabhängig und erhält den gleichen Anfangswert (ich vermute, es könnte GetTickCount sein), weil mehrere Indikatoren die gleiche ID erhalten.

Daher leite ich die ID derzeit aus dem Namen des Indikators und dem Unterfenster ab, was eine eindeutige Kombination sein könnte. Dennoch ist die Terminal-Implementierung in letzter Zeit instabil, so dass ich gerne eine ID finden würde, die unabhängig von einer Subwindow-Nummer ist.

Hat jemand eine Idee?


Was ist das Problem mit der Unterfensternummer?
 
gchrmt4:
Wenn Sie weniger sichtbaren Müll wollen, könnten Sie versuchen, die Datei xxxx1 mit exklusivem Zugriff zu öffnen, und dann xxxx2 und dann xxxx3 usw.

Zum Beispiel (mit WindowHandle() anstelle von ChartID(), weil ChartID() in den Versionen von MT4, die noch weit verbreitet sind, unzuverlässig ist):

int glbMyIdentifier = -1;
int glbLockHandle = 0;
string glbLockFile = "";

int OnInit()
{
   for (int i = 1; i < 10000; i++) {
      string strTestLockFile = StringConcatenate(WindowHandle(Symbol(), Period()), "-", i);
      int lock = FileOpen(strTestLockFile, FILE_WRITE | FILE_BIN);
      if (lock == INVALID_HANDLE) {
      
      } else {
         glbMyIdentifier = i;
         glbLockHandle = lock;
         glbLockFile = strTestLockFile;
         break;
      }
   }   
   
   Print("Allocated: " , glbMyIdentifier);
   
   return(INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
   FileClose(glbLockHandle);
   FileDelete(glbLockFile);
}