指定
//+------------------------------------------------------------------+
//| XAUUSD M5 TELEGRAM TRADING EA |
//| EMA 20/50/200 + RSI + ATR + Telegram |
//+------------------------------------------------------------------+
#property strict
#property version "1.00"
#property description "XAUUSD M5 EA with EMA, RSI, ATR and Telegram notifications"
#include <Trade/Trade.mqh>
CTrade trade;
//==================================================================
// PARAMETRES GENERAUX
//==================================================================
input group "=== TRADING ==="
input double Lots = 0.01;
input ulong MagicNumber = 26082601;
input int DeviationPoints = 30;
input bool EnableTrading = true;
input group "=== INDICATEURS ==="
input int EMA_Fast = 20;
input int EMA_Medium = 50;
input int EMA_Slow = 200;
input int RSI_Period = 14;
input int ATR_Period = 14;
input double ATR_SL_Multiplier = 1.5;
input double RiskReward = 2.0;
input double MinimumScore = 70.0;
input group "=== TELEGRAM ==="
input bool EnableTelegram = true;
input string TelegramToken = "TON_BOT_TOKEN";
input string TelegramChatID = "TON_CHAT_ID";
input int TelegramTimeout = 10000;
input bool SendStartupMessage = true;
//==================================================================
// HANDLES INDICATEURS
//==================================================================
int handleEMA20 = INVALID_HANDLE;
int handleEMA50 = INVALID_HANDLE;
int handleEMA200 = INVALID_HANDLE;
int handleRSI = INVALID_HANDLE;
int handleATR = INVALID_HANDLE;
//==================================================================
// VARIABLES
//==================================================================
datetime LastBarTime = 0;
//==================================================================
// INITIALISATION
//==================================================================
int OnInit()
{
Print("======================================");
Print("XAUUSD M5 TELEGRAM EA");
Print("Initialisation...");
Print("======================================");
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(DeviationPoints);
trade.SetTypeFillingBySymbol(_Symbol);
// EMA 20
handleEMA20 = iMA(
_Symbol,
PERIOD_M5,
EMA_Fast,
0,
MODE_EMA,
PRICE_CLOSE
);
// EMA 50
handleEMA50 = iMA(
_Symbol,
PERIOD_M5,
EMA_Medium,
0,
MODE_EMA,
PRICE_CLOSE
);
// EMA 200
handleEMA200 = iMA(
_Symbol,
PERIOD_M5,
EMA_Slow,
0,
MODE_EMA,
PRICE_CLOSE
);
// RSI
handleRSI = iRSI(
_Symbol,
PERIOD_M5,
RSI_Period,
PRICE_CLOSE
);
// ATR
handleATR = iATR(
_Symbol,
PERIOD_M5,
ATR_Period
);
if(handleEMA20 == INVALID_HANDLE ||
handleEMA50 == INVALID_HANDLE ||
handleEMA200 == INVALID_HANDLE ||
handleRSI == INVALID_HANDLE ||
handleATR == INVALID_HANDLE)
{
Print("ERREUR : impossible de créer les indicateurs.");
return INIT_FAILED;
}
if(EnableTelegram && SendStartupMessage)
{
string message =
"🤖 XAUUSD M5 EA DEMARRE\n\n"
"📊 Symbole : " + _Symbol + "\n"
"⏱ Timeframe : M5\n"
"💰 Lot : " + DoubleToString(Lots,2) + "\n"
"📈 EMA : 20 / 50 / 200\n"
"📊 RSI : " + IntegerToString(RSI_Period) + "\n"
"📏 ATR : " + IntegerToString(ATR_Period) + "\n\n"
"⚠️ Mode automatique : " +
(EnableTrading ? "ACTIF" : "DESACTIVE");
SendTelegram(message);
}
Print("EA initialise avec succes.");
return INIT_SUCCEEDED;
}
//==================================================================
// DEINITIALISATION
//==================================================================
void OnDeinit(const int reason)
{
if(handleEMA20 != INVALID_HANDLE)
IndicatorRelease(handleEMA20);
if(handleEMA50 != INVALID_HANDLE)
IndicatorRelease(handleEMA50);
if(handleEMA200 != INVALID_HANDLE)
IndicatorRelease(handleEMA200);
if(handleRSI != INVALID_HANDLE)
IndicatorRelease(handleRSI);
if(handleATR != INVALID_HANDLE)
IndicatorRelease(handleATR);
Print("EA arrete.");
}
//==================================================================
// TICK PRINCIPAL
//==================================================================
void OnTick()
{
// On travaille uniquement sur une nouvelle bougie M5
if(!IsNewBar())
return;
// Une seule position sur le symbole
if(PositionSelect(_Symbol))
{
Print("Position deja ouverte sur ", _Symbol);
return;
}
AnalyzeMarket();
}
//==================================================================
// DETECTION NOUVELLE BOUGIE
//==================================================================
bool IsNewBar()
{
datetime currentBar =
iTime(_Symbol, PERIOD_M5, 0);
if(currentBar == 0)
return false;
if(currentBar != LastBarTime)
{
LastBarTime = currentBar;
return true;
}
return false;
}
//==================================================================
// ANALYSE DU MARCHE
//==================================================================
void AnalyzeMarket()
{
double ema20[3];
double ema50[3];
double ema200[3];
double rsi[3];
double atr[3];
ArraySetAsSeries(ema20,true);
ArraySetAsSeries(ema50,true);
ArraySetAsSeries(ema200,true);
ArraySetAsSeries(rsi,true);
ArraySetAsSeries(atr,true);
if(CopyBuffer(handleEMA20,0,0,3,ema20) < 3)
return;
if(CopyBuffer(handleEMA50,0,0,3,ema50) < 3)
return;
if(CopyBuffer(handleEMA200,0,0,3,ema200) < 3)
return;
if(CopyBuffer(handleRSI,0,0,3,rsi) < 3)
return;
if(CopyBuffer(handleATR,0,0,3,atr) < 3)
return;
// Bougie clôturée
double openPrice = iOpen(_Symbol,PERIOD_M5,1);
double closePrice = iClose(_Symbol,PERIOD_M5,1);
double highPrice = iHigh(_Symbol,PERIOD_M5,1);
double lowPrice = iLow(_Symbol,PERIOD_M5,1);
if(openPrice == 0 || closePrice == 0)
return;
// Valeurs de la dernière bougie clôturée
double e20 = ema20[1];
double e50 = ema50[1];
double e200 = ema200[1];
double rsiValue = rsi[1];
double atrValue = atr[1];
if(atrValue <= 0)
return;
double buyScore = 0;
double sellScore = 0;
string buyReasons = "";
string sellReasons = "";
//==============================================================
// BUY
//==============================================================
// Prix > EMA200
if(closePrice > e200)
{
buyScore += 25;
buyReasons += "Prix > EMA200\n";
}
// EMA20 > EMA50
if(e20 > e50)
{
buyScore += 20;
buyReasons += "EMA20 > EMA50\n";
}
// Prix > EMA20
if(closePrice > e20)
{
buyScore += 15;
buyReasons += "Prix > EMA20\n";
}
// RSI haussier
if(rsiValue > 50 && rsiValue < 70)
{
buyScore += 20;
buyReasons += "RSI haussier\n";
}
// Bougie haussiere
if(closePrice > openPrice)
{
buyScore += 20;
buyReasons += "Bougie haussiere\n";
}
//==============================================================
// SELL
//==============================================================
// Prix < EMA200
if(closePrice < e200)
{
sellScore += 25;
sellReasons += "Prix < EMA200\n";
}
// EMA20 < EMA50
if(e20 < e50)
{
sellScore += 20;
sellReasons += "EMA20 < EMA50\n";
}
// Prix < EMA20
if(closePrice < e20)
{
sellScore += 15;
sellReasons += "Prix < EMA20\n";
}
// RSI baissier
if(rsiValue > 30 && rsiValue < 50)
{
sellScore += 20;
sellReasons += "RSI baissier\n";
}
// Bougie baissiere
if(closePrice < openPrice)
{
sellScore += 20;
sellReasons += "Bougie baissiere\n";
}
//==============================================================
// DECISION
//==============================================================
Print(
"Analyse M5 | BUY=",
DoubleToString(buyScore,0),
"% | SELL=",
DoubleToString(sellScore,0),
"%"
);
// BUY
if(buyScore >= MinimumScore &&
buyScore > sellScore)
{
OpenBuy(
buyScore,
rsiValue,
atrValue,
buyReasons
);
return;
}
// SELL
if(sellScore >= MinimumScore &&
sellScore > buyScore)
{
OpenSell(
sellScore,
rsiValue,
atrValue,
sellReasons
);
return;
}
Print("Aucun signal valide.");
}
//==================================================================
// OUVERTURE BUY
//==================================================================
void OpenBuy(
double score,
double rsiValue,
double atrValue,
string reasons
)
{
double ask =
SymbolInfoDouble(
_Symbol,
SYMBOL_ASK
);
if(ask <= 0)
return;
int digits =
(int)SymbolInfoInteger(
_Symbol,
SYMBOL_DIGITS
);
double sl =
ask -
(atrValue * ATR_SL_Multiplier);
double risk =
ask - sl;
double tp =
ask +
(risk * RiskReward);
sl = NormalizeDouble(sl,digits);
tp = NormalizeDouble(tp,digits);
Print(
"Tentative BUY | Entry=",
DoubleToString(ask,digits),
" | SL=",
DoubleToString(sl,digits),
" | TP=",
DoubleToString(tp,digits)
);
if(!EnableTrading)
{
string testMessage =
"🟢 SIGNAL BUY\n\n"
"📊 " + _Symbol + " M5\n"
"📍 Entrée : " +
DoubleToString(ask,digits) + "\n"
"🛑 SL : " +
DoubleToString(sl,digits) + "\n"
"🎯 TP : " +
DoubleToString(tp,digits) + "\n"
"🔥 Score : " +
DoubleToString(score,0) + "%\n"
"📈 RSI : " +
DoubleToString(rsiValue,2) + "\n\n"
"⚠️ Trading automatique désactivé.";
SendTelegram(testMessage);
return;
}
bool result =
trade.Buy(
Lots,
_Symbol,
0.0,
sl,
tp,
"XAUUSD_M5_BUY"
);
if(result)
{
Print("BUY envoye.");
Sleep(300);
SendTradeNotification(
"BUY",
score,
rsiValue,
atrValue,
reasons
);
}
else
{
Print(
"Erreur BUY : ",
trade.ResultRetcode(),
" - ",
trade.ResultRetcodeDescription()
);
}
}
//==================================================================
// OUVERTURE SELL
//==================================================================
void OpenSell(
double score,
double rsiValue,
double atrValue,
string reasons
)
{
double bid =
SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
if(bid <= 0)
return;
int digits =
(int)SymbolInfoInteger(
_Symbol,
SYMBOL_DIGITS
);
double sl =
bid +
(atrValue * ATR_SL_Multiplier);
double risk =
sl - bid;
double tp =
bid -
(risk * RiskReward);
sl = NormalizeDouble(sl,digits);
tp = NormalizeDouble(tp,digits);
Print(
"Tentative SELL | Entry=",
DoubleToString(bid,digits),
" | SL=",
DoubleToString(sl,digits),
" | TP=",
DoubleToString(tp,digits)
);
if(!EnableTrading)
{
string testMessage =
"🔴 SIGNAL SELL\n\n"
"📊 " + _Symbol + " M5\n"
"📍 Entrée : " +
DoubleToString(bid,digits) + "\n"
"🛑 SL : " +
DoubleToString(sl,digits) + "\n"
"🎯 TP : " +
DoubleToString(tp,digits) + "\n"
"🔥 Score : " +
DoubleToString(score,0) + "%\n"
"📈 RSI : " +
DoubleToString(rsiValue,2) + "\n\n"
"⚠️ Trading automatique désactivé.";
SendTelegram(testMessage);
return;
}
bool result =
trade.Sell(
Lots,
_Symbol,
0.0,
sl,
tp,
"XAUUSD_M5_SELL"
);
if(result)
{
Print("SELL envoye.");
Sleep(300);
SendTradeNotification(
"SELL",
score,
rsiValue,
atrValue,
reasons
);
}
else
{
Print(
"Erreur SELL : ",
trade.ResultRetcode(),
" - ",
trade.ResultRetcodeDescription()
);
}
}
//==================================================================
// NOTIFICATION TELEGRAM DU TRADE
//==================================================================
void SendTradeNotification(
string direction,
double score,
double rsiValue,
double atrValue,
string reasons
)
{
if(!EnableTelegram)
return;
if(!PositionSelect(_Symbol))
{
Print(
"Position non trouvee apres ouverture."
);
return;
}
int digits =
(int)SymbolInfoInteger(
_Symbol,
SYMBOL_DIGITS
);
double entry =
PositionGetDouble(
POSITION_PRICE_OPEN
);
double sl =
PositionGetDouble(
POSITION_SL
);
double tp =
PositionGetDouble(
POSITION_TP
);
double volume =
PositionGetDouble(
POSITION_VOLUME
);
ulong ticket =
(ulong)PositionGetInteger(
POSITION_TICKET
);
string emoji =
direction == "BUY" ? "🟢" : "🔴";
string message =
emoji + " XAUUSD M5 — " +
direction + "\n\n"
"📊 Symbole : " + _Symbol + "\n"
"💰 Lot : " +
DoubleToString(volume,2) + "\n"
"🎫 Ticket : " +
IntegerToString((long)ticket) + "\n\n"
"📍 Entrée : " +
DoubleToString(entry,digits) + "\n"
"🛑 SL : " +
DoubleToString(sl,digits) + "\n"
"🎯 TP : " +
DoubleToString(tp,digits) + "\n\n"
"🔥 Score : " +
DoubleToString(score,0) + "%\n"
"📈 RSI : " +
DoubleToString(rsiValue,2) + "\n"
"📏 ATR : " +
DoubleToString(atrValue,digits) + "\n\n"
"🔎 Conditions :\n" +
reasons + "\n"
"⚠️ Signal algorithmique — "
"aucune garantie de gain.";
SendTelegram(message);
}
//==================================================================
// TELEGRAM
//==================================================================
bool SendTelegram(string message)
{
if(!EnableTelegram)
return false;
if(TelegramToken == "" ||
TelegramChatID == "" ||
TelegramToken == "TON_BOT_TOKEN" ||
TelegramChatID == "TON_CHAT_ID")
{
Print(
"Telegram non configure."
);
return false;
}
string url =
"https://api.telegram.org/bot" +
TelegramToken +
"/sendMessage";
// Encoder le message pour application/x-www-form-urlencoded
string encodedMessage =
UrlEncode(message);
string body =
"chat_id=" +
UrlEncode(TelegramChatID) +
"&text=" +
encodedMessage;
char post[];
char result[];
string resultHeaders;
int length =
StringToCharArray(
body,
post,
0,
-1,
CP_UTF8
);
if(length > 0)
ArrayResize(post,length - 1);
string headers =
"Content-Type: application/x-www-form-urlencoded\r\n";
ResetLastError();
int response =
WebRequest(
"POST",
url,
headers,
TelegramTimeout,
post,
result,
resultHeaders
);
if(response == 200)
{
Print(
"Telegram : message envoye."
);
return true;
}
Print(
"Telegram WebRequest erreur = ",
response,
" | LastError = ",
GetLastError()
);
Print(
"Reponse Telegram : ",
CharArrayToString(result)
);
return false;
}
//==================================================================
// URL ENCODE
//==================================================================
string UrlEncode(string text)
{
uchar data[];
StringToCharArray(
text,
data,
0,
WHOLE_ARRAY,
CP_UTF8
);
string result = "";
for(int i=0; i<ArraySize(data); i++)
{
uchar c = data[i];
if(c == 0)
break;
bool safe =
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '0' && c <= '9') ||
c == '-' ||
c == '_' ||
c == '.' ||
c == '~';
if(safe)
{
result += CharToString(c);
}
else if(c == ' ')
{
result += "+";
}
else
{
result += "%";
result += StringFormat(
"%02X",
c
);
}
}
return result;
}
//==================================================================
// NOTIFICATIONS DES FERMETURES
//==================================================================
void OnTradeTransaction(
const MqlTradeTransaction &trans,
const MqlTradeRequest &request,
const MqlTradeResult &result
)
{
if(!EnableTelegram)
return;
// Nous nous intéressons aux nouveaux deals
if(trans.type != TRADE_TRANSACTION_DEAL_ADD)
return;
if(trans.deal == 0)
return;
// Sélectionner le deal dans l'historique
if(!HistoryDealSelect(trans.deal))
return;
string symbol =
HistoryDealGetString(
trans.deal,
DEAL_SYMBOL
);
if(symbol != _Symbol)
return;
long entryType =
HistoryDealGetInteger(
trans.deal,
DEAL_ENTRY
);
// Notification fermeture
if(entryType == DEAL_ENTRY_OUT ||
entryType == DEAL_ENTRY_OUT_BY)
{
double volume =
HistoryDealGetDouble(
trans.deal,
DEAL_VOLUME
);
double price =
HistoryDealGetDouble(
trans.deal,
DEAL_PRICE
);
double profit =
HistoryDealGetDouble(
trans.deal,
DEAL_PROFIT
);
ulong dealTicket =
trans.deal;
string emoji =
profit >= 0 ? "✅" : "❌";
string resultText =
profit >= 0 ? "GAIN" : "PERTE";
int digits =
(int)SymbolInfoInteger(
_Symbol,
SYMBOL_DIGITS
);
string message =
emoji + " TRADE FERME — " +
resultText + "\n\n"
"📊 Symbole : " +
symbol + "\n"
"💰 Volume : " +
DoubleToString(volume,2) + "\n"
"📍 Prix sortie : " +
DoubleToString(price,digits) + "\n"
"💵 Résultat : " +
DoubleToString(profit,2) + "\n"
"🎫 Deal : " +
IntegerToString((long)dealTicket);
SendTelegram(message);
}
}
//+------------------------------------------------------------------+
プロジェクト情報
予算
30+ USD
締め切り
最低 10 最高 25 日
依頼者
出された注文1
裁定取引数0