Numero magico automatico - pagina 4

 
cloudbreaker:

Mi ha fatto pensare che sarebbe utile documentare (molto concisamente):

1. Criteri per decidere di implementare i numeri magici

2. Criteri per decidere di usare la generazione automatica di numeri magici

3. Criteri per decidere di implementare un livello di persistenza

4. Criteri per decidere su globals vs. accesso ai file per la persistenza

Risposte brevi e del tutto personali...


(2) dipende da una serie di fattori, compreso il fatto che l'utente voglia essere in grado di controllare i numeri magici in modo da poterli usare come un modo per raggruppare i risultati di diverse strategie.

(3) è qualcosa che eviterei se potessi, ma non ci riesco quasi mai (vedi "variabili esterne e cambio di timeframe?"). Sarebbe bello se MT4 fornisse aiuto nel persistere e recuperare lo stato degli EAs. Ma non lo fa.

(4) porta ad una preferenza personale abbastanza forte: Non mi piacciono i globali. Gli utenti possono cancellarli; la memorizzazione è limitata ai numeri; e il formato di gvariables.dat è oscuro. Preferisco di gran lunga i file che, come ultima risorsa se necessario, possono essere modificati utilizzando un editor di testo.


- Mi restano solo 8 post prima di prendermi una pausa per un po'.

Vedo che hai raggiunto il numero magico. Almeno farà caldo dove sei tu...

 

Ho lavorato su questa idea più e più volte, e finalmente sono riuscito a fare quello che volevo. Ecco un generatore di numeri magici che prende il codice ASCII del simbolo e lo aggiunge al timeframe e a un codice personalizzato per generare un numero magico che è unico per il timeframe, il simbolo e l'EA. Se conoscessi un modo per l'EA di leggere il proprio nome, userei l'ASCII di questo invece del codice personalizzato. Con questa debolezza, penso che si adatti ai criteri di cui sopra - andrebbe bene con un crash di sistema perché sceglierebbe lo stesso numero che ha scelto in precedenza al riavvio del sistema. La debolezza che potrei vedere è che sceglierebbe numeri magici duplicati se si fa trading con più di un'istanza dello stesso EA sullo stesso timeframe e simbolo.

Ecco cosa ho:

stringa GetSymbol=Symbol();
int MNSymbol,MNSymbolCalc,MagicNumber;
for(int a=0;a<6;a++)//trasforma il Symbol() in una stringa ASCII e aggiunge ogni carattere in MNSymbol
{
MNSymbolCalc=StringGetChar(GetSymbol, a);
MNSymbolCalc=((MNSymbolCalc-64)*(MathPow(10,(a))));//sottrae 64 b/c i caratteri ASCII iniziano a 65, moltiplica il risultato per la potenza a-esima per chiarezza (non necessario però)
MNSymbol = MNSymbol+MNSymbolCalc;
}
int MNPeriod=Period();

int MNEACode=100000;//Mettere questo numero diverso per ogni EA per evitare che due diversi tipi di EA scelgano lo stesso Magic Number
MagicNumber=MNSymbol+MNPeriod+MNEACode;

 

JT, sì... i "problemi" di duplicazione sono roba da incubi ;)


Come te e sospetto molti, il problema dell'unicità è un tema ricorrente costante che viene attaccato come e quando, ma in qualche modo non sembra mai giusto!

Il mio codice pubblicato in precedenza in questo thread è stato sostituito con il seguente che può essere utile (se non altro per una buona risata :).

***Nota la stringa del nome EA disponibile tramite la chiamata a builtin.

Nel tentativo di rendere multi ccy,per ci sono funzioni locali utilizzate. cioè, mi sono stufato di codificare sempre lo stesso codice di intestazione di funzione per controllare gli effettivi vuoti: ccy,per

da qui il mio uso di _Symbol() e _Period(). Considerazioni di velocità/dimensione imho, anche sull'interprete MT4 non vale la pena di preoccuparsene...

Comunque, forse questo è uno spunto di riflessione...


il mio ragionamento per fare sotto [e documentato nella funzione] è:

Questo è un modo pratico per assicurarsi che se un EA si ferma su un CCY,PER, quando lo si esegue di nuovo in seguito con lo stesso CCY,PER

genererà un giExpertId identico (aka, Magic#). Significa che può riprendere a gestire i trade in sospeso nel pool...

Un altro EA nominato può essere eseguito sullo stesso ambiente grafico senza paura di duplicare i valori.

Pertanto, gli OrderPools avranno ticket con un magic# specifico dell'EA, permettendo la mappatura dei suoi ticket solo per EA.


Il tuo commento su >1 'stesso nome' EA sullo stesso ccy,per è davvero un problema. Alla fine ho deciso che HEY! sii realista... se faccio questo errore allora mi merito un calcio nel didietro per essere stato così sconsiderato, lol

alla fine, come mostrato su questo thread, ci sono zilioni di idee/metodi, ognuno con i loro punti di forza e di debolezza.

Tutto si riduce a ottenere [almeno] un dato unico ogni volta che un EA funziona e questo [per me] è il problema principale.

Non ho mai pensato molto al crash dell'EA/CT che porta al riavvio e alla scatola di vermi che riguarda il riprendere da dove è stato lasciato. Questo è stato risolto ora, finché l'EA autogenizza il suo EAid/magic# con dati che sono unici per il suo ambiente grafico R/T. Sarà sempre lo stesso numero...

Oh beh, buon divertimento!


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

Anche se personalmente preferisco l'impostazione manuale del numero magico, la tua soluzione è abbastanza elegante. Bel codice.


Una correzione - le costanti di stringa hanno una lunghezza massima di 255, le variabili di stringa possono essere molto più grandi, vedi -> https://www.mql5.com/en/forum/123551.

 

Grazie Gordon, il codice sembra funzionare bene, ma alla fine non è certo a prova di proiettile se dovessi eseguire lo stesso EA sullo stesso ambiente grafico - quindi sì... l'impostazione manuale di magic# è il metodo infallibile per eccellenza - non ci sono dubbi!


Per me le stringhe sono sempre state una spina nel fianco. Eppure, la maggior parte delle cose è possibile, per esempio, costruendo in modo incrementale un insieme di strumenti, ognuno dei quali utilizza le funzionalità degli strumenti di livello inferiore.

Inoltre, ricordo che irusoh1 diceva/ricordava che 'questo è tutto', quindi convivete con esso... Beh, per me, ricordo sempre il primo paragrafo del suo post ed è *sempre* nella mia mente ogni volta che arrivo al punto con MT dove la volontà di vivere sciolta :))


Il MQL4 online/offline parla dei tipi di dati di base. Il link alla stringa in entrambi va alle costanti di stringa e sappiamo tutti cosa dice quella pagina del doc... cioè 255bytes.

Capisco perfettamente quello che stai dicendo, ma il thread 29373 è, come la gestione runtime di MQL4 delle stringhe, inconcludente e come jjc e senza dubbio molti altri hanno sperimentato - un po'incerto

Non riesco a trovare alcuna documentazione per supportare il pieno utilizzo del formato della struct da 8byte, se ci fosse documentazione per supportare stringhe più lunghe, sarebbe interessante.

Comunque, in passato ho avuto problemi irrisolvibili usando le stringhe, quindi preferisco attenermi a ciò che dice la documentazione e lavorare intorno ad essa - se necessario.

 
fbj:

Il MQL4 online/offline parla dei tipi di dati di base. Il link alle stringhe in entrambi va alle costanti di stringa e tutti sappiamo cosa dice quella pagina di documenti... cioè 255bytes.

Capisco perfettamente quello che stai dicendo, ma il thread 29373 è, come la gestione runtime di MQL4 delle stringhe, inconcludente e come jjc e senza dubbio molti altri hanno sperimentato - un po'instabile

Non riesco a trovare alcuna documentazione per supportare il pieno utilizzo del formato 8byte struct, se ci fosse documentazione per supportare stringhe più lunghe, sarebbe interessante.

Comunque, in passato ho avuto problemi irrisolvibili usando le stringhe, quindi preferisco attenermi a ciò che dicono i documenti e lavorare intorno ad essi - se necessario.

Attenersi al massimo di 255 è ovviamente la soluzione sicura, anche se ho un bel po' di codice che ignora questo limite e non ho mai incontrato problemi. Ma di nuovo questo codice è per lo più non critico.

So che la documentazione è un po' poco chiara su questo argomento, ma se provate a sfogliare i forum russi (con Google translate) ricordo di aver letto un commento ufficiale di uno dei moderatori che le variabili stringa supportano più di 255byte, ma non riesco a trovarlo ora... Oh beh, immagino che "è così" e dobbiamo conviverci :)

 
fbj:

Non riesco a trovare alcuna documentazione per supportare il pieno utilizzo del formato della struct da 8byte, se ci fosse documentazione per supportare stringhe più lunghe, sarebbe interessante.

Comunque, in passato ho avuto problemi irrisolvibili usando le stringhe, quindi preferisco attenermi a ciò che dice la documentazione e lavorare intorno ad essa - se necessario.

"La lunghezza di una costante di stringa è compresa tra 0 e 255 caratteri. Se la costante di stringa è più lunga, i caratteri superflui sulla destra saranno respinti, e il compilatore avviserà di conseguenza.

La sua rappresentazione interna è una struttura di 8 byte. Il primo elemento della struttura è un intero lungo che contiene la dimensione del buffer distribuito per la linea. Il secondo elemento della struttura è l'indirizzo di ordine 32 del buffer che contiene la linea".

Citato dal dizionario MetaEditor Data Types - String constants

roba affascinante ragazzi...

 

So che questo thread è vecchio, ma vedo che ognuno ha il proprio modo per ottenere un "numero magico" o come lo volete chiamare. Ho anche visto che qualcuno voleva che l'EA fosse in grado di leggere il proprio nome... beh, questo è quello che uso per ottenere il nome del mio EA

Mettete questo nella parte superiore dell'EA:

#define EAName "Metti qui il nome dell'EA"

Quando controlli gli ordini aperti metti questo:

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

Per quando il vostro trade è piazzato assicuratevi di averlo in modo che metta l'EAName per un commento come questo:

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

Poi se vuoi un numero magico, cosa che faresti se volessi eseguire l'EA sulla stessa coppia ma con TF diversi nello stesso momento.........., usa semplicemente questo:

int MagicNumber = Periodo();