Generatore di ID unico per un particolare indicatore

 

Vorrei ottenere un ID unico nel codice dell'indicatore, per garantire che gli indicatori su un grafico non interferiscano tra loro.

Originariamente, ho usato la funzione MathRand(), che purtroppo non restituisce numeri unici come mi aspettavo. Probabilmente il generatore casuale viene eseguito in ogni indicatore in modo indipendente, e ottiene lo stesso seme iniziale (credo che potrebbe essere GetTickCount), perché più indicatori ottengono lo stesso ID.

Quindi attualmente derivo l'ID dal nome dell'indicatore e dalla sottofinestra, la cui combinazione potrebbe essere unica. Tuttavia l'implementazione del Terminale è instabile di recente, quindi vorrei trovare l'ID che sia indipendente dal numero della sottofinestra.

Qualche idea?

 
Ovo:

Qualche idea?


... Dipende se vuoi un ID che persiste attraverso i riavvii di MT4. Probabilmente no, dato che hai provato a usare MathRand().

Se vuoi un ID univoco robusto, allora puoi chiedere al sistema operativo un Guid usando la chiamata CoCreateGuid(). Se vuoi un'opzione che non implichi importazioni di DLL, allora potresti provare qualcosa come l'incremento di un contatore in una variabile globale MT4: il primo indicatore ottiene il valore 0 e aumenta il contatore a 1; il secondo indicatore ottiene il valore 1 e aumenta il contatore a 2 ecc.

 
Ovo:

Vorrei ottenere un ID unico nel codice dell'indicatore, per garantire che gli indicatori su un grafico non interferiscano tra loro.

Originariamente, ho usato la funzione MathRand(), che purtroppo non restituisce numeri unici come mi aspettavo. Probabilmente il generatore casuale viene eseguito in ogni indicatore in modo indipendente, e ottiene lo stesso seme iniziale (credo che potrebbe essere GetTickCount), perché più indicatori ottengono lo stesso ID.

Quindi attualmente derivo l'ID dal nome dell'indicatore e dalla sottofinestra, la cui combinazione potrebbe essere unica. Tuttavia l'implementazione di Terminal è instabile di recente, quindi vorrei trovare l'ID che sia indipendente dal numero di sottofinestra.

Qualche idea?


Hai usato MathSRand() prima di usare MathRand()?
 
angevoyageur:
Hai usato MathSRand() prima di usare MathRand()?

Questo non è rimandare il problema? Con cosa semini MathSRand()? Se hai una copia di MT4 che si avvia con indicatori già collegati ai grafici, allora è molto probabile che ottengano lo stesso valore per qualcosa come GetTickCount(). Avete ancora bisogno di un identificatore unico, ma ora avete bisogno di un identificatore unico che potete passare a MathSRand...
 
gchrmt4:
Questo non è rimandare il problema? Con cosa semini MathSRand()? Se avete una copia di MT4 che si avvia con indicatori già collegati ai grafici, allora è molto probabile che ottengano lo stesso valore per qualcosa come GetTickCount(). Avete ancora bisogno di un identificatore unico, ma ora avete bisogno di un identificatore unico che potete passare a MathSRand...

Se gli indicatori sono già attaccati ai grafici, suppongo che abbiano già un ID unico, memorizzato in un modo o nell'altro. Probabilmente non capisco lo scopo di questo ID unico.

 
gchrmt4:


... Dipende se vuoi un ID che persiste attraverso i riavvii di MT4. Probabilmente no, dato che avete provato a usare MathRand().

Se volete un ID unico e robusto, allora potete chiedere al sistema operativo un Guid usando la chiamata CoCreateGuid(). Se vuoi un'opzione che non implichi importazioni di DLL, allora potresti provare qualcosa come l'incremento di un contatore in una variabile globale di MT4: il primo indicatore ottiene il valore 0 e aumenta il contatore a 1; il secondo indicatore ottiene il valore 1 e aumenta il contatore a 2 ecc.


Grazie. Ho capito. Sì, voglio evitare la DLL, e voglio evitare di lasciarmi dietro della spazzatura - uso il pool GV principalmente per le impostazioni globali, e la spazzatura in giro rende la mia panoramica più difficile. Tuttavia lo stesso trucco può essere fatto con un oggetto etichetta - potrei considerarlo.

L'intenzione dell'ID unico è di differenziare gli oggetti su un grafico, che sono stati creati da più istanze di un singolo indicatore (in diverse sottofinestre). Credo di non essere il primo ad affrontarlo. Non è necessario che siano persistenti, dato che gli oggetti scompaiono alla disattivazione.

Un altro modo semplice sarebbe aspettare il secondo valore di GetTickCount... se accetto di perdere tempo. Oppure con l'accesso alla DLL potrei leggere la struttura temporale del sistema, dato che ha una risoluzione al nanosecondo. Ma niente più DLL per questo semplice compito :)

 
angevoyageur:

Se gli indicatori sono già attaccati ai grafici, suppongo che abbiano già un ID unico, memorizzato in un modo o nell'altro. Probabilmente non capisco lo scopo di questo ID unico.

... Un altro scenario sarebbe applicare un modello che ha più copie dello stesso indicatore in esso.

Personalmente andrei all'API di Windows per questo, ma il seguente codice sembra funzionare in termini di assegnazione di un numero unico per ogni indicatore per sessione MT4:

   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:

Grazie. Ho capito. Sì, voglio evitare la DLL, e voglio evitare di lasciare spazzatura dietro di me - uso il pool GV principalmente per le impostazioni globali, e la spazzatura intorno rende la mia panoramica più difficile. Tuttavia lo stesso trucco può essere fatto con un oggetto etichetta - potrei considerarlo.

... prova a creare un oggetto nascosto con l'ID xxxx1, e se questo fallisce prova xxxx2, e poi xxxx3 ecc? Questo ti dà l'ID da usare per altri oggetti - anche se crea spazzatura temporanea in termini di oggetti grafico piuttosto che variabili globali.
 
gchrmt4:
... prova a creare un oggetto nascosto con l'ID xxxx1, e se questo fallisce prova xxxx2, e poi xxxx3 ecc? Questo vi dà l'ID da usare per altri oggetti - anche se crea spazzatura temporanea in termini di oggetti grafici piuttosto che variabili globali.
Se volete meno spazzatura visibile, potreste provare ad aprire il file xxxx1 con accesso esclusivo, e poi xxxx2 e poi xxxx3 ecc.
 
Ovo:

Vorrei ottenere un ID unico nel codice dell'indicatore, per garantire che gli indicatori su un grafico non interferiscano tra loro.

Originariamente, ho usato la funzione MathRand(), che purtroppo non restituisce numeri unici come mi aspettavo. Probabilmente il generatore casuale viene eseguito in ogni indicatore in modo indipendente, e ottiene lo stesso seme iniziale (credo che potrebbe essere GetTickCount), perché più indicatori ottengono lo stesso ID.

Quindi attualmente derivo l'ID dal nome dell'indicatore e dalla sottofinestra, la cui combinazione potrebbe essere unica. Tuttavia l'implementazione del Terminale è instabile di recente, quindi vorrei trovare l'ID che sia indipendente dal numero della sottofinestra.

Qualche idea?


Qual è il problema con il numero di sottofinestra?
 
gchrmt4:
Se volete meno spazzatura visibile, potreste provare ad aprire il file xxxx1 con accesso esclusivo, e poi xxxx2 e poi xxxx3 ecc.

Per esempio (usando WindowHandle() invece di ChartID(), perché ChartID() non è affidabile nelle versioni di MT4 che sono ancora in uso):

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);
}
Motivazione: