Il Risultato Finale — Il Messaggio Oracle
Prima del codice, vediamo cosa ottieni alla fine. Ogni mattina Oracle analizza il mercato e invia questo messaggio al canale Telegram gratuito quando trova un segnale valido:
Setup — BotFather e Configurazione MT5
/newbot → scegli un nome e uno username (deve finire in "bot"). BotFather ti darà un token nel formato 1234567890:AABBccDD... — salvalo, ti serve nel codice.-100xxxxxxxxxx per i canali).WebRequest — L'API Completa
WebRequest è la funzione MQL5 che esegue richieste HTTP. In MQL5 esiste in due versioni — usa la versione con headers per le richieste POST all'API Telegram:
// ============================================================ // WebRequest — versione POST per Telegram Bot API // ============================================================ // Firma: // int WebRequest( // string method, // "GET" o "POST" // string url, // URL completo // string headers, // headers HTTP (separati da \r\n) // int timeout, // timeout in ms (min 1000, consigliato 5000) // char &data[], // body della richiesta (POST) // char &result[], // buffer per la risposta // string &result_headers // headers della risposta // ) // Ritorna: HTTP status code (200=OK, -1=errore locale) // Esempio base — GET semplice char data_empty[]; // body vuoto per GET char result[]; string result_headers; int status = WebRequest( "GET", "https://api.telegram.org/bot" + BOT_TOKEN + "/getMe", "", // headers vuoti per GET 5000, // timeout 5 secondi data_empty, result, result_headers ); if(status == 200) Print("Bot OK: ", CharArrayToString(result)); else if(status == -1) PrintFormat("Errore locale: %d (verifica URL permessi)", GetLastError()); else PrintFormat("HTTP %d: ", status, CharArrayToString(result));
Oracle Alert System — Il Codice Completo
Questo è il modulo Oracle_TelegramAlert.mqh — il sistema completo di notifiche Telegram che Oracle usa in produzione. Include formattazione HTML del messaggio, retry automatico su errore, rate limiting per rispettare i limiti dell'API Telegram (max 30 msg/secondo per bot), e log locale:
// ============================================================ // Oracle_TelegramAlert.mqh // Sistema notifiche Telegram per UlcerZenith Oracle v78 // ============================================================ #ifndef ORACLE_TELEGRAM_MQH #define ORACLE_TELEGRAM_MQH // ---- Configurazione — modifica questi valori ---- #define TG_API_URL "https://api.telegram.org/bot" #define TG_TIMEOUT 5000 // 5 secondi #define TG_MAX_RETRY 3 // tentativi prima di rinunciare #define TG_RETRY_MS 2000 // attesa tra retry in ms #define TG_RATE_WAIT 1000 // attesa minima tra messaggi (rate limit) // Timestamp ultimo invio (rate limiting) static datetime s_last_send = 0; // ============================================================ // TGSend — invia testo con formattazione HTML // token: bot token da BotFather // chat_id: ID canale/gruppo (stringa perché può essere negativo) // text: messaggio — supporta HTML con <b>, <i>, <code> // ============================================================ bool TGSend(string token, string chat_id, string text) { // Rate limiting — non inviare troppo velocemente while(TimeCurrent() - s_last_send < 1) // almeno 1 sec tra messaggi Sleep(100); // Costruisce URL endpoint string url = TG_API_URL + token + "/sendMessage"; // Costruisce payload JSON // parse_mode HTML permette grassetto, corsivo, codice string json = "{\"chat_id\":\"" + chat_id + "\"," + "\"text\":\"" + TGEscape(text) + "\"," + "\"parse_mode\":\"HTML\"," + "\"disable_web_page_preview\":true}"; // Converti stringa JSON in char array char post_data[]; StringToCharArray(json, post_data, 0, StringLen(json)); char result[]; string result_headers; string headers = "Content-Type: application/json\r\n"; // Retry loop for(int attempt = 1; attempt <= TG_MAX_RETRY; attempt++) { int status = WebRequest( "POST", url, headers, TG_TIMEOUT, post_data, result, result_headers ); if(status == 200) { s_last_send = TimeCurrent(); Print("TG inviato OK"); return(true); } else if(status == 429) // Too Many Requests { Print("TG rate limit — attendo..."); Sleep(TG_RETRY_MS * attempt); // backoff esponenziale } else if(status == -1) { PrintFormat("TG errore locale tentativo %d/%d: %d", attempt, TG_MAX_RETRY, GetLastError()); if(attempt < TG_MAX_RETRY) Sleep(TG_RETRY_MS); } else { PrintFormat("TG HTTP %d: %s", status, CharArrayToString(result)); break; // errore HTTP non recuperabile } } return(false); } // ============================================================ // TGEscape — escape caratteri speciali JSON // ============================================================ string TGEscape(string text) { StringReplace(text, "\\", "\\\\"); // backslash prima StringReplace(text, "\"", "\\\""); // virgolette StringReplace(text, "\n", "\\n"); // newline StringReplace(text, "\r", ""); // carriage return return(text); } // ============================================================ // TGSendSignal — messaggio formattato Oracle completo // ============================================================ bool TGSendSignal(string token, string chat_id, string symbol, bool is_buy, double entry, double sl, double tp, double lots, double score, double regime, double balance_ref) { string dir = is_buy ? "▲ BUY" : "▼ SELL"; string emoji = is_buy ? "🟢" : "🔴"; double pip = SymbolInfoDouble(symbol, SYMBOL_POINT) * 10; double sl_pip = MathAbs(entry - sl) / pip; double tp_pip = MathAbs(entry - tp) / pip; double rr = (sl_pip > 0) ? tp_pip / sl_pip : 0; string reg_str = (regime == 1.0) ? "📈 TREND" : (regime == 2.0) ? "↔️ RANGE" : "💥 BREAKOUT"; string sl_sign = is_buy ? "−" : "+"; string tp_sign = is_buy ? "+" : "−"; string msg = "⚡ <b>ORACLE SIGNAL</b>\n" + "\n" + "📊 <b>Simbolo:</b> " + symbol + "\n" + "🕐 <b>TF:</b> H4 · " + TimeToString(TimeCurrent()) + "\n" + "\n" + emoji + " <b>Segnale:</b> <b>" + dir + "</b>\n" + "💰 <b>Entry:</b> <code>" + DoubleToString(entry, _Digits) + "</code>\n" + "🛡️ <b>Stop Loss:</b> <code>" + DoubleToString(sl, _Digits) + "</code> (" + sl_sign + IntegerToString((int)sl_pip) + " pip)\n" + "🎯 <b>Take Profit:</b> <code>" + DoubleToString(tp, _Digits) + "</code> (" + tp_sign + IntegerToString((int)tp_pip) + " pip)\n" + "\n" + "📐 <b>Lotti</b> (1% / €" + IntegerToString((int)balance_ref) + "): <b>" + DoubleToString(lots, 2) + "</b>\n" + "⚡ <b>Oracle Score:</b> <b>" + DoubleToString(score, 1) + " / 10</b>\n" + "📈 <b>Regime:</b> " + reg_str + "\n" + "🔁 <b>RR:</b> 1 : " + DoubleToString(rr, 1) + "\n" + "\n" + "<i>Oracle v78 · MTInvestments.it</i>"; return(TGSend(token, chat_id, msg)); } #endif
Integrazione in Oracle — Quando e Come Chiamare
#include "Oracle_TelegramAlert.mqh" // Input nell'indicatore input string InpBotToken = ""; // Bot Token da BotFather input string InpChatId = ""; // Chat ID canale/gruppo input bool InpAlerts = true; // Abilita alert Telegram // Anti-spam: flag per non inviare lo stesso segnale due volte static datetime s_last_signal_bar = 0; // In OnCalculate(), dopo aver calcolato lo score: void CheckAndAlert(double score, double dir, double regime, double sl, double tp) { if(!InpAlerts) return; if(StringLen(InpBotToken) < 20) return; // token non impostato // Invia solo su nuova barra — evita spam su ogni tick datetime current_bar = (datetime)SeriesInfoInteger( _Symbol, PERIOD_H4, SERIES_LASTBAR_DATE); if(current_bar == s_last_signal_bar) return; // Score minimo per inviare if(score < 4.5 || MathAbs(dir) < 0.5) return; s_last_signal_bar = current_bar; // Calcola entry e lotti double entry = (dir > 0) ? SymbolInfoDouble(_Symbol, SYMBOL_ASK) : SymbolInfoDouble(_Symbol, SYMBOL_BID); double sl_pts = MathAbs(entry - sl) / SymbolInfoDouble(_Symbol, SYMBOL_POINT); double balance = AccountInfoDouble(ACCOUNT_BALANCE); double lots = CalcLotSize(1.0, sl_pts); // 1% di rischio // Invia alert Telegram bool sent = TGSendSignal( InpBotToken, InpChatId, _Symbol, (dir > 0), entry, sl, tp, lots, score, regime, balance ); if(!sent) Alert("Oracle: errore invio Telegram — controlla token e URL permessi"); }
Il codice che hai letto
genera i segnali che ricevi ogni mattina.
Entra nel canale Oracle gratuito — entry, SL, TP e lotti calcolati su MT5 reale.
Live gratuite su Telegram e sul grafico MT5.
FAQ — Alert Telegram MQL5
static datetime s_last_signal_bar = 0 per ricordare l'ultima barra su cui hai inviato l'alert. Prima di inviare, controlla che la barra corrente sia diversa: if(current_bar == s_last_signal_bar) return;. Aggiorna dopo l'invio: s_last_signal_bar = current_bar. Questo garantisce un solo alert per barra H4, anche se OnCalculate() viene chiamato più volte sulla stessa barra (a ogni tick).<b>grassetto</b>, <i>corsivo</i>, <code>codice monospace</code>. Attenzione: i caratteri < e > nel testo normale devono essere escaped come < e > per non confondersi con i tag HTML. Alternativa: usa parse_mode "MarkdownV2" — più potente ma richiede escape di molti caratteri speciali.