Numéro magique automatique - page 4

 
cloudbreaker:

J'ai pensé qu'il serait utile de documenter (de manière très concise) :

1. Critères de décision pour l'implémentation des nombres magiques

2. Critères pour décider d'utiliser la génération automatique de nombres magiques

3. Critères de décision pour la mise en œuvre d'une couche de persistance 4.

4. Critères pour décider de l'utilisation des globaux ou de l'accès aux fichiers pour la persistance

Réponses brèves et entièrement personnelles...


(2) dépend d'un certain nombre de facteurs, notamment si l'utilisateur veut pouvoir contrôler les nombres magiques afin de les utiliser comme moyen de regrouper les résultats de différentes stratégies.

Le point (3) est quelque chose que j'éviterais si je le pouvais, mais je ne le peux presque jamais (voir "variables externes et changement d'horizon temporel"). Ce serait bien si MT4 fournissait une aide pour la persistance et la récupération de l'état des EA. Mais ce n'est pas le cas.

(4) conduit à une préférence personnelle assez forte : Je n'aime pas les globaux. Les utilisateurs peuvent les supprimer ; le stockage est limité à des nombres ; et le format de gvariables.dat est obscur. Je préfère de loin les fichiers qui, en dernier recours si nécessaire, peuvent être modifiés à l'aide d'un éditeur de texte.


- Il ne me reste plus que 8 messages avant de faire une pause pour un petit moment.

Je vois que vous avez atteint le chiffre magique. Au moins, il va faire chaud là où vous êtes...

 

J'ai travaillé sur cette idée par intermittence, et j'ai finalement réussi à faire ce que je voulais. Voici un générateur de nombres magiques qui prend le code ASCII du symbole et l'ajoute à l'horizon temporel et à un code personnalisé pour générer un nombre magique unique pour l'horizon temporel, le symbole et l'EA. Si je connaissais un moyen pour l'EA de lire son propre nom, j'utiliserais l'ASCII de celui-ci au lieu du code personnalisé. Avec cette faiblesse, je pense qu'il répond aux critères ci-dessus - il serait parfait en cas de panne du système parce qu'il choisirait le même numéro que celui qu'il a choisi précédemment au redémarrage du système. La faiblesse que je pourrais voir est qu'il choisirait des numéros magiques en double si l'on trade plus d'une instance du même EA sur la même période et le même symbole.

Voici ce que j'ai :

string GetSymbol=Symbol() ;
int MNSymbol,MNSymbolCalc,MagicNumber ;
for(int a=0;a<6;a++)//transforme le Symbol() en une chaîne ASCII et ajoute chaque caractère dans MNSymbol
{
MNSymbolCalc=StringGetChar(GetSymbol, a) ;
MNSymbolCalc=((MNSymbolCalc-64)*(MathPow(10,(a))));//soustraire 64 car les caractères ASCII commencent à 65, multiplier le résultat par la puissance a-ième pour la propreté (inutile cependant)
MNSymbol = MNSymbol+MNSymbolCalc ;
}
int MNPeriod=Period() ;

int MNEACode=100000;//Faites en sorte que ce nombre soit différent pour chaque EA afin d'éviter que deux types différents d'EA choisissent le même numéro magique
MagicNumber=MNSymbol+MNPeriod+MNEACode ;

 

JT, oui... les "problèmes" de duplication font partie des cauchemars ;)


Comme vous et, je pense, comme beaucoup d'autres, le problème de l'unicité est un thème récurrent constant qui est attaqué à tout moment, mais qui ne semble jamais correct !

Le code que j'ai publié plus tôt dans ce fil de discussion a été remplacé par le code ci-dessous qui peut être utile (si ce n'est pour une raison autre que de rire un peu :).

***Remarquez la chaîne de nom EA disponible via l'appel au buildin.

Dans les efforts pour rendre le multi ccy,per il y a des fonctions locales utilisées. ie, j'en ai eu marre de toujours coder la même fonction code d'en-tête pour vérifier si les réels sont vides : ccy,per

d'où mon utilisation de _Symbol() et _Period(). Les considérations de vitesse/taille, même sur l'interpréteur MT4, ne valent pas la peine de s'en préoccuper...

Quoi qu'il en soit, peut-être cela donne-t-il matière à réflexion...


Mon raisonnement pour faire ce qui suit [et documenté dans la fonction] est le suivant :

C'est un moyen pratique de s'assurer que SI un EA s'arrête sur un CCY,PER, en le relançant plus tard sur le même CCY,PER, il générera des giExpert identiques.

il générera un giExpertId (aka, Magic#) identique. Cela signifie qu'il peut reprendre la gestion des transactions en cours dans le pool...

Un autre EA nommé peut être exécuté dans le même environnement graphique sans crainte de dupliquer les valeurs.

Par conséquent, les OrderPools auront des tickets avec un Magic# spécifique à l'EA, permettant le mappage par EA de ses tickets uniquement.


Votre commentaire sur >1 EA 'même nom' sur le même ccy,per est effectivement un problème. J'ai finalement décidé que HEY ! soyez réaliste... si je fais cette erreur, je mérite un coup de pied au derrière pour avoir été si irréfléchi, lol

en fin de compte, comme le montre ce fil, il y a des millions d'idées/méthodes, chacune avec ses forces et ses faiblesses.

tout se résume à obtenir [au moins] une donnée unique à chaque fois qu'une EA est exécutée et c'est [pour moi] le problème central.

Je n'ai jamais beaucoup pensé au crash de l'EA/CT menant au redémarrage et à la boîte de Pandore concernant la reprise là où elle a été laissée. C'est réglé maintenant, tant que l'EA génère automatiquement son EAid/magic# avec des données qui sont uniques à son environnement graphique R/T. Il générera toujours le même numéro. Il s'agira toujours du même numéro...

Et bien, amusez-vous bien !


int iMakeExpertId (string sSymbol="",int iPeriod=EMPTY)
{

  return( iMakeHash(_Symbol( sSymbol), getPeriodStr(_Period( iPeriod)),WindowExpertName()) );

}//iMakeExpertId()
//
//
//


//+------------------------------------------------------------------+
//
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 int 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
  2. When you hash a value, you cannot 'unhash' it. Hashing is a one-way process.
     Using traditional symetric encryption techniques (such as Triple-DES) provide the reversible encryption behaviour you require.
     Ref:http://forums.asp.net/t/886426.aspx subj:Unhash password when using NT Security poster:Participant
  //
  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 {myWord! isn't C concise! Pity MQL4 is"!"} ]
  {
    //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()
 
fbj:
  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

Bien que je préfère personnellement le réglage manuel du nombre magique, votre solution est assez élégante. Beau code.


Une correction - les constantes de chaîne ont une longueur maximale de 255, les variables de chaîne peuvent être beaucoup plus grandes, voir -> https://www.mql5.com/en/forum/123551.

 

Merci Gordon, le code semble fonctionner correctement, mais au final, il n'est certainement pas à l'épreuve des balles si j'exécute le même EA sur le même environnement graphique - donc oui... le réglage manuel du magic# est l'ultime méthode infaillible - aucun doute là-dessus !


Pour moi, les chaînes de caractères ont toujours été un casse-tête. Pourtant, presque tout est possible en construisant progressivement un ensemble d'outils, chacun utilisant les fonctionnalités d'outils de niveau inférieur.

De plus, je me souviens qu'irusoh1 a dit/rappelé que "c'est comme ça" et qu'il faut vivre avec... En ce qui me concerne, je me souviens toujours du premier paragraphe du contenu de son post et je l'ai *toujours* à l'esprit lorsque j'arrive à un point où la volonté de vivre avec MT est faible :))


Le MQL4 online/offline parle des types de données de base. Le lien string dans les deux va vers les constantes string et nous savons tous ce que cette page de doc dit... c'est-à-dire 255bytes.

Je comprends parfaitement ce que vous dites, mais le fil de discussion 29373 est, comme la gestion des chaînes par le runtime de MQL4, peu concluant et, comme jjc et sans doute beaucoup d'autres l'ont expérimenté, quelque peu douteux.

Je n'ai pu trouver aucune documentation permettant d'utiliser pleinement le format de la structure de 8 octets. S'il existe une documentation permettant de gérer des chaînes plus longues, ce serait intéressant.

Quoi qu'il en soit, j'ai eu par le passé des problèmes insolubles en utilisant des chaînes de caractères, alors je préfère m'en tenir à ce que dit la documentation et contourner le problème - si nécessaire.

 
fbj:

Le MQL4 online/offline parle des types de données de base. Le lien string dans les deux cas renvoie aux constantes string et nous savons tous ce que dit cette page de documentation... c'est-à-dire 255bytes.

Je comprends parfaitement ce que vous dites, mais le fil de discussion 29373 est, comme la gestion des chaînes par le runtime de MQL4, peu concluant et, comme jjc et sans doute beaucoup d'autres l'ont expérimenté, quelque peu douteux.

Je n'ai pu trouver aucune documentation permettant d'utiliser pleinement le format de la structure de 8 octets. S'il existe une documentation permettant de gérer des chaînes plus longues, ce serait intéressant.

Quoi qu'il en soit, j'ai eu dans le passé des problèmes insolubles en utilisant des chaînes de caractères, donc je préfère m'en tenir à ce que dit la documentation et contourner le problème - si nécessaire.

S'en tenir à 255 est évidemment la solution la plus sûre, bien que j'aie pas mal de code qui ignore cette limite et je n'ai jamais rencontré de problèmes. Mais encore une fois, ce code est principalement non critique.

Je sais que la documentation n'est pas très claire à ce sujet, mais si vous essayez de parcourir les forums russes (avec Google translate), je me souviens avoir lu un commentaire officiel de l'un des modérateurs indiquant que les variables de type chaîne supportent plus de 255bytes, mais je n'arrive pas à le trouver maintenant... Oh bien, je suppose que "ça y est" et que nous devons vivre avec :)

 
fbj:

Je n'ai pas trouvé de documentation permettant d'utiliser pleinement le format de la structure à 8 octets. S'il existe une documentation permettant d'utiliser des chaînes plus longues, ce serait intéressant.

Quoi qu'il en soit, j'ai eu par le passé des problèmes insolubles en utilisant des chaînes de caractères, alors je préfère m'en tenir à ce que dit la documentation et contourner le problème - si nécessaire.

"La longueur d'une constante de chaîne est comprise entre 0 et 255 caractères. Si la constante de chaîne est plus longue, les caractères superflus à droite seront rejetés, et le compilateur alertera en conséquence.

Sa représentation interne est une structure de 8 octets. Le premier élément de la structure est un entier long qui contient la taille du tampon distribué pour la ligne. Le deuxième élément de la structure est l'adresse d'ordre 32 du tampon qui contient la ligne. "

Cité dans le dictionnaire MetaEditor Data Types - String constants

des trucs fascinants les gars...

 

Je sais que ce fil est vieux, mais je vois que tout le monde a sa propre façon d'obtenir un "nombre magique" ou ce que vous voulez l'appeler. J'ai également vu que quelqu'un voulait que son EA soit capable de lire son propre nom... voici ce que j'utilise pour obtenir le nom de mon EA

Placez ceci en haut de l'EA :

#define EAName "Mettez le nom de l'EA ici".

Lorsque vous vérifiez les ordres ouverts, placez ceci :

if (OrderType() <= OP_SELL && OrderSymbol() == Symbol() && OrderComment() == EAName && OrderMagicNumber() == MagicNumber)

Lorsque votre transaction est placée, assurez-vous que le nom de l'EAN est placé pour un commentaire comme celui-ci :

Ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage, 0, 0, EAName, MagicNumber, 0, Blue) ;

Ensuite, si vous voulez un nombre magique, ce qui serait le cas si vous vouliez exécuter l'EA sur la même paire mais sur des TF différents au même moment, utilisez simplement ceci : .......... :

int MagicNumber = Period() ;

Raison: