MagicNumber

 

Hallo,

Bezüglich MagicNumber. Habe nun einen EA mit folgedem laufen:

MQL4:

extern int MagicNumber = 12345;

Ich habe gelesen das man hier aufpassen muss wenn man mehre EA's gleichzeitig laufen lässt, so dass die EA's nicht durcheinander kommen. Was gebe ich nun beim zweiten EA ein?

Danke für Eure Hilfe.

LG
FH

 
Florian Horinka:

Hallo,

Bezüglich MagicNumber. Habe nun einen EA mit folgedem laufen:

MQL4:

extern int MagicNumber = 12345;

Ich habe gelesen das man hier aufpassen muss wenn man mehre EA's gleichzeitig laufen lässt, so dass die EA's nicht durcheinander kommen. Was gebe ich nun beim zweiten EA ein?

Danke für Eure Hilfe.

LG
FH

Na irgendeine andere Zahl. Kannst auch einen Nummerngenerator verwenden.
ulong MagicNumber()                                   // returns a magic number created from _Symbol
{
   string ms="", 
          st=NormalizeSymbol();
   int    sl=StringLen(st),                           // in case of short symbol name eg GOLD
          ii;
          
   for (ii=0; ii<sl; ii++)
      ms=ms+(string)StringGetCharacter(st,ii);
      
   return((ulong)ms);
}
aus meiner großen Schublade gezaubert ;)
 

Brauchst noch was dazu:

string NormalizeSymbol(string aSymbol)                // cut off stupid extensions of specified symbol
{
   return(StringSubstr(aSymbol,0,6));
}

string NormalizeSymbol()                              // cut off stupid extensions of current symbol
 {
   return(NormalizeSymbol(_Symbol));
}

 

Otto,

dann kriegen zwei EAs, die dasselbe Symbol handeln, die gleiche MagicNumber?

Wenn, dann sollte man vielleicht WindowExpertName() verwenden?

Man könnte eigentlich auch eine hash verwenden: https://www.mql5.com/en/code/277, aber int ist nur 9 Zahlen lang (die zehnte kann nur 1 oder 2 annehmen).

Hash functions library
Hash functions library
  • Stimmen: 21
  • 2011.01.27
  • Aleksandr Chugunov
  • www.mql5.com
General purpose hash functions: All three functions are adapted for MQL5 Unicode strings. The results has been verified with Fsum Frontend 1.5.5.1. Radix Conversion: The radix conversion is based on the following sequence of chars: 10 [0..9] + 26 [A..Z] + 26 [a..z] + 33 [А..Я] + 33 [а..я].  The "0-9" digits and "A-Z" english letters...
 

Hi Otto,


danke für deine Antwort. Das heisst ich benötige dann

extern int MagicNumber = 12345; nicht mehr?

Steht bei mir ganz oben im EA unter den properties und würde diese Zeile mit deinem angegeben Text ersetzen oder 

gehört das zu einem der drei Phasen (z.B. void OnTick()) des EA ?

ulong MagicNumber()                                   // returns a magic number created from _Symbol
{
   string ms="", 
          st=NormalizeSymbol();
   int    sl=StringLen(st),                           // in case of short symbol name eg GOLD
          ii;
          
   for (ii=0; ii<sl; ii++)
      ms=ms+(string)StringGetCharacter(st,ii);
      
   return((ulong)ms);
}

string NormalizeSymbol(string aSymbol)                // cut off stupid extensions of specified symbol
{
   return(StringSubstr(aSymbol,0,6));
}

string NormalizeSymbol()                              // cut off stupid extensions of current symbol
 {
   return(NormalizeSymbol(_Symbol));
}

 

Der Code errechnet Dir eine Magic Number abhängig vom Symbol.


Das ist echt schön, Du kannst aber natürlich auch ganz anders vorgehen und einfach Timestamp basierend oder noch ganz anders die Magic vergeben.

Gerne genommen sind auch Geburtsdatum, 42, 69 oder 4711, es ist vollkommen egal, solange es nicht zu Interferenzen der EAs kommt.

Diese ungewollten Effekte kannst Du bei sauberer Implementierung selbst vermeiden (und sogar die Magic ignorieren), wenn Du aber zusätzlich oder ausschließlich EAs einsetzt, deren Programmierung Du nicht kennst, ist das sehr riskant.

Du kannst ja problemlos einen EA programmieren, der statt alle offenen Orders des Symbols,auf das er angewendet wird, stattdessen alle Orders manipuliert oder schließt.

 

Die Verwendung des Symbols zur Generierung der MagicNumber ist durchaus am Sinnvollsten.

Timestamps sind zwar stets eindeutig, aber dann muss man auch Verwaltungscode implementieren, der diesen Timestamp bzw. diese MagicNummer dann bereithält (z.B. nicht nur für den EA selbst, sondern vielleicht auch für andere). Wenn der User den Chart neu öffnet, müßten dann die existierenden Positionen wieder mit dem "damals" verwendeten Timestamp verknüpft werden. Naja, wenn man sich diese Arbeit unbedingt machen will... :-)

Dann ziehe ich doch lieber die Verwendung des Symbols plus ggf. noch den Programm-Namen vor. Warum noch den Programm-Namen? Naja, es kann ja sein, dass ein Benutzer auf die schlaue Idee kommt, für ein und dasselbe Symbol 2 Charts aufzumachen -> auf dem einen EA1 und auf dem anderen Chart EA2 einzusetzen.. Wenn die MagicNummer nur den Symbol-String gehasht hätte, kämen sich EA1 und EA2 dann mit derselben MagicNummer in die Quere. Ouch! Das könnte dem Benutzer teuer zu stehen kommen.

Hier mein Code, falls es Jemandem hilft:


int CreateMagicNumber(const string inputString)
{
        int convertedNumber = 0;

        for (int pos=0; pos < StringLen(inputString); pos++)
        {
                ushort character = StringGetCharacter(inputString, pos);
                //Print("Char '" + ShortToString(character) + "' with ushort value: " + IntegerToString((int)character));

                // rotate on 6 positions only, since the max number of digits in integer max (2 147 483 647) is 11. Note: we add characters with values in 100s. So it's best to set this to 6! 
                int position = (int)MathMod(pos, 6);            
                int addedNumber = (int)MathPow(10, position) * (int)character;
                //Print("Adds converted number '" + IntegerToString(addedNumber) + "' at position " + IntegerToString(position));
                
                convertedNumber += addedNumber;
                //Print("So far converted number is: " + IntegerToString(convertedNumber));
        }
        
        Print("Created magic number from '" + inputString + "': " + IntegerToString(convertedNumber));
        return MathAbs(convertedNumber); // in case of an integer overflow -> return a positive Magic Number
}


Die Position, wo der konvertierte Char platziert wird, ist hier "rotierend". Warum? Es könnte theoretisch 2 Symbole geben wie "EURUSD" und "USDEUR" (nur mal als Annahme!), dann würde ohne ständig versetzte Position nämlich immer dieselbe MagicNumber dabei herauskommen (man addiert ja immer nur die konvertierten Char-Werte auf derselben Stelle -> uncool).

Ansonsten: Toller Thread. Man sieht immer noch zu viele Codebeispiele für EAs mit der MagicNummer als Input.. fürchterlich! :)

 

Warum nicht die Bits der Zeichen/Buchstaben des Symbols direkt 1:1 in das Bitraster einer long Variable schreiben?

//+------------------------------------------------------------------+
//|      create magic number                                         |
//+------------------------------------------------------------------+
long MagicNumber(string symbolstring)
  {
   long magic=0;
   for (int i=0;i<MathMin(StringLen(symbolstring),8);i++)
     {
      magic=magic<<8; //=left shift of binary representation by 8 bits
      magic+=(uchar)StringGetCharacter(symbolstring,i);
     }
   return magic;
  }

Ich bin allerdings nicht gerade routiniert mit "bitwise operations". Sieht da irgendjemand einen Haken?

Hinter dem "MathMin(StringLen..." steht die Überlegung, dass long-Variablen ja max. 8x8=64 Bits aufnehmen können und somit bis zu 8 char Zeichen kodieren könnten. Da die meisten Symbole i.d.R. ja nur 6(-7) Zeichen haben, dürfte aber in der Praxis die 8 ja ohnehin nicht überschritten werden.

 

Man könnte den Wert eines Hexadezimalstrings nehmen. Also so:

sinput uint Magic=0xCafeEA01;

Dann hätte man die Ziffern 0-9/a-f/A-F als Gestaltungsmöglichkeit für einen EA-Namen mit Versionsnummer. Wie oben z.B. Café EA v0.1, wofür auch immer das Café dann steht... =:)

MQL5 erlaubt sogar long Typen als Magic, damit hätte man noch 8 Ziffern mehr:

sinput ulong Magic=0xDeadbeefCafeEA01;

Es gibt sicher sinnvollere Namen für EAs als Deadbeef Café, aber der Fantasie sind ja keine Grenzen gesetzt. :D

 

!!ERROR!! INVALID MAGIC NUMBER: currency pairs other congolese franc (CDF)  / canadian dollar (CAD) forbidden due to HEX encoding limitations ;-)

Im Ernst: Sinn der Sache ist doch, dass man keine Namen oder Nummern mehr manuell zuordnen muss, sondern dass der EA das automatisch macht und verschiedene IDs je nach Währung zuordnet. Wenn ich mir entweder einen String ausdenken muss und/oder dieser für den EA fix ist, kann ich ja auch gleich eine fixe Nummer wie 34567 nehmen. Das mit dem HEX Code ist hübsch, doch ich sehe nicht den Vorteil.

Mögliche Alternative:

(1.) 16 Bit-ID als eindeutigen, einmalig festgelegten Identifikator des EA

        plus

(2.) automatisches 6x8 Bit Char-Encoding des Symbols analog zu meinem obigen Beispiel

in die 8 Byte einer long Variablen schreiben,

also sowas wie "EAEURUSD" oder "EA"+Symbol() (oder für die Freunde kongolesischer Francs auch "xyCDFCAD") in die obige Funktion füttern; die Chance dass ein anderer EA die gleiche Magic Id verwendet liegt dann ja bei immensen 1:2^64 ...

Grund der Beschwerde: