Cos'è MQL5 — Il Linguaggio di MetaTrader 5
MQL5 (MetaQuotes Language 5) è il linguaggio di programmazione proprietario sviluppato da MetaQuotes per la piattaforma MetaTrader 5. È un linguaggio compilato, basato sulla sintassi di C++, con supporto completo per la programmazione orientata agli oggetti — classi, ereditarietà, polimorfismo, template.
Rispetto a MQL4 (il predecessore per MT4), MQL5 è profondamente diverso: è più potente, più vicino a un vero linguaggio di programmazione, e ha un ecosistema di librerie standard molto più ricco. La curva di apprendimento è più ripida — ma chi impara MQL5 ha in mano uno strumento professionale che può costruire sistemi della complessità di UlcerZenith Oracle.
| Caratteristica | MQL4 (MT4) | MQL5 (MT5) |
|---|---|---|
| Piattaforma | MetaTrader 4 | MetaTrader 5 |
| Paradigma | Procedurale | OOP + Procedurale |
| Backtesting | OHLC — limitato | Tick data reale |
| Multi-threading | No | Sì |
| Account model | Solo hedging | Netting + Hedging |
| Libreria standard | Minimale | Completa (STL-like) |
| Market Depth | No | Sì |
| Futuro | Deprecato lentamente | Attivamente sviluppato |
I Tre Tipi di Programmi MQL5
Prima di scrivere una riga di codice, devi scegliere quale tipo di programma stai creando. In MQL5 esistono tre tipi fondamentali, ognuno con funzione e struttura diversa:
Architettura Event-Driven — Come Pensa MQL5
MQL5 è un linguaggio event-driven: i tuoi programmi non girano in un loop continuo. Dormono e si svegliano solo quando MetaTrader genera un evento specifico. Ogni tipo di evento corrisponde a una funzione speciale che devi implementare:
La Struttura Base di un Indicatore MQL5
Vediamo la struttura completa di un indicatore MQL5 minimo ma funzionante — uno che calcola e plotta una media mobile semplice. Questo è il template da cui parte ogni indicatore personalizzato:
// ============================================================ // SimpleMA_Example.mq5 — Template indicatore base // Autore: Manuel Trotta · MTInvestments // ============================================================ // --- PROPRIETÀ INDICATORE --- #property copyright "Manuel Trotta - MTInvestments" #property version "1.00" #property indicator_chart_window // sul grafico principale #property indicator_buffers 1 // numero di buffer dati #property indicator_plots 1 // numero di linee plottate // --- PROPRIETÀ PLOT --- #property indicator_label1 "MA" #property indicator_type1 DRAW_LINE #property indicator_color1 clrGold #property indicator_style1 STYLE_SOLID #property indicator_width1 2 // --- PARAMETRI INPUT --- input int InpPeriod = 14; // Periodo MA input ENUM_APPLIED_PRICE InpPrice = PRICE_CLOSE; // --- BUFFER DATI --- double MABuffer[]; // array dove Oracle scrive i valori // --- HANDLE INDICATORI BUILT-IN --- int g_ma_handle; // ============================================================ // OnInit — inizializzazione // ============================================================ int OnInit() { // Collega il buffer all'array SetIndexBuffer(0, MABuffer, INDICATOR_DATA); // Crea handle per la MA built-in g_ma_handle = iMA(_Symbol, _Period, InpPeriod, 0, MODE_SMA, InpPrice); if(g_ma_handle == INVALID_HANDLE) { Print("Errore creazione handle MA: ", GetLastError()); return(INIT_FAILED); } IndicatorSetString(INDICATOR_SHORTNAME, "MA(" + IntegerToString(InpPeriod) + ")"); return(INIT_SUCCEEDED); } // ============================================================ // OnCalculate — calcolo ad ogni tick/barra // ============================================================ 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[]) { // Quante barre devo calcolare? int to_copy = rates_total - prev_calculated; if(to_copy <= 0) to_copy = 1; // sempre almeno 1 // Copia i valori MA dal handle nel buffer if(CopyBuffer(g_ma_handle, 0, 0, to_copy, MABuffer) < 0) { Print("CopyBuffer error: ", GetLastError()); return(0); } return(rates_total); // tutte le barre calcolate } // ============================================================ // OnDeinit — pulizia // ============================================================ void OnDeinit(const int reason) { if(g_ma_handle != INVALID_HANDLE) IndicatorRelease(g_ma_handle); }
Le Funzioni Fondamentali — Il Vocabolario di Base
MQL5 ha centinaia di funzioni built-in. Queste sono quelle che userai in ogni progetto professionale — le funzioni che appaiono decine di volte in UlcerZenith Oracle:
Template EA — Struttura Base di un Expert Advisor
Ecco il template base di un Expert Advisor MQL5 professionale — la struttura che trovi in ogni EA serio, incluso ZENITH EXECUTOR:
#property copyright "Manuel Trotta - MTInvestments" #property version "1.00" #include <Trade\Trade.mqh> // Libreria ordini standard // --- INPUT --- input double InpRiskPercent = 1.0; // Rischio % per trade input double InpSL_Pips = 30.0; // Stop Loss in pips input double InpTP_RR = 3.0; // Take Profit RR input double InpScoreMin = 4.5; // Oracle Score minimo // --- OGGETTI GLOBALI --- CTrade g_trade; // oggetto per gestire ordini bool g_position_open; // flag posizione aperta ulong g_ticket; // ticket dell'ordine corrente // ============================================================ int OnInit() { g_trade.SetExpertMagicNumber(20241987); // magic number univoco g_trade.SetDeviationInPoints(10); // slippage max 1 pip g_position_open = false; Print("EA inizializzato correttamente"); return(INIT_SUCCEEDED); } // ============================================================ void OnTick() { // Lavora solo sulla chiusura di una nuova barra static datetime last_bar_time = 0; datetime current_bar = (datetime)SeriesInfoInteger( _Symbol, PERIOD_H4, SERIES_LASTBAR_DATE); if(current_bar == last_bar_time) return; // stessa barra last_bar_time = current_bar; // Leggi Oracle Score dalla GlobalVariable double oracle_score = GlobalVariableGet("ORACLE_SCORE_EURUSD_H4"); double oracle_dir = GlobalVariableGet("ORACLE_DIR_EURUSD_H4"); // +1.0 = BUY signal, -1.0 = SELL signal, 0 = no signal // Verifica condizioni di ingresso if(oracle_score >= InpScoreMin && !g_position_open) { double lot = CalcLots(InpRiskPercent, InpSL_Pips); double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); double pip = SymbolInfoDouble(_Symbol, SYMBOL_POINT) * 10; if(oracle_dir > 0) // BUY signal { double sl = ask - InpSL_Pips * pip; double tp = ask + InpSL_Pips * pip * InpTP_RR; if(g_trade.Buy(lot, _Symbol, ask, sl, tp, "Oracle")) { g_position_open = true; g_ticket = g_trade.ResultOrder(); Print("BUY aperto · ticket: ", g_ticket, " · lots: ", lot); } } } } // ============================================================ // CalcLots — calcola lotti su % di rischio // ============================================================ double CalcLots(double risk_pct, double sl_pips) { double balance = AccountInfoDouble(ACCOUNT_BALANCE); double risk_money = balance * risk_pct / 100.0; double pip_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE); double lot = risk_money / (sl_pips * pip_value * 10); // Normalizza al lotsize del broker double min_lot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN); double lot_step = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP); lot = MathMax(min_lot, MathRound(lot / lot_step) * lot_step); return(lot); }
GlobalVariables — La Comunicazione tra Programmi
Le GlobalVariables sono il meccanismo con cui Oracle e ZENITH EXECUTOR EA si parlano. Sono variabili double persistenti visibili da tutti i programmi in esecuzione sulla stessa istanza di MT5. Oracle scrive i segnali nelle GlobalVariables, l'EA le legge ad ogni tick:
// ============================================================ // LATO ORACLE (indicatore) — scrive il segnale // ============================================================ void WriteSignalToGV(string symbol, string tf, double score, double direction, double entry, double sl, double tp) { string prefix = "ORACLE_" + symbol + "_" + tf + "_"; GlobalVariableSet(prefix + "SCORE", score); GlobalVariableSet(prefix + "DIRECTION", direction); // +1=BUY -1=SELL GlobalVariableSet(prefix + "ENTRY", entry); GlobalVariableSet(prefix + "SL", sl); GlobalVariableSet(prefix + "TP", tp); GlobalVariableSet(prefix + "TIMESTAMP", (double)TimeCurrent()); } // ============================================================ // LATO EXECUTOR EA — legge il segnale // ============================================================ bool ReadSignalFromGV(string symbol, string tf, double &score, double &direction, double &sl, double &tp) { string prefix = "ORACLE_" + symbol + "_" + tf + "_"; // Verifica che il segnale esista e sia recente (<5 min) if(!GlobalVariableCheck(prefix + "SCORE")) return(false); double ts = GlobalVariableGet(prefix + "TIMESTAMP"); if(TimeCurrent() - (datetime)ts > 300) return(false); // segnale stale score = GlobalVariableGet(prefix + "SCORE"); direction = GlobalVariableGet(prefix + "DIRECTION"); sl = GlobalVariableGet(prefix + "SL"); tp = GlobalVariableGet(prefix + "TP"); return(score >= 4.5 && direction != 0.0); }
Vuoi vedere 12.000 righe
di MQL5 in azione?
UlcerZenith Oracle v78 — tutto quello che hai letto in questa guida, implementato.
Live gratuite: iscriviti alla prossima — Oracle sul grafico MT5 in tempo reale.