
1. Introduzione a MQL5
MQL5 è un linguaggio di programmazione orientato agli oggetti basato su C++ e progettato specificamente per sviluppare strategie di trading automatizzate, script, e indicatori tecnici per MetaTrader 5. È importante avere una conoscenza di base della programmazione, preferibilmente in C++ o simili, per iniziare con MQL5.
2. Ambiente di Sviluppo
Prima di iniziare a programmare, devi avere MetaTrader 5 installato sul tuo computer. MetaTrader 5 include l’editor di MetaQuotes (MetaEditor), che è l’ambiente di sviluppo integrato (IDE) per scrivere e testare il codice MQL5.
Provalo in una piattaforma MT5 demo=> RoboForex – professional services on Forex market – professional services on Forex market
3. Il Primo Script: “Hello, MQL5!”
Iniziamo con un semplice script che stampa un messaggio nel log.
Passaggi:
- Apri MetaEditor.
- Crea un nuovo script:
File > New > Script
. - Inserisci il seguente codice:
//+------------------------------------------------------------------+
//| Script program start function |
//+------------------------------------------------------------------+
void OnStart()
{
- Salva il file con un nome (ad esempio,
HelloMQL5.mq5
).- Compila lo script premendo
F7
.- Esegui lo script in MetaTrader 5.
4. Concetti di Base
Funzioni Principali
- OnStart: Funzione principale per gli script che esegue il codice quando lo script viene avviato.
- OnInit: Funzione di inizializzazione per gli Expert Advisors e gli indicatori.
- OnDeinit: Funzione di deinizializzazione per gli Expert Advisors e gli indicatori.
- OnTick: Funzione principale per gli Expert Advisors, chiamata ad ogni tick di prezzo.
5. Creare un Expert Advisor (EA)
Un Expert Advisor è un programma che esegue operazioni di trading automatizzate.
Passaggi:
- Apri MetaEditor.
- Crea un nuovo Expert Advisor:
File > New > Expert Advisor (template)
.- Inserisci il seguente codice:
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
- Salva il file con un nome (ad esempio,
SimpleEA.mq5
).- Compila l’Expert Advisor premendo
F7
.- Attacca l’EA a un grafico in MetaTrader 5.
6. Lavorare con gli Ordini
Per eseguire operazioni di trading, utilizzerai funzioni per aprire, modificare e chiudere ordini.
Aprire un Ordine di Acquisto
void OnTick()
{
double lot = 0.1;
double price = Ask;
double sl = price - 100 * Point;
double tp = price + 100 * Point;
int ticket = OrderSend(Symbol(), OP_BUY, lot, price, 2, sl, tp, "My Buy Order", 0, 0, clrGreen);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
else
{
Print("OrderSend succeeded, ticket #", ticket);
}
}Andiamo nel dettaglio delle Funzioni Principali
1.
OnStart()
La funzione
OnStart()
è la funzione principale eseguita quando uno script viene avviato. Questa funzione è utilizzata solo negli script.Esempio di
OnStart()
:void OnStart()
{
Print("Hello, MQL5!");
}Spiegazione:
void
: Tipo di ritorno della funzione,void
significa che la funzione non restituisce alcun valore.OnStart()
: Nome della funzione.Print("Hello, MQL5!");
: Stampa il messaggio “Hello, MQL5!” nel log.2.
OnInit()
La funzione
OnInit()
viene chiamata all’inizializzazione di un Expert Advisor o di un indicatore tecnico. Serve per eseguire il codice di inizializzazione.Esempio di
OnInit()
:int OnInit()
{
Print("EA initialized.");
return(INIT_SUCCEEDED);
}Spiegazione:
int
: Tipo di ritorno della funzione,int
significa che la funzione restituisce un valore intero.OnInit()
: Nome della funzione.Print("EA initialized.");
: Stampa il messaggio “EA initialized.” nel log.return(INIT_SUCCEEDED);
: RestituisceINIT_SUCCEEDED
, un codice che indica che l’inizializzazione è avvenuta con successo.3.
OnDeinit()
La funzione
OnDeinit()
viene chiamata quando un Expert Advisor o un indicatore tecnico viene disattivato. Serve per eseguire il codice di deinizializzazione.Esempio di
OnDeinit()
:void OnDeinit(const int reason)
{
Print("EA deinitialized.");
}Spiegazione:
void
: Tipo di ritorno della funzione,void
significa che la funzione non restituisce alcun valore.OnDeinit(const int reason)
: Nome della funzione, con un parametroreason
che specifica il motivo della deinizializzazione.Print("EA deinitialized.");
: Stampa il messaggio “EA deinitialized.” nel log.4.
OnTick()
La funzione
OnTick()
è la funzione principale di un Expert Advisor e viene chiamata ad ogni tick di prezzo. Viene utilizzata per eseguire il codice di trading automatizzato.Esempio di
OnTick()
:void OnTick()
{
double price = Bid;
Print("New tick received, price: ", price);
}Spiegazione:
void
: Tipo di ritorno della funzione,void
significa che la funzione non restituisce alcun valore.OnTick()
: Nome della funzione.double price = Bid;
: Ottiene il prezzo corrente di vendita (Bid).Print("New tick received, price: ", price);
: Stampa il messaggio con il prezzo corrente nel log.5.
OnCalculate()
La funzione
OnCalculate()
è utilizzata negli indicatori tecnici per calcolare i valori dell’indicatore. Questa funzione viene chiamata ogni volta che è necessario aggiornare i valori dell’indicatore.Esempio di
OnCalculate()
:int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
for(int i = 0; i < rates_total; i++)
{
Buffer[i] = iMA(NULL, 0, 14, 0, MODE_SMA, PRICE_CLOSE, i);
}
return(rates_total);
}Spiegazione:
int
: Tipo di ritorno della funzione,int
significa che la funzione restituisce un valore intero.OnCalculate(const int rates_total, ...)
: Nome della funzione con vari parametri che rappresentano i dati di mercato.for(int i = 0; i < rates_total; i++)
: Ciclo che attraversa tutti i dati disponibili.Buffer[i] = iMA(NULL, 0, 14, 0, MODE_SMA, PRICE_CLOSE, i);
: Calcola la media mobile semplice (SMA) a 14 periodi e memorizza i valori nel buffer.return(rates_total);
: Restituisce il numero totale di valori calcolati.Altre Funzioni Utili
Print()
La funzione
Print()
viene utilizzata per stampare messaggi nel log.Esempio di
Print()
:Print("This is a message.");
Print("The current price is: ", price);Spiegazione:
Print("This is a message.");
: Stampa il messaggio “This is a message.” nel log.Print("The current price is: ", price);
: Stampa il messaggio “The current price is: ” seguito dal valore della variabileprice
nel log.
OrderSend()
La funzione
OrderSend()
viene utilizzata per inviare ordini di trading.Esempio di
OrderSend()
:int ticket = OrderSend(Symbol(), OP_BUY, lot, price, 2, sl, tp, "My Buy Order", 0, 0, clrGreen);
Spiegazione:
int ticket
: Variabile che memorizza il numero del ticket dell’ordine.OrderSend(Symbol(), OP_BUY, lot, price, 2, sl, tp, "My Buy Order", 0, 0, clrGreen);
: Invia un ordine di acquisto (buy) con i parametri specificati.
Symbol()
: Simbolo dell’ordine.OP_BUY
: Tipo di ordine (acquisto).lot
: Quantità dell’ordine.price
: Prezzo dell’ordine.2
: Slippage (massimo slippage accettabile).sl
: Stop Loss.tp
: Take Profit."My Buy Order"
: Commento dell’ordine.0
: Magic number.0
: Data di scadenza (0 per nessuna scadenza).clrGreen
: Colore dell’ordine nel grafico.Andiamo nel dettaglio delle funzioni Ordini
Aprire operazioni (ordini) in MQL5 è una delle funzionalità più importanti per chi desidera automatizzare il trading. Le funzioni principali che utilizzerai per aprire, modificare e chiudere operazioni sono
OrderSend()
,OrderModify()
, eOrderClose()
. Vediamo ciascuna di queste funzioni in dettaglio.1.
OrderSend()
La funzione
OrderSend()
è utilizzata per inviare ordini al mercato. Questa funzione può essere utilizzata per aprire ordini di acquisto (buy) e vendita (sell), nonché ordini pendenti.Sintassi di
OrderSend()
:int OrderSend( string symbol, int action, double volume, double price, int slippage, double stoploss, double takeprofit, string comment, int magic, datetime expiration, color arrow_color );
Esempio di utilizzo per aprire un ordine di acquisto (Buy):
void OnTick() { double lot = 0.1; double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - 100 * _Point; double tp = price + 100 * _Point; int slippage = 2; string comment = "My Buy Order"; int magic = 0; color arrow_color = clrGreen; int ticket = OrderSend(_Symbol, OP_BUY, lot, price, slippage, sl, tp, comment, magic, 0, arrow_color); if(ticket < 0) { Print("OrderSend failed with error #", GetLastError()); } else { Print("OrderSend succeeded, ticket #", ticket); } }
Spiegazione dei parametri:
symbol
: Il simbolo dell’ordine (ad es. EURUSD).action
: Tipo di ordine (ad es.OP_BUY
per un ordine di acquisto,OP_SELL
per un ordine di vendita).volume
: Quantità dell’ordine (in lotti).price
: Prezzo al quale l’ordine deve essere eseguito.slippage
: Slippage massimo accettabile (differenza tra il prezzo richiesto e il prezzo effettivo).stoploss
: Livello di Stop Loss.takeprofit
: Livello di Take Profit.comment
: Commento associato all’ordine.magic
: Numero magico per identificare l’ordine.expiration
: Data di scadenza per ordini pendenti (0 per nessuna scadenza).arrow_color
: Colore della freccia visualizzata nel grafico per l’ordine.2.
OrderModify()
La funzione
OrderModify()
è utilizzata per modificare i parametri di un ordine esistente, come il livello di Stop Loss o Take Profit.Sintassi di
OrderModify()
:bool OrderModify( int ticket, double price, double stoploss, double takeprofit, datetime expiration, color arrow_color );
Esempio di utilizzo per modificare un ordine:
void ModifyOrder(int ticket, double new_sl, double new_tp) { double price = 0; datetime expiration = 0; color arrow_color = clrYellow; bool result = OrderModify(ticket, price, new_sl, new_tp, expiration, arrow_color); if(!result) { Print("OrderModify failed with error #", GetLastError()); } else { Print("OrderModify succeeded for ticket #", ticket); } }
Spiegazione dei parametri:
ticket
: Numero del ticket dell’ordine da modificare.price
: Nuovo prezzo dell’ordine (0 per mantenere il prezzo attuale).stoploss
: Nuovo livello di Stop Loss.takeprofit
: Nuovo livello di Take Profit.expiration
: Nuova data di scadenza (0 per mantenere la scadenza attuale).arrow_color
: Nuovo colore della freccia nel grafico.3.
OrderClose()
La funzione
OrderClose()
è utilizzata per chiudere un ordine esistente.Sintassi di
OrderClose()
:bool OrderClose( int ticket, double lots, double price, int slippage, color arrow_color );
Esempio di utilizzo per chiudere un ordine:
void CloseOrder(int ticket) { double lots = OrderLots(); double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); int slippage = 2; color arrow_color = clrRed; bool result = OrderClose(ticket, lots, price, slippage, arrow_color); if(!result) { Print("OrderClose failed with error #", GetLastError()); } else { Print("OrderClose succeeded for ticket #", ticket); } }
Spiegazione dei parametri:
ticket
: Numero del ticket dell’ordine da chiudere.lots
: Quantità da chiudere (può essere parte della quantità totale).price
: Prezzo al quale chiudere l’ordine.slippage
: Slippage massimo accettabile.arrow_color
: Colore della freccia nel grafico.Esercizi Pratici
Esercizio 1: Aprire un ordine di acquisto con Stop Loss e Take Profit
void OnTick() { double lot = 0.1; double price = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double sl = price - 50 * _Point; double tp = price + 50 * _Point; int slippage = 2; string comment = "Buy Order with SL and TP"; int magic = 12345; color arrow_color = clrGreen; int ticket = OrderSend(_Symbol, OP_BUY, lot, price, slippage, sl, tp, comment, magic, 0, arrow_color); if(ticket < 0) { Print("OrderSend failed with error #", GetLastError()); } else { Print("OrderSend succeeded, ticket #", ticket); } }
Esercizio 2: Modificare un ordine esistente
void ModifyOrder(int ticket) { double new_sl = SymbolInfoDouble(_Symbol, SYMBOL_BID) - 50 * _Point; double new_tp = SymbolInfoDouble(_Symbol, SYMBOL_BID) + 50 * _Point; datetime expiration = 0; color arrow_color = clrYellow; bool result = OrderModify(ticket, 0, new_sl, new_tp, expiration, arrow_color); if(!result) { Print("OrderModify failed with error #", GetLastError()); } else { Print("OrderModify succeeded for ticket #", ticket); } }
Esercizio 3: Chiudere un ordine esistente
void CloseOrder(int ticket) { double lots = OrderLots(); double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); int slippage = 2; color arrow_color = clrRed; bool result = OrderClose(ticket, lots, price, slippage, arrow_color); if(!result) { Print("OrderClose failed with error #", GetLastError()); } else { Print("OrderClose succeeded for ticket #", ticket); } }
Questi esempi dovrebbero fornirti una buona comprensione di come aprire, modificare e chiudere operazioni in MQL5.
Andiamo nel dettaglio delle funzioni variabili globali
In MQL5, le variabili globali sono variabili definite fuori da qualsiasi funzione e sono accessibili da tutte le funzioni all’interno dello stesso script, EA (Expert Advisor) o indicatore. Sono utili per conservare informazioni che devono essere condivise tra diverse parti del programma. Vediamo una spiegazione dettagliata di ciascuna variabile globale utilizzata nel nostro esempio di Expert Advisor.
Variabili Globali Utilizzate nel Nostro Esempio
1.
input double Lots = 0.1;
- Tipo:
double
- Descrizione: Questa variabile specifica il volume dell’ordine che desideriamo aprire. Il tipo
input
permette all’utente di modificare il valore di questa variabile dalle proprietà dell’EA, senza dover modificare il codice sorgente.- Esempio di utilizzo: Se vogliamo aprire un ordine con un volume di 0.1 lotti, utilizziamo
Lots
nella funzioneOrderSend
.2.
input int Slippage = 2;
- Tipo:
int
- Descrizione: Questa variabile specifica lo slippage massimo accettabile, ossia la differenza massima accettabile tra il prezzo richiesto e il prezzo effettivo di esecuzione dell’ordine. Come
input
, il valore può essere impostato dall’utente.- Esempio di utilizzo: Utilizziamo
Slippage
nella funzioneOrderSend
per specificare lo slippage massimo.3.
input double TakeProfit = 50;
- Tipo:
double
- Descrizione: Questa variabile specifica il livello di Take Profit in punti. Il valore può essere modificato dall’utente. Indica la distanza dal prezzo di apertura alla quale vogliamo chiudere l’ordine in profitto.
- Esempio di utilizzo: Utilizziamo
TakeProfit
per calcolare il livello di Take Profit nel nostro ordine.4.
input double StopLoss = 50;
- Tipo:
double
- Descrizione: Questa variabile specifica il livello di Stop Loss in punti. Il valore può essere modificato dall’utente. Indica la distanza dal prezzo di apertura alla quale vogliamo chiudere l’ordine in perdita.
- Esempio di utilizzo: Utilizziamo
StopLoss
per calcolare il livello di Stop Loss nel nostro ordine.5.
input int MA_Period = 14;
- Tipo:
int
- Descrizione: Questa variabile specifica il periodo della media mobile semplice (SMA) che utilizziamo per prendere decisioni di trading. Il valore può essere modificato dall’utente.
- Esempio di utilizzo: Utilizziamo
MA_Period
per calcolare la media mobile nel nostro EA.6.
double ma;
- Tipo:
double
- Descrizione: Questa variabile memorizza il valore corrente della media mobile. Non è un
input
, quindi non può essere modificata dall’utente direttamente. È utilizzata per confrontare il prezzo corrente con la media mobile.- Esempio di utilizzo:
ma
viene calcolata nella funzioneOnInit
e aggiornata nella funzioneOnTick
.7.
int ticket = -1;
- Tipo:
int
- Descrizione: Questa variabile memorizza il numero del ticket dell’ordine aperto. Inizialmente è impostata a -1 per indicare che non c’è alcun ordine aperto. È utilizzata per verificare se c’è già un ordine aperto e per modificare o chiudere l’ordine esistente.
- Esempio di utilizzo:
ticket
viene impostata quando un ordine viene aperto e verificata/modificata nelle funzioniOnTick
eOnDeinit
.Esempio Completo di Utilizzo delle Variabili Globali
input double Lots = 0.1; input int Slippage = 2; input double TakeProfit = 50; input double StopLoss = 50; input int MA_Period = 14; double ma; int ticket = -1; int OnInit() { ma = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 0); return(INIT_SUCCEEDED); } void OnTick() { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double new_ma = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 0); if(price > new_ma && ticket < 0) { double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; ticket = OrderSend(_Symbol, OP_BUY, Lots, price, Slippage, sl, tp, "Buy Order", 0, 0, clrGreen); if(ticket < 0) { Print("OrderSend failed with error #", GetLastError()); } else { Print("OrderSend succeeded, ticket #", ticket); } } if(ticket >= 0 && OrderSelect(ticket, SELECT_BY_TICKET)) { double new_sl = price - StopLoss * _Point; double new_tp = price + TakeProfit * _Point; if(OrderStopLoss() != new_sl || OrderTakeProfit() != new_tp) { bool result = OrderModify(ticket, OrderOpenPrice(), new_sl, new_tp, 0, clrYellow); if(!result) { Print("OrderModify failed with error #", GetLastError()); } else { Print("OrderModify succeeded for ticket #", ticket); } } } if(ticket >= 0 && price >= OrderTakeProfit()) { bool result = OrderClose(ticket, OrderLots(), price, Slippage, clrRed); if(!result) { Print("OrderClose failed with error #", GetLastError()); } else { Print("OrderClose succeeded for ticket #", ticket); ticket = -1; } } ma = new_ma; } void OnDeinit(const int reason) { if(ticket >= 0 && OrderSelect(ticket, SELECT_BY_TICKET)) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); OrderClose(ticket, OrderLots(), price, Slippage, clrRed); ticket = -1; } }
Spiegazione Finale
- Variabili di input: Permettono all’utente di configurare i parametri del trading senza modificare il codice.
- Variabili di stato: Come
ma
eticket
, memorizzano lo stato attuale dell’EA e sono utilizzate per prendere decisioni nel corso dell’esecuzione.Le variabili globali sono essenziali per mantenere lo stato e permettere la comunicazione tra diverse parti del programma. Usando variabili globali in modo appropriato, puoi creare EA e script più organizzati e facili da gestire.
Passiamo all’Expert e creiamo un esempio completo di un Expert Advisor (EA) in MQL5 che utilizza le funzioni per aprire, modificare e chiudere operazioni, possiamo costruire un EA semplice che apre un ordine di acquisto quando il prezzo attraversa una media mobile e chiude l’ordine quando il prezzo raggiunge un certo livello di profitto.
Esempio di Expert Advisor Completo
1. Definizione delle variabili globali:
input double Lots = 0.1; input int Slippage = 2; input double TakeProfit = 50; input double StopLoss = 50; input int MA_Period = 14; double ma; int ticket = -1;
2. Funzione
OnInit()
Inizializziamo l’EA e calcoliamo il valore iniziale della Media Mobile.
int OnInit() { ma = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 0); return(INIT_SUCCEEDED); }
3. Funzione
OnTick()
Questa funzione viene chiamata ad ogni tick di prezzo. Apriamo un ordine di acquisto se il prezzo supera la Media Mobile e non c’è già un ordine aperto. Modifichiamo l’ordine per aggiornare il livello di Stop Loss e Take Profit se necessario, e chiudiamo l’ordine quando il prezzo raggiunge il livello di Take Profit.
void OnTick() { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); double new_ma = iMA(_Symbol, 0, MA_Period, 0, MODE_SMA, PRICE_CLOSE, 0); if(price > new_ma && ticket < 0) { double sl = price - StopLoss * _Point; double tp = price + TakeProfit * _Point; ticket = OrderSend(_Symbol, OP_BUY, Lots, price, Slippage, sl, tp, "Buy Order", 0, 0, clrGreen); if(ticket < 0) { Print("OrderSend failed with error #", GetLastError()); } else { Print("OrderSend succeeded, ticket #", ticket); } } if(ticket >= 0 && OrderSelect(ticket, SELECT_BY_TICKET)) { double new_sl = price - StopLoss * _Point; double new_tp = price + TakeProfit * _Point; if(OrderStopLoss() != new_sl || OrderTakeProfit() != new_tp) { bool result = OrderModify(ticket, OrderOpenPrice(), new_sl, new_tp, 0, clrYellow); if(!result) { Print("OrderModify failed with error #", GetLastError()); } else { Print("OrderModify succeeded for ticket #", ticket); } } } if(ticket >= 0 && price >= OrderTakeProfit()) { bool result = OrderClose(ticket, OrderLots(), price, Slippage, clrRed); if(!result) { Print("OrderClose failed with error #", GetLastError()); } else { Print("OrderClose succeeded for ticket #", ticket); ticket = -1; } } ma = new_ma; }
4. Funzione
OnDeinit()
Questa funzione viene chiamata quando l’EA viene disattivato. Chiudiamo qualsiasi ordine aperto per evitare operazioni lasciate in sospeso.
void OnDeinit(const int reason) { if(ticket >= 0 && OrderSelect(ticket, SELECT_BY_TICKET)) { double price = SymbolInfoDouble(_Symbol, SYMBOL_BID); OrderClose(ticket, OrderLots(), price, Slippage, clrRed); ticket = -1; } }
Spiegazione del Codice
- Definizione delle variabili globali: Definiamo i parametri di input (ad esempio, volume dell’ordine, slippage, take profit, stop loss e periodo della media mobile) e alcune variabili globali per memorizzare il valore della media mobile e il numero del ticket dell’ordine.
- Funzione
OnInit()
: Inizializziamo l’EA calcolando il valore iniziale della media mobile.- Funzione
OnTick()
: Ad ogni tick di prezzo, calcoliamo la nuova media mobile e verifichiamo se il prezzo corrente supera la media mobile. Se lo supera e non c’è già un ordine aperto, apriamo un nuovo ordine di acquisto. Se c’è già un ordine aperto, verifichiamo se è necessario modificare il livello di stop loss o take profit. Se il prezzo raggiunge il livello di take profit, chiudiamo l’ordine.- Funzione
OnDeinit()
: Quando l’EA viene disattivato, chiudiamo qualsiasi ordine aperto per evitare operazioni lasciate in sospeso.Questo esempio completo ti fornisce una panoramica di come aprire, modificare e chiudere operazioni in un Expert Advisor di MQL5.