Numero magico automatico - pagina 2

 
jjc:

Mi manca qualcosa qui. Se apro due grafici, ad esempio USDJPY H1, e aggiungo un'istanza dell'EA a ciascuno di essi, entrambi utilizzano il numero magico 9999033.

Sì, questa opzione non è stata incorporata perché non ne ho mai avuto bisogno. L'unica possibilità di distinguere tra due grafici indentici (che posso vedere) sarebbe l'hash nella maniglia della finestra...

ma poi si perderebbe la persistenza sui riavvii e la chiusura dei grafici, e quindi gli ordini orfani potrebbero essere creati come risultato.

 
BarrowBoy:

Quindi l'applicazione terminale MT è un 'contenitore' - con una singola hWnd per <l'intera cosa>?

Sì. È un'applicazione MDI abbastanza tipica. C'è una finestra di livello superiore che contiene cose come barre degli strumenti, riquadri e l'area client MDI. Quest'ultima poi contiene ogni grafico, e ogni grafico in realtà consiste di due finestre: un contenitore con l'area di disegno al suo interno. Ognuna di queste cose ha il proprio handle hWnd. La funzione WindowHandle() restituisce l'handle dell'area di disegno, e quindi usando la chiamata API GetParent() tre volte si ottiene l'hWnd della finestra MT4 di primo livello.

 

fwiw, io uso sotto e non ho mai avuto duplicati. Stesso EA su fino a 10 grafici [qualsiasi tipo].

Non ho una risposta alla sovrabbondanza di spazzatura effettiva consegnata alla funzione hash. Ci ho messo dentro tutto, compreso il lavello della cucina. Cioè, non sono un matematico..., ho solo martellato e cesellato fino a quando non ho mai avuto ripetizioni - anche all'avvio del terminale con 10 profili grafici tutti uguali EA...

Ovviamente, mi piacerebbe avere un metodo migliore e più descrivibile/logico... quindi inizia a farlo a pezzi :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, io uso sotto e non ho mai avuto duplicati. Stesso EA su fino a 10 grafici [qualsiasi tipo].

Non ho una risposta alla sovrabbondanza di spazzatura effettiva consegnata alla funzione hash. Ci ho messo dentro tutto, compreso il lavello della cucina. Cioè, non sono un matematico..., ho solo martellato e cesellato fino a quando non ho mai avuto ripetizioni - anche all'avvio del terminale con 10 profili grafici tutti uguali EA...

Ovviamente, mi piacerebbe avere un metodo migliore e più descrivibile/logico... quindi inizia a farlo a pezzi :O)

Mi piace. In particolare il buon vecchio hashtag djb2.

 

Roba molto impressionante ragazzi :)

I contenitori MDI mi riportano indietro <sigh>.

Continuo a dire che, IMHO, i Magic Numbers sono troppo importanti per applicarli a caso!

Sono sicuro che CB confermerebbe che il recupero prevedibile al riavvio è un elemento estremamente importante in un sistema robusto...

FWIW

-BB-

 

Con questo codice un EA è in grado di riconoscere i propri ordini se la piattaforma si spegne. Utilizza Variabili Globali quindi se si vuole rendere l'EA "inmune" allo spegnimento del PC potrebbe essere riscritto per utilizzare file invece di Variabili Globali. Ho allegato anche un esempio che apre una posizione proprio al momento dell'init e la chiude nella barra successiva, si può caricare l'esperto in timeframe 1M, spegnere metatrader e poi riaprirlo, basta aspettare la barra successiva per vedere come l'EA chiude il suo ordine. Non è stato provato con grafici multipli né ingannato con ordini multipli, ma cosa ne pensate?

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);
   }
      
}
File:
 
jjc wrote >>

Mi piace. In particolare il buon vecchio hashish djb2.

grazie - ma mi sento davvero a disagio per un po' di codifica disinformata in makeexpertid...

È ancora presto, ma forse qualcuno individuerà il difetto (o i difetti)... se sono presenti

 
BarrowBoy wrote >>

Roba molto impressionante ragazzi :)

I contenitori MDI mi riportano indietro <sigh>.

Continuo a dire che, IMHO, i Magic Numbers sono troppo importanti per applicarli a caso!

Sono sicuro che CB confermerebbe che il recupero prevedibile al riavvio è un elemento estremamente importante in un sistema robusto...


FWIW

-BB-

Continuo a dire che, IMHO, i Magic Numbers sono troppo importanti per essere applicati a caso!

di sicuro BB, dati vip. Ho passato troppo tempo a cercare di scoprire un dato unico che più istanze di un EA potessero utilizzare. Questo dato doveva essere ripetibile in modo che tutti i file aperti fossero mappabili al recupero/riavvio. Volevo permettere la possibilità a qualsiasi numero di istanze EA dello stesso ccy+per grafico di aprire 'in qualche modo' un nome di file unico e al riavvio magicamente riaprire...


I dati della maniglia della finestra potrebbero essere quel 'fattore X'?

 
fbj:

di sicuro BB, i dati vip. Ho passato troppo tempo a cercare di scoprire un dato unico che più istanze di un EA potessero usare. Questo dato doveva essere ripetibile in modo che tutti i file aperti fossero mappabili al recupero/riavvio. Volevo dare la possibilità a qualsiasi numero di istanze EA dello stesso ccy+per grafico di aprire 'in qualche modo' un nome di file unico e al riavvio magicamente riaprire...

Non riesco a vedere come questo sia possibile senza che MT4 o l'utente assegnino un ID a ciascun EA. O, più precisamente, non vedo nulla che non implichi qualcosa di molto brutto come generare un ID unico e poi modificare il file .chr dell'EA per memorizzare l'ID come parte dei parametri esterni dell'EA.


E, per l'intrattenimento generale, quanto segue non fa realmente avanzare la discussione in alcun modo, ma sostituisce l'input all'hash djb2 con un valore che è garantito essere unico (al costo di richiedere chiamate DLL). Non so quanto sia buono djb2 su cose come i GUID, ma ho appena provato a generare 1.000.000 di ID senza alcuna collisione. Ma ancora non risolve il problema del riavvio.


#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 >>

I dati della maniglia della finestra potrebbero essere quel 'fattore X' ?

Se non stavi chiudendo parzialmente alcun ordine, potevi usare il commento dell'ordine per memorizzare le informazioni sulla coppia/timeframe di origine?

In questo modo l'EA, al riavvio, potrebbe capire se aveva degli ordini precedenti e quale numero magico avrebbe dovuto utilizzare?

NB

Mantenere i commenti a < 25 e controllare il LEFT(OrderComments(), 24) altrimenti la roba [sl] o [tp] potrebbe influenzare le cose

Presume che <tutta la storia> sia lasciata disponibile nella scheda Storia dell'account!

FWIW

-BB-

Motivazione: