Générateur d'ID unique pour un indicateur particulier

 

J'aimerais obtenir un ID unique dans le code d'un indicateur, afin de m'assurer que les indicateurs sur un graphique n'interfèrent pas entre eux.

À l'origine, j'ai utilisé la fonction MathRand(), qui ne renvoie malheureusement pas de numéros uniques comme je l'espérais. Probablement que le générateur aléatoire fonctionne dans chaque indicateur indépendamment, et obtient la même graine initiale (je suppose que cela pourrait être GetTickCount), parce que plusieurs indicateurs obtiennent le même ID.

Donc actuellement, je dérive l'ID du nom de l'indicateur et de la sous-fenêtre, dont la combinaison pourrait être unique. Néanmoins, l'implémentation du Terminal est instable ces derniers temps, et j'aimerais donc trouver un ID qui soit indépendant du numéro de sous-fenêtre.

Une idée ?

 
Ovo:

Une idée ?


... Tout dépend si vous voulez un ID qui persiste à travers les redémarrages de MT4. Probablement pas, étant donné que vous avez essayé d'utiliser MathRand().

Si vous voulez un identifiant unique robuste, vous pouvez demander au système d'exploitation un Guid en utilisant l'appel CoCreateGuid(). Si vous souhaitez une option qui n'implique pas d'importations de DLL, vous pouvez essayer quelque chose comme l'incrémentation d'un compteur dans une variable globale MT4 : le premier indicateur obtient la valeur 0 et augmente le compteur à 1 ; le deuxième indicateur obtient la valeur 1 et augmente le compteur à 2, etc.

 
Ovo:

J'aimerais obtenir un ID unique dans le code d'un indicateur, afin de m'assurer que les indicateurs sur un graphique n'interfèrent pas entre eux.

À l'origine, j'ai utilisé la fonction MathRand(), qui ne renvoie malheureusement pas de numéros uniques comme je l'espérais. Probablement que le générateur aléatoire fonctionne dans chaque indicateur indépendamment, et obtient la même graine initiale (je suppose que cela pourrait être GetTickCount), parce que plusieurs indicateurs obtiennent le même ID.

Donc actuellement, je dérive l'ID du nom de l'indicateur et de la sous-fenêtre, dont la combinaison pourrait être unique. Néanmoins, l'implémentation du Terminal est instable ces derniers temps, et j'aimerais donc trouver un ID qui soit indépendant du numéro de sous-fenêtre.

Une idée ?


Avez-vous utilisé MathSRand() avant d'utiliser MathRand() ?
 
angevoyageur:
Avez-vous utilisé MathSRand() avant d'utiliser MathRand() ?

N'est-ce pas reporter le problème ? Avec quoi ensemencez-vous MathSRand() ? Si vous avez une copie de MT4 qui démarre avec des indicateurs déjà attachés aux graphiques, alors il est fort probable qu'ils obtiennent la même valeur pour quelque chose comme GetTickCount(). Vous avez toujours besoin d'un identifiant unique, mais maintenant vous avez besoin d'un identifiant unique que vous pouvez passer à MathSRand...
 
gchrmt4:
N'est-ce pas reporter le problème ? Avec quoi ensemencez-vous MathSRand() ? Si vous avez une copie de MT4 qui démarre avec des indicateurs déjà attachés aux graphiques, alors il est fort probable qu'ils obtiennent la même valeur pour quelque chose comme GetTickCount(). Vous avez toujours besoin d'un identifiant unique, mais maintenant vous avez besoin d'un identifiant unique que vous pouvez passer à MathSRand...

Si les indicateurs sont déjà attachés aux graphiques, je suppose qu'ils ont déjà un identifiant unique, stocké d'une manière ou d'une autre. Je ne comprends probablement pas l'objectif de cet identifiant unique.

 
gchrmt4:


... Tout dépend si vous voulez un ID qui persiste à travers les redémarrages de MT4. Probablement pas, étant donné que vous avez essayé d'utiliser MathRand().

Si vous voulez un identifiant unique et robuste, vous pouvez demander au système d'exploitation un Guid en utilisant l'appel CoCreateGuid(). Si vous souhaitez une option qui n'implique pas d'importations de DLL, vous pouvez essayer quelque chose comme l'incrémentation d'un compteur dans une variable globale MT4 : le premier indicateur obtient la valeur 0 et augmente le compteur à 1 ; le deuxième indicateur obtient la valeur 1 et augmente le compteur à 2, etc.


Merci. Je comprends. Oui, je veux éviter les DLL, et je veux éviter de laisser des déchets derrière moi - j'utilise le pool GV principalement pour les paramètres globaux, et les déchets autour rendent mon aperçu plus difficile. Néanmoins, la même astuce peut être réalisée avec un objet label - je pourrais l'envisager.

L'objectif de l'ID unique est de différencier les objets sur un graphique, qui ont été créés par plusieurs instances d'un même indicateur (dans différentes sous-fenêtres). Je crois que je ne suis pas le premier à y être confronté. Ils n'ont pas besoin d'être persistants, puisque les objets disparaissent à la désinit.

Un autre moyen facile serait d'attendre la deuxième valeur de GetTickCount... si j'accepte de perdre du temps. Ou avec un accès DLL, je peux lire la structure temporelle du système, puisqu'elle a une résolution en nanosecondes. Mais plus de DLL pour cette simple tâche :)

 
angevoyageur:

Si les indicateurs sont déjà attachés aux graphiques, je suppose qu'ils ont déjà un ID unique, stocké d'une manière ou d'une autre. Je ne comprends probablement pas l'objectif de cet ID unique.

... Un autre scénario consisterait à appliquer un modèle contenant plusieurs copies du même indicateur.

Je me tournerais personnellement vers l'API Windows pour cela, mais le code suivant semble fonctionner en termes d'attribution d'un numéro unique pour chaque indicateur par session 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:

Merci. Je comprends. Oui, je veux éviter les DLL, et je veux éviter de laisser des déchets derrière moi - j'utilise le pool GV principalement pour les paramètres globaux, et les déchets autour rendent ma vue d'ensemble plus difficile. Néanmoins, la même astuce peut être réalisée avec un objet label - je pourrais l'envisager.

... essayez de créer un objet caché avec l'ID xxxx1, et si cela échoue, essayez xxxx2, puis xxxx3, etc ? Cela vous donne alors l'ID à utiliser pour d'autres objets - bien que cela crée des déchets temporaires en termes d'objets graphiques plutôt que de variables globales.
 
gchrmt4:
... essayez de créer un objet caché avec l'ID xxxx1, et si cela échoue, essayez xxxx2, puis xxxx3, etc. Cela vous donne alors l'ID à utiliser pour d'autres objets - bien que cela crée des déchets temporaires en termes d'objets graphiques plutôt que de variables globales.
Si vous voulez des déchets moins visibles, vous pouvez essayer d'ouvrir le fichier xxxx1 avec un accès exclusif, puis xxxx2, puis xxxx3, etc.
 
Ovo:

J'aimerais obtenir un ID unique dans le code d'un indicateur, afin de m'assurer que les indicateurs sur un graphique n'interfèrent pas entre eux.

À l'origine, j'ai utilisé la fonction MathRand(), qui ne renvoie malheureusement pas de numéros uniques comme je l'espérais. Probablement que le générateur aléatoire fonctionne dans chaque indicateur indépendamment, et obtient la même graine initiale (je suppose que cela pourrait être GetTickCount), parce que plusieurs indicateurs obtiennent le même ID.

Donc actuellement, je dérive l'ID du nom de l'indicateur et de la sous-fenêtre, dont la combinaison pourrait être unique. Néanmoins, l'implémentation du Terminal est instable ces derniers temps, et j'aimerais donc trouver un ID qui soit indépendant du numéro de sous-fenêtre.

Une idée ?


Quel est le problème avec le numéro de sous-fenêtre ?
 
gchrmt4:
Si vous voulez moins de déchets visibles, vous pouvez essayer d'ouvrir le fichier xxxx1 avec un accès exclusif, puis xxxx2, puis xxxx3, etc.

Par exemple (en utilisant WindowHandle() au lieu de ChartID(), car ChartID() n'est pas fiable dans les versions de MT4 qui sont encore largement utilisées) :

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