domenica 21 novembre 2010

Come usare il Magic Number negli expert advisor di metatrader

Il magic number o magic id è un numero che viene utilizzato all'interno di un expert advisor in fase di apertura, chiusura e ricerca degli ordini.

Lo scopo principale di questo numero magico è quello di permettere l'esecuzione di più expert advisor contemporaneamente (o di operazioni manuali) sulla stessa piattaforma senza che gli ordini aperti manualmente, o da un expert, vadano ad interferire con il funzionamento dell'altro.

Provate ad immaginare che cosa succederebbe se le operazioni che aprite venissero chiuse dall'ea in funzione su di un altro grafico di metatrader, sicuramente un disastro incontrollabile.

Non tutti i programmatori però utilizzano il magic number all'interno del loro codice. Quando non si è sicuri,  o non si conosce il funzionamento di un consigliere esperto, l'unica soluzione è quella di farlo girare in modalità stand-alone. Solo in questo caso si è certi che l'ea non interferisca con gli altri ordini.

Andiamo ora a vedere i passi necessari per utilizzare correttamente il magic number:


1) Dichiarare una variabile esterna di tipo intero:

extern   int      e_MagicID                  = 23456;

E' necessario che questo valore sia modificabile dall'esterno, immaginate di utilizzare due consiglieri che aprono ordini con lo stesso magic number, sarebbe come non utilizzarlo.

2) Ricordarsi di inserire il magic number durante l'apertura di tutte le posizioni (è un parametro della funzione OrderSend):

OrderSend(Symbol(), OP_BUY, e_Lots, Ask, 3, Ask - (e_Stoploss*Point), Ask + (e_TakeProfit*Point), "carlo10 EA", e_MagicID, 0, Green);

3) Se la strategia effettua un controllo sul numero/tipo di posizioni aperte dall'ea, considerare solo quelle con lo stesso magic id (la funzione OrderMagicNumber serve proprio a questo scopo):

if((OrderSelect(v_i, SELECT_BY_POS, MODE_TRADES)==true) && (OrderMagicNumber() == e_MagicID))

4) Chiudere esclusivamente le posizioni aperte dal proprio ea:

int total = OrdersTotal();
for(int i=total-1;i>=0;i--){
    OrderSelect(i, SELECT_BY_POS);
    int type   = OrderType();
    switch(type){
        case OP_BUY:  if (OrderSymbol() == Symbol() && (OrderMagicNumber() == e_MagicID)) OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_BID), 5, Red ); break;
        case OP_SELL: if (OrderSymbol() == Symbol() && (OrderMagicNumber() == e_MagicID)) OrderClose( OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(), MODE_ASK), 5, Red );              
    }
}

Se utilizzate questi semplici accorgimenti non dovreste avere problemi ad utilizzare più ea contemporaneamente.
 

14 commenti:

Ale L ha detto...

Ciao Carlo e ciao a tutti. Vi è mai capitato che facendo un backtest (ogni tick) con lo stesso EA su computer differenti vi desse risultati diversi? E' quello che ho notato facendo girare un EA prima sul pc fisso e poi sul portatile, stesso settaggio, stesse impostazioni. Come è possibile?

carlo10 ha detto...

Più che altro i fattori da guardare a mio avviso sono:
- conto demo aperto con lo stesso broker?
- dati aggiornati dal centro storia di metatrader?
- timeframe su cui stai facendo girare il backtest
- affidabilità del backtest

I dati storici cambiano da un broker all'altro quindi è probabile vedere dei dati differenti specie su timeframe bassi.

Ale L ha detto...

Delle 4 ipotesi escluderei l'aggiornamento dei dati che ho fatto su entrambi, il timeframe che è impostato allo stesso modo e la tipologia di backtest (entrambi tick by tick).

Pertanto devo dedurre che probabilmente ho scaricato la demo da due broker diversi...

Scusa Carlo, ma come è possibile che i dati storici siano diversi da un broker a un altro? Le candele non si formano allo stesso modo?

Questo vuol dire che ottimizzando un EA con una demo non è detto che abbia gli stessi risultati con un altro conto?

carlo10 ha detto...

Se stai utilizzando un timeframe molto basso le differenze possono essere notevoli.

Dipende molto anche dalla strategia dell'ea, in teoria se apri ordini sui prezzi di apertura delle candele dovresti avere meno discrepanze.

Comunque questo è uno dei tanti motivi per cui nel forum trovi spesso scritto che i backtest lasciano il tempo che trovano.

Il livello di precisione delle quotazioni salvate per forza di cose non è quello massimo perchè probabilmente occuperebbe troppo spazio e i backtest troppe risorse.

I backtest sono utili per vedere che il codice si comporta effettivamente come desideri, una volta raggiunto questo risultato è consigliabile passare ai test in forward demo.

Ale L ha detto...

Per forward demo intendi allegare l'EA a un grafico e vedere come si comporta in real time?

E' possibile allegare diversi EA allo stesso grafico?

Scusa se ti tartasso di domande...ma sono impaziente di imparare :-)

Visto che ti sto praticamente occupando un blog, se preferisci posso scriverti a un indirizzo mail!

Grazie x la tua disponibilità

carlo10 ha detto...

Scrivimi pure qui, lo preferisco.

Si, il forward demo è il test su un conto demo in real time.

Non puoi attacare più di un EA allo stesso grafico.

Ale L ha detto...

Ciao Carlo, ecco un nuovo quesito che volevo evidenziare, riguarda l'utilizzo del Magic Number. è vero che con il Magic number è possibile utilizzare più EA contemporaneamente, ma è anche vero che se ogni EA contiene la condizione di apertura di un solo ordine per volta è quasi come utilizzare un EA alla volta in quanto se un ordine è stato aperto, gli altri non si apriranno. Quindi mi chiedevo se esiste una funzione tipo OrdersTotal che però non conteggi tutti gli ordini aperti, ma solo quelli aperti sul singolo grafico.

carlo10 ha detto...

L'errore a mio avviso è quello di considerare solo OrdersTotal senza ciclare poi i singoli ordini.

Nell'articolo che ho scritto puoi osservare la seguente condizione:

if((OrderSelect(v_i, SELECT_BY_POS, MODE_TRADES)==true) && (OrderMagicNumber() == e_MagicID))

Questo permette proprio di capire se l'ordine che sto selezionando con orderSelect è stato aperto dall'ea corrente o da un altro.

Ale L ha detto...

In particolare mi riferisco alla condizione che precede l'apertura di un ordine, e cioè:
____________________________________
int total = OrdersTotal();
if(total < 1)
{

//condizioni apertura ordine
.....
____________________________________

Questa condizione ci evita di aprire più di un'ordine alla volta (è utile perchè evita le aperture multiple quando i prezzi oscillano frequentenete e si ripresentano più volte le condizioni per l'apertura), ma credo che valga per tutti i grafici, giusto? Nella variabile OrdersTotal vengono memorizzati tutti gli ordini di un conto, per cui se è già aperto un ordine, anche se i MagicNumber sono diversi, non vengono aperti altri ordini da altri EA su altri grafici. E' corretto?

Ale L ha detto...

Invece vorrei che il codice consenta l'apertura di un solo ordine alla volta ma per ogni grafico/EA. Cioè se su un grafico è aperto un ordine, sia consentito aprire un secondo ordine su un altro chart. Forse la strada giusta è inserire una condizione con OrderSymbol() ?

carlo10 ha detto...

Si, le strade sono 2:
- modificare il magic number ogni volta che attacchi l'ea su di un grafico (è sufficiente inserirlo tra i parametri esterni ed il gioco è fatto)
- aggiungere il controllo su OrderSymbol come hai indicato te

Ale L ha detto...

Quindi se ho capito bene, se inserisco 2 Magic Number diversi, per lo stesso EA, li attacco a 2 chart differenti, entrambi con la condizione (if OrdersTotal < 1 Apri ordine), questi non dovrebbero interferire tra loro? Si apriranno anche 2 ordini?

Io credevo che nella funzione OrdersTotal venissero conteggiati tutti gli ordini aperti (indipendentemente dal chart).

carlo10 ha detto...

La funzione OrdersTotal li conteggia effettivamente tutti ma per come è strutturato il codice dell'articolo la funzione serve solo a trovare il numero totale di ordini aperti per poi selezionarli singolarmente uno ad uno.

Ogni volta che selezioni un ordini verifichi se il suo magic number è uguale a quello impostato nei parametri esterni.

Quindi la risposta, è si, se attacchi lo stesso ea a 2 grafici diversi con magic number diversi non interferiranno tra loro.

Ale L ha detto...

Allora mi stavo ponendo un problema che di fatto non esiste utilizzando il magic number...
Scusa la mia ignoranza in materia :/

Grazie Carlo! :)

Posta un commento