Número mágico automático - página 2

 
jjc:

Está me faltando algo aqui. Se eu abrir dois gráficos para, por exemplo, USDJPY H1, e adicionar uma instância da EA a cada um deles, então ambos usam o número mágico 9999033.

Sim, essa opção não foi incorporada porque eu nunca tive qualquer utilidade para ela. Somente a possibilidade de distinguir dois gráficos indenéticos (que eu posso ver) seria o hash no manípulo da janela...

mas então você perderia a persistência sobre o reinício e o fechamento do gráfico, e portanto as ordens órfãs poderiam ou serão criadas como resultado.

 
BarrowBoy:

Então o terminal MT é um 'container' - com um único hWnd para <a coisa toda>?

Sim. É uma aplicação MDI bastante típica. Há uma janela de nível superior que contém coisas como barras de ferramentas, painéis e a área do cliente MDI. Esta última contém então cada gráfico, e cada gráfico na verdade consiste de duas janelas: um recipiente com a área de desenho dentro dele. Cada uma destas coisas tem seu próprio cabo hWnd. A função WindowHandle() retorna a alça da área de desenho e, portanto, usando a chamada API GetParent() três vezes, obtém-se o hWnd da janela MT4 de nível superior.

 

fwiw, eu uso abaixo e nunca tive duplicatas. O mesmo EA em até 10 gráficos [de qualquer tipo].

Eu não tenho resposta para o massivamente exagerado número de atuadores de lixo entregue à função de hash. Eu apenas empurrei em tudo, inclusive na pia da cozinha. Ou seja, não sou uma pessoa de matemática..., apenas martelo 'n' arrancado até nunca ter repetições - mesmo na inicialização do terminal com 10 cartas de perfil, todas do mesmo EA...

Obviamente, eu estaria interessado em ter um método melhor e mais descritível/lógico... então comece a rasgá-lo em pedaços :O)

#define EMPTYSTRING     ""
#define EAIDMIN         1
#define EAIDMAX         21473


  //+------------------------------------------------------------------+
//
int iMakeHash (string s1, string s2=EMPTYSTRING, string s3=EMPTYSTRING, string s4=EMPTYSTRING, string s5=EMPTYSTRING
              ,string s6=EMPTYSTRING, string s7=EMPTYSTRING, string s8=EMPTYSTRING, string s9=EMPTYSTRING, string s10=EMPTYSTRING)
{
  /*
  Produce 32bit string hash code from  a string composed of up to TEN concatenated input strings.
  WebRef: http://www.cse.yorku.ca/~oz/hash.html
  KeyWrd: "djb2"
  FirstParaOnPage:
  "  Hash Functions
    A comprehensive collection of hash functions, a hash visualiser and some test results [see Mckenzie
    et al. Selecting a Hashing Algorithm, SP&E 20(2):209-224, Feb 1990] will be available someday. If
    you just want to have a good hash function, and cannot wait, djb2 is one of the best string hash
    functions i know. it has excellent distribution and speed on many different sets of keys and table
    sizes. you are not likely to do better with one of the "well known" functions such as PJW, K&R[1],
    etc. Also see tpop pp. 126 for graphing hash functions.
  "

  NOTES:
  0. WARNING - mql4 strings maxlen=255 so... unless code changed to deal with up to 10 string parameters
     the total length of contactenated string must be <=255
  1. C source uses "unsigned [char|long]", not in MQL4 syntax
  //
  Downside?
    original code uses UNSIGNED - MQL4 not support this, presume could use type double and then cast back to type int.
  */
  string s = StringConcatenate(s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);
  int iHash = 5381;
  int iLast = StringLen(s)-1;
  int iPos=0;

  while( iPos <= iLast )    //while (c = *str++)  [ consume str bytes until EOS hit {isn't C concise!} ]
  {
    //original C code: hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
    iHash = ((iHash << 5) + iHash) + StringGetChar(s,iPos);    //StringGetChar() returns int
    iPos++;
  }
  return(MathAbs(iHash));
  
}//iMakeHash()




  //+------------------------------------------------------------------+
//
int iMakeExpertId ()
{
  int i1a,i2a,i1b,i2b;
  int iExpertId = EAIDMAX+1;
  while(iExpertId<EAIDMIN || iExpertId>EAIDMAX)
  {
    i1a=TimeLocal(); i2a=GetTickCount();
    Sleep(500);
    i1b=TimeLocal(); i2b=GetTickCount();
    MathSrand(iMakeHash(Symbol()
                        ,DoubleToStr(Period(),Digits)
                        ,DoubleToStr(i2a*WindowBarsPerChart()/Period(),Digits-1)
                        ,DoubleToStr(WindowTimeOnDropped()/i2b,Digits+1)
                        ,StringConcatenate(i2a/Period()
                                          ,Symbol()
                                          ,Period()
                                          ,i1a
                                          ,i2b*WindowBarsPerChart()/Period()
                                          ,i1b/WindowBarsPerChart()
                                          ,WindowTimeOnDropped()
                                          )
                        )
              );

    iExpertId = MathRand();  //here, on 2nd rand call, is even btr (tests seem to say this...)
  }

  return(iExpertId);

}//iMakeExpertId()

daaaaamn... these results are when had diff EAIDMAX! Anyway, just can't get the staff these days 0 lol
  /*test extract:
12:06:22 "EXPERT ID = "19736
12:06:21 "EXPERT ID = "16236
12:06:20 "EXPERT ID = "4633
12:06:19 "EXPERT ID = "26753
12:06:18 "EXPERT ID = "28286
12:06:16 "EXPERT ID = "23335
12:06:15 "EXPERT ID = "4036
12:06:14 "EXPERT ID = "12879
12:06:13 "EXPERT ID = "8095

12:06:08 "EXPERT ID = "7940
12:06:07 "EXPERT ID = "10700
12:06:06 "EXPERT ID = "24889
12:06:05 "EXPERT ID = "16055
12:06:04 "EXPERT ID = "12774
12:06:03 "EXPERT ID = "10058
12:06:02 "EXPERT ID = "29346
12:06:01 "EXPERT ID = "14624
12:06:00 "EXPERT ID = "18432
*/
 
fbj:

fwiw, eu uso abaixo e nunca tive duplicatas. O mesmo EA em até 10 gráficos [de qualquer tipo].

Eu não tenho resposta para o massivamente exagerado número de atuadores de lixo entregue à função de hash. Eu apenas empurrei em tudo, inclusive na pia da cozinha. Ou seja, não sou uma pessoa de matemática..., apenas martelo 'n' arrancado até nunca ter repetições - mesmo na inicialização do terminal com 10 cartas de perfil, todas do mesmo EA...

Obviamente, eu estaria interessado em ter um método melhor e mais descritível/lógico... então comece a rasgá-lo em pedaços :O)

Eu gosto disso. Particularmente o bom velho haxixe djb2.

 

Muito impressionantes calças de couro :)

Os recipientes MDI me levam de volta <sigh>

Eu ainda digo que, IMHO, Números Mágicos são muito importantes para serem aplicados de forma aleatória!

Tenho certeza que a CB confirmaria que a recuperação previsível no reinício é um elemento extremamente importante em um sistema robusto...

FWIW

-BB-

 

Com este código uma EA é capaz de reconhecer suas próprias ordens se a plataforma for desativada. Ele usa Variáveis Globais, portanto, se você quiser tornar o EA "inmune" ao desligamento do PC, ele poderá ser reescrito para usar arquivos em vez de Variáveis Globais. Anexei também um exemplo que abre uma posição apenas na hora do init e a fecha na próxima barra, você pode carregar o especialista em 1M de tempo, fechar o metatrader e depois abri-lo novamente, basta esperar a próxima barra para ver como a EA fecha seu pedido. Não foi provado com vários gráficos nem enganado com várias ordens, mas o que você pensa sobre isso?

int MagicNumber;
 
int init()
{
   // Unique sting id.    
   string id = WindowExpertName() + Symbol() + Period();
    
    
   // If there isn't already a Global Variable with the id in wich search for the MagicNumber create it  
   if(!GlobalVariableCheck( id))
   {
      MagicNumber = WindowHandle(Symbol(),0);   
      GlobalVariableSet( id, MagicNumber);
   }
   else // Just get the MagicNumber for the unique id
   {
      MagicNumber = GlobalVariableGet( id);
   }
      
}
Arquivos anexados:
 
jjc wrote >>

Eu gosto disso. Particularmente o bom velho haxixe djb2.

obrigado - mas eu realmente me sinto um pouco descuidado com uma codificação tão desinformada no makeexpertid...

Ainda é cedo, mas talvez alguém consiga detectar a(s) falha(s)... se eles estiverem presentes

 
BarrowBoy wrote >>

Muito impressionantes calças de couro :)

Os recipientes MDI me levam de volta <sigh>

Eu ainda digo que, IMHO, Números Mágicos são muito importantes para serem aplicados de forma aleatória!

Tenho certeza que a CB confirmaria que a recuperação previsível no reinício é um elemento extremamente importante em um sistema robusto...


FWIW

-BB-

Eu ainda digo que, IMHO, Números Mágicos são muito importantes para serem aplicados de forma aleatória!

com certeza BB, vip datums. Eu gastei muito tempo tentando descobrir um dado único que várias instâncias de um EA poderiam usar. Este dado tinha que ser repetível, de modo que todos os arquivos abertos pudessem ser mapeados na recuperação/reinício. Eu queria permitir a possibilidade de qualquer número de instâncias do mesmo gráfico ccy+per EA para "como" abrir um nome de arquivo único e, ao reiniciar, reabrir magicamente...


Os dados da janela podem ser aquele 'fator X' ?

 
fbj:

com certeza BB, vip datums. Passei muito tempo tentando descobrir um dado único que várias instâncias de um EA poderiam utilizar. Este dado tinha que ser repetível, de modo que todos os arquivos abertos pudessem ser mapeados na recuperação/reinício. Eu queria permitir a possibilidade de qualquer número de instâncias do mesmo gráfico ccy+per EA para "como" abrir um nome de arquivo único e, ao reiniciar, reabrir magicamente...

Não consigo ver como isso é possível sem o MT4 ou sem que o usuário atribua uma identificação a cada EA. Ou, mais precisamente, não consigo ver nada que não envolva algo muito desagradável, como gerar uma ID única e depois modificar o arquivo .chr da EA para armazenar a ID como parte dos parâmetros externos da EA.


E, para entretenimento geral, o seguinte não adianta de forma alguma a discussão, mas substitui a entrada para o hash djb2 por um valor que é garantido como único (ao custo de requerer chamadas DLL). Não sei como o djb2 deve ser bom em coisas como GUIDs, mas acabei de tentar gerar 1.000.000 de IDs sem nenhuma colisão. Mas ainda não resolve o problema do reinício.


#import "ole32.dll"
   int CoCreateGuid(int & Bytes[]);
#import

int GenerateMagicNumber()
{
   // Generate a 16-byte GUID
   int Bytes[4];
   CoCreateGuid( Bytes);
   
   // Hash the GUID using djb2
   int iHash = 5381;
   for (int i = 0; i < 4; i++) {
      //original C code: hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
      iHash = (( iHash << 5) + iHash) + Bytes[ i];
   }
   return (MathAbs( iHash));
}
 
fbj wrote >>

Os dados da janela podem ser aquele 'fator X' ?

Se você não estivesse fechando parcialmente nenhum pedido, você poderia usar o comentário do pedido para armazenar as informações sobre o par/tempo de origem...?

Assim, o EA, ao reiniciar, poderia funcionar se tivesse algum pedido anterior e que número mágico ele deveria estar usando?

NB

Mantenha os comentários em < 25 e verifique na ESQUERDA (OrderComments(), 24) senão o material [sl] ou [tp] pode afetar as coisas

Supõe que <todos os históricos> estão disponíveis na guia Histórico de contas!

FWIW

-BB-