Gerador de identificação único para um indicador particular

 

Gostaria de obter uma identificação única em código indicador, para garantir que os indicadores em um gráfico não interfiram uns com os outros.

Originalmente, usei a função MathRand(), que infelizmente não retorna números únicos, como eu esperava. Provavelmente o gerador aleatório roda em cada indicador independentemente, e recebe a mesma semente inicial (acho que pode ser GetTickCount), porque vários indicadores ganham a mesma identificação.

Portanto, atualmente eu obtenho o ID a partir do nome do indicador e da subjanela, cuja combinação pode ser única. No entanto, a implementação do Terminal é instável recentemente, então gostaria de encontrar o ID que é independente em um número de subjanela.

Alguma idéia?

 
Ovo:

Alguma idéia?


... Depende se você quer uma identificação que persista em todas as reinicializações do MT4. Provavelmente não dado que você tenha tentado usar MathRand().

Se você quiser uma identificação única e robusta, então você pode pedir ao sistema operacional um guia usando a chamada CoCreateGuid(). Se você quiser uma opção que não envolva importações de DLL, então você poderia tentar algo como incrementar um contador em uma variável global MT4: primeiro indicador recebe o valor 0 e aumenta o contador para 1; segundo indicador recebe o valor 1 e aumenta o contador para 2 etc.

 
Ovo:

Gostaria de obter uma identificação única em código indicador, para garantir que os indicadores em um gráfico não interfiram uns com os outros.

Originalmente, usei a função MathRand(), que infelizmente não retorna números únicos, como eu esperava. Provavelmente o gerador aleatório roda em cada indicador independentemente, e recebe a mesma semente inicial (acho que pode ser GetTickCount), porque vários indicadores ganham a mesma identificação.

Portanto, atualmente eu obtenho o ID a partir do nome do indicador e da subjanela, cuja combinação pode ser única. No entanto, a implementação do Terminal é instável recentemente, então gostaria de encontrar o ID que é independente em um número de subjanela.

Alguma idéia?


Você usou MathSRand() antes de usar MathRand() ?
 
angevoyageur:
Você usou MathSRand() antes de usar MathRand() ?

Isso não é adiar o problema? Com o que você semeia MathSRand()? Se você tiver uma cópia do MT4 começando com indicadores já anexados aos gráficos, então é bem provável que eles tenham o mesmo valor para algo como GetTickCount(). Você ainda precisa de um identificador único, mas agora você precisa de um identificador único que você pode passar para MathSRand()...
 
gchrmt4:
Isso não é adiar o problema? Com o que você semeia MathSRand()? Se você tiver uma cópia do MT4 começando com indicadores já anexados aos gráficos, então é bem provável que eles tenham o mesmo valor para algo como GetTickCount(). Você ainda precisa de um identificador único, mas agora você precisa de um identificador único que você pode passar para MathSRand()...

Se os indicadores já estiverem anexados aos gráficos, suponho que eles já tenham uma identificação única, armazenada de uma forma ou de outra. Provavelmente não entendo o propósito desta identificação única.

 
gchrmt4:


... Depende se você quer uma identificação que persista em todas as reinicializações do MT4. Provavelmente não se sabe se você já tentou usar MathRand().

Se você quiser uma identificação única e robusta, então você pode pedir ao sistema operacional um guia usando a chamada CoCreateGuid(). Se você quiser uma opção que não envolva importações de DLL, então você poderia tentar algo como incrementar um contador em uma variável global MT4: primeiro indicador recebe o valor 0 e aumenta o contador para 1; segundo indicador recebe o valor 1 e aumenta o contador para 2 etc.


Obrigado. Eu entendo. Sim, eu quero evitar DLL, e quero evitar deixar lixo para trás - eu uso o GV pool principalmente para configurações globais, e o lixo ao redor torna minha visão geral mais difícil. No entanto, o mesmo truque pode ser feito com um objeto de etiqueta - posso considerar isso.

A intenção da identificação única é diferenciar objetos em um gráfico, que foram criados por múltiplas instâncias de um único indicador (em diferentes subwindows). Creio que não sou o primeiro a enfrentá-lo. Eles não precisam ser persistentes, pois os objetos desaparecem no deinit.

Outra maneira fácil seria esperar pelo segundo valor do GetTickCount... se eu aceitar a perda de tempo. Ou com acesso à DLL posso ler a estrutura de tempo do sistema, já que ele tem resolução de nanossegundos. Mas não mais DLL para esta simples tarefa :)

 
angevoyageur:

Se os indicadores já estiverem anexados aos gráficos, suponho que eles já tenham uma identificação única, armazenada de uma forma ou de outra. Provavelmente não entendo o propósito desta identificação única.

... Outro cenário seria a aplicação de um modelo que tivesse várias cópias do mesmo indicador.

Eu iria pessoalmente ao API do Windows para isso, mas o seguinte código parece funcionar em termos de alocação de um número único para cada indicador por sessão 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:

Obrigado. Eu entendo. Sim, eu quero evitar DLL, e quero evitar deixar lixo para trás - eu uso a piscina GV principalmente para configurações globais, e o lixo ao redor torna minha visão geral mais difícil. No entanto, o mesmo truque pode ser feito com um objeto de etiqueta - posso considerar isso.

... tente criar um objeto escondido com o ID xxxx1, e aquele que falhar tente xxxx2, e depois xxxx3 etc... Isso então lhe dá o ID para usar para outros objetos - embora crie lixo temporário em termos de objetos gráficos em vez de variáveis globais.
 
gchrmt4:
... tente criar um objeto escondido com o ID xxxx1, e aquele que falhar tente xxxx2, e depois xxxx3 etc... Isso então lhe dá o ID para usar para outros objetos - embora crie lixo temporário em termos de objetos gráficos em vez de variáveis globais.
Se você quiser lixo menos visível, você poderia tentar abrir o arquivo xxxx1 com acesso exclusivo, e depois xxxx2 e depois xxxx3, etc.
 
Ovo:

Gostaria de obter uma identificação única em código indicador, para garantir que os indicadores em um gráfico não interfiram uns com os outros.

Originalmente, usei a função MathRand(), que infelizmente não retorna números únicos, como eu esperava. Provavelmente o gerador aleatório roda em cada indicador independentemente, e recebe a mesma semente inicial (acho que pode ser GetTickCount), porque vários indicadores ganham a mesma identificação.

Portanto, atualmente eu obtenho o ID a partir do nome do indicador e da subjanela, cuja combinação pode ser única. No entanto, a implementação do Terminal é instável recentemente, então gostaria de encontrar o ID que é independente em um número de subjanela.

Alguma idéia?


Qual é o problema com o número da subjanela?
 
gchrmt4:
Se você quiser um lixo menos visível, você poderia tentar abrir o arquivo xxxx1 com acesso exclusivo, e depois xxxx2 e depois xxxx3, etc.

Por exemplo (usando WindowHandle() em vez de ChartID(), porque ChartID() não é confiável nas versões do MT4 que ainda estão em amplo 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);
}