Automatische magische Zahl - Seite 2

 
jjc

Ich übersehe hier etwas. Wenn ich zwei Charts für z.B. USDJPY H1 öffne und jedem von ihnen eine Instanz des EA hinzufüge, dann verwenden beide die magische Zahl 9999033.

Ja, diese Option wurde nicht eingebaut, weil ich nie eine Verwendung dafür hatte. Die einzige Möglichkeit, zwischen zwei identischen Charts zu unterscheiden (die ich sehen kann), wäre ein Hash im Fensterhandle...

aber dann würde man die Persistenz über Neustarts und das Schließen von Charts verlieren, und deshalb können oder werden verwaiste Orders als Ergebnis erstellt werden.

 
BarrowBoy

Ist die MT-Terminal-Anwendung also ein "Container" - mit einem einzigen hWnd für <das Ganze>?

Ja. Es ist eine ziemlich typische MDI-Anwendung. Es gibt ein Top-Level-Fenster, das Dinge wie Symbolleisten, Fenster und den MDI-Client-Bereich enthält. Letzterer enthält dann jedes Diagramm, und jedes Diagramm besteht eigentlich aus zwei Fenstern: einem Container mit der Zeichenfläche darin. Jedes dieser Fenster hat sein eigenes hWnd-Handle. Die Funktion WindowHandle() gibt das Handle der Zeichenfläche zurück. Wenn Sie also den API-Aufruf GetParent() dreimal ausführen, erhalten Sie das hWnd des MT4-Fensters der obersten Ebene.

 

fwiw, ich benutze unten und habe nie Duplikate gehabt. Gleiche EA auf bis zu 10 [jede Art] Charts.

Ich habe keine Antwort auf die massiv overkill junk actuals übergeben, um Hash-Funktion. Ich habe einfach alles hineingeschoben, einschließlich der Küchenspüle. d.h. ich bin kein Mathe-Mensch..., ich habe einfach gehämmert und gemeißelt, bis ich nie Wiederholungen hatte - sogar beim Terminal-Start mit 10 Chart-Profilen, die alle denselben EA haben...

Natürlich würde ich gerne eine bessere und besser beschreibbare/logische Methode haben... also fangt an, sie in Stücke zu reißen :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, ich benutze unten und habe nie Duplikate gehabt. Gleiche EA auf bis zu 10 [jede Art] Charts.

Ich habe keine Antwort auf die massiv overkill junk actuals übergeben, um Hash-Funktion. Ich habe einfach alles hineingeschoben, einschließlich der Küchenspüle. d.h. ich bin kein Mathe-Mensch..., ich habe einfach gehämmert und gemeißelt, bis ich nie Wiederholungen hatte - sogar beim Terminal-Start mit 10 Chart-Profilen, die alle denselben EA haben...

Natürlich würde ich gerne eine bessere und besser beschreibbare/logische Methode haben... also fangt an, sie in Stücke zu reißen :O)

Ich mag es. Besonders der gute alte djb2-Hash.

 

Sehr beeindruckende Sachen, Jungs :)

MDI-Container bringen mich zurück <seufz>

Ich bin nach wie vor der Meinung, dass die Magic Numbers zu wichtig sind, um sie willkürlich anzuwenden!

Ich bin mir sicher, dass CB bestätigen würde, dass eine vorhersehbare Wiederherstellung beim Neustart ein extrem wichtiges Element in einem robusten System ist...

FWIW

-BB-

 

Mit diesem Code ist ein EA in der Lage, seine eigenen Aufträge zu erkennen, wenn die Plattform heruntergefahren wird. Es verwendet Globale Variablen, so dass, wenn Sie die EA "inmune", um PC-Shutdown machen wollen, könnte es umgeschrieben werden, um Dateien anstelle von Globalen Variablen zu verwenden. Ich habe auch ein Beispiel angehängt, das eine Position gerade zum Startzeitpunkt öffnet und sie im nächsten Takt schließt. Sie können den Experten im 1M-Zeitrahmen laden, den Metatrader herunterfahren und ihn dann wieder öffnen, einfach auf den nächsten Takt warten, um zu sehen, wie der EA seinen Auftrag schließt. Es wurde weder mit mehreren Graphen bewiesen noch mit mehreren Aufträgen ausgetrickst, aber was denken Sie darüber?

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

Ich mag es. Besonders der gute alte djb2-Hash.

Danke - aber ich fühle mich wirklich beschämt über so ein uninformiertes Stück Code in makeexpertid...

Es ist noch zu früh, aber vielleicht entdeckt jemand den/die Fehler... sollten sie vorhanden sein

 
BarrowBoy wrote >>

Sehr beeindruckende Sachen, Jungs :)

MDI-Container bringen mich zurück <seufz>

Ich bin nach wie vor der Meinung, dass die Magic Numbers zu wichtig sind, um sie willkürlich anzuwenden!

Ich bin mir sicher, dass CB bestätigen würde, dass eine vorhersehbare Wiederherstellung beim Neustart ein extrem wichtiges Element in einem robusten System ist...


FWIW

-BB-

Ich sage immer noch, dass die magischen Zahlen IMHO zu wichtig sind, um sie willkürlich anzuwenden!

sicher BB, vip datums. Ich habe viel zu viel Zeit damit verbracht, ein einzigartiges Datum zu finden, das von mehreren Instanzen eines EA verwendet werden kann. Dieses Datum musste wiederholbar sein, damit alle geöffneten Dateien bei Wiederherstellung/Neustart zugeordnet werden können. Ich wollte die Möglichkeit schaffen, dass eine beliebige Anzahl von gleichen EA-Instanzen (ccy+per chart) "irgendwie" einen eindeutigen Dateinamen öffnen und bei einem Neustart auf magische Weise wieder öffnen...


Fenstergriffdaten könnten dieser "Faktor X" sein?

 
fbj:

sicher BB, vip datums. Ich habe viel zu viel Zeit mit dem Versuch verbracht, ein eindeutiges Datum zu finden, das mehrere Instanzen eines EA verwenden können. Dieses Datum musste wiederholbar sein, damit alle geöffneten Dateien bei Wiederherstellung/Neustart zugeordnet werden können. Ich wollte die Möglichkeit schaffen, dass eine beliebige Anzahl von EA-Instanzen mit demselben Ccy+pro Chart "irgendwie" einen eindeutigen Dateinamen öffnen und beim Neustart auf magische Weise wieder öffnen können...

Ich sehe nicht, wie dies möglich ist, ohne dass entweder MT4 oder der Benutzer jedem EA eine ID zuweist. Oder, genauer gesagt, ich sehe nichts, was nicht etwas sehr Unangenehmes beinhaltet, wie z.B. das Generieren einer eindeutigen ID und das anschließende Ändern der .chr-Datei des EAs, um die ID als Teil der externen Parameter des EAs zu speichern.


Und, zur allgemeinen Unterhaltung, das Folgende bringt die Diskussion nicht wirklich voran, aber es ersetzt die Eingabe in den djb2-Hash durch einen Wert, der garantiert eindeutig ist (auf Kosten der Notwendigkeit von DLL-Aufrufen). Ich weiß nicht, wie gut djb2 bei Dingen wie GUIDs sein soll, aber ich habe gerade versucht, 1.000.000 IDs ohne Kollisionen zu erzeugen. Aber das löst immer noch nicht das Problem des Neustarts.


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

Die Daten des Fenstergriffs könnten der "Faktor X" sein?

Wenn Sie keine Aufträge teilweise schließen würden, könnten Sie den Auftragskommentar verwenden, um das Ursprungspaar/den Zeitrahmen zu speichern...?

Auf diese Weise könnte der EA beim Neustart herausfinden, ob er frühere Aufträge hatte und welche magische Zahl er daher verwenden sollte?

NB

Halten Sie die Kommentare auf < 25 und achten Sie auf LEFT(OrderComments(), 24), da sonst die [sl] oder [tp] Dinge beeinflussen könnten.

Geht davon aus, dass <all history> in der Registerkarte Account History verfügbar bleibt!

FWIW .

-BB-