Vigiar
1
0
Derivar
Você já tinha feito uma derivação do repositório SniperGold_ML, anteriormente
0
SniperGold_ML/Gold algo

632 linhas
13 KiB
Text

//+------------------------------------------------------------------+
//| XAUUSD MTF MARKET HEALTH EA - MT5 |
//| M5 Entry + M15 + H1 + H4 Confirmation |
//+------------------------------------------------------------------+
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
//==================== INPUTS ========================================//
input ENUM_TIMEFRAMES EntryTF = PERIOD_M5;
input int FastEMA = 9;
input int SlowEMA = 15;
input int TrendEMA = 100;
input int RSIPeriod = 14;
input int ATRPeriod = 14;
input double MinHealthScore = 70.0;
input double RiskPercent = 1.0;
input double MaxDailyLossPercent = 3.0;
input int MaxTradesPerDay = 5;
input double SL_ATR_Multiplier = 1.5;
input double TP_ATR_Multiplier = 2.5;
input bool UseBreakEven = true;
input double BreakEvenATR = 1.0;
input bool UseTrailing = true;
input double TrailingATR = 1.0;
input int MaxSpreadPoints = 100;
input ulong MagicNumber = 9051501;
//==================== HANDLES ======================================//
int fastM5, slowM5, trendM5, rsiM5, atrM5;
int trendM15;
int trendH1;
int trendH4;
datetime lastBar = 0;
//==================== INIT ==========================================//
int OnInit()
{
fastM5 = iMA(_Symbol, EntryTF, FastEMA, 0, MODE_EMA, PRICE_CLOSE);
slowM5 = iMA(_Symbol, EntryTF, SlowEMA, 0, MODE_EMA, PRICE_CLOSE);
trendM5 = iMA(_Symbol, EntryTF, TrendEMA, 0, MODE_EMA, PRICE_CLOSE);
rsiM5 = iRSI(_Symbol, EntryTF, RSIPeriod, PRICE_CLOSE);
atrM5 = iATR(_Symbol, EntryTF, ATRPeriod);
trendM15 = iMA(_Symbol, PERIOD_M15, TrendEMA, 0,
MODE_EMA, PRICE_CLOSE);
trendH1 = iMA(_Symbol, PERIOD_H1, TrendEMA, 0,
MODE_EMA, PRICE_CLOSE);
trendH4 = iMA(_Symbol, PERIOD_H4, TrendEMA, 0,
MODE_EMA, PRICE_CLOSE);
if(fastM5 == INVALID_HANDLE ||
slowM5 == INVALID_HANDLE ||
trendM5 == INVALID_HANDLE ||
rsiM5 == INVALID_HANDLE ||
atrM5 == INVALID_HANDLE ||
trendM15 == INVALID_HANDLE ||
trendH1 == INVALID_HANDLE ||
trendH4 == INVALID_HANDLE)
{
Print("Indicator initialization failed.");
return INIT_FAILED;
}
trade.SetExpertMagicNumber(MagicNumber);
Print("MTF Market Health EA Started.");
return INIT_SUCCEEDED;
}
//==================== DEINIT ========================================//
void OnDeinit(const int reason)
{
IndicatorRelease(fastM5);
IndicatorRelease(slowM5);
IndicatorRelease(trendM5);
IndicatorRelease(rsiM5);
IndicatorRelease(atrM5);
IndicatorRelease(trendM15);
IndicatorRelease(trendH1);
IndicatorRelease(trendH4);
}
//==================== NEW BAR =======================================//
bool IsNewBar()
{
datetime t = iTime(_Symbol, EntryTF, 0);
if(t != lastBar)
{
lastBar = t;
return true;
}
return false;
}
//==================== GET VALUE =====================================//
double GetMAValue(int handle, int shift)
{
double buffer[];
if(CopyBuffer(handle, 0, shift, 1, buffer) != 1)
return 0;
return buffer[0];
}
//==================== RSI ===========================================//
double GetRSI()
{
double buffer[];
if(CopyBuffer(rsiM5, 0, 1, 1, buffer) != 1)
return 50;
return buffer[0];
}
//==================== ATR ===========================================//
double GetATR()
{
double buffer[];
if(CopyBuffer(atrM5, 0, 1, 1, buffer) != 1)
return 0;
return buffer[0];
}
//==================== TREND =========================================//
int GetTrend(ENUM_TIMEFRAMES tf, int handle)
{
double ema = GetMAValue(handle, 1);
double price = iClose(_Symbol, tf, 1);
if(ema == 0 || price == 0)
return 0;
if(price > ema)
return 1;
if(price < ema)
return -1;
return 0;
}
//==================== VOLUME ========================================//
bool VolumeBullish()
{
long currentVol = iVolume(_Symbol, EntryTF, 1);
long previousVol = iVolume(_Symbol, EntryTF, 2);
return currentVol >= previousVol;
}
//==================== SPREAD ========================================//
bool SpreadOK()
{
double ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double bid = SymbolInfoDouble(_Symbol, SYMBOL_BID);
double spread = (ask - bid) / _Point;
return spread <= MaxSpreadPoints;
}
//==================== DAILY LOSS ====================================//
double TodayProfit()
{
datetime start =
StringToTime(TimeToString(TimeCurrent(), TIME_DATE));
if(!HistorySelect(start, TimeCurrent()))
return 0;
double profit = 0;
int total = HistoryDealsTotal();
for(int i=0; i<total; i++)
{
ulong ticket = HistoryDealGetTicket(i);
if(ticket == 0)
continue;
long magic =
HistoryDealGetInteger(ticket, DEAL_MAGIC);
if(magic != (long)MagicNumber)
continue;
profit += HistoryDealGetDouble(ticket, DEAL_PROFIT);
profit += HistoryDealGetDouble(ticket, DEAL_SWAP);
profit += HistoryDealGetDouble(ticket, DEAL_COMMISSION);
}
return profit;
}
//==================== TRADES TODAY ==================================//
int TradesToday()
{
datetime start =
StringToTime(TimeToString(TimeCurrent(), TIME_DATE));
if(!HistorySelect(start, TimeCurrent()))
return 0;
int count = 0;
int total = HistoryDealsTotal();
for(int i=0; i<total; i++)
{
ulong ticket = HistoryDealGetTicket(i);
if(ticket == 0)
continue;
long magic =
HistoryDealGetInteger(ticket, DEAL_MAGIC);
long entry =
HistoryDealGetInteger(ticket, DEAL_ENTRY);
if(magic == (long)MagicNumber &&
entry == DEAL_ENTRY_IN)
{
count++;
}
}
return count;
}
//==================== HEALTH SCORE ==================================//
double GetHealthScore(int direction)
{
double score = 0;
// M15 trend = 20
int m15 = GetTrend(PERIOD_M15, trendM15);
if(m15 == direction)
score += 20;
// H1 trend = 25
int h1 = GetTrend(PERIOD_H1, trendH1);
if(h1 == direction)
score += 25;
// H4 trend = 25
int h4 = GetTrend(PERIOD_H4, trendH4);
if(h4 == direction)
score += 25;
// M5 trend = 10
int m5 = GetTrend(EntryTF, trendM5);
if(m5 == direction)
score += 10;
// RSI = 10
double rsi = GetRSI();
if(direction == 1 && rsi >= 55)
score += 10;
if(direction == -1 && rsi <= 45)
score += 10;
// Volume = 10
if(VolumeBullish())
score += 10;
return score;
}
//==================== LOT SIZE ======================================//
double CalculateLot(double slDistance)
{
double balance =
AccountInfoDouble(ACCOUNT_BALANCE);
double riskMoney =
balance * RiskPercent / 100.0;
double tickValue =
SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
double tickSize =
SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
if(tickValue <= 0 || tickSize <= 0)
return SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double lossPerLot =
(slDistance / tickSize) * tickValue;
if(lossPerLot <= 0)
return SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double lot = riskMoney / lossPerLot;
double minLot =
SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot =
SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double step =
SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lot = MathMax(lot, minLot);
lot = MathMin(lot, maxLot);
lot = MathFloor(lot / step) * step;
return NormalizeDouble(lot, 2);
}
//==================== BUY SIGNAL ====================================//
bool BuySignal()
{
double fast1 = GetMAValue(fastM5, 1);
double fast2 = GetMAValue(fastM5, 2);
double slow1 = GetMAValue(slowM5, 1);
double slow2 = GetMAValue(slowM5, 2);
if(fast1 == 0 || slow1 == 0)
return false;
bool crossover =
fast2 <= slow2 &&
fast1 > slow1;
return crossover;
}
//==================== SELL SIGNAL ===================================//
bool SellSignal()
{
double fast1 = GetMAValue(fastM5, 1);
double fast2 = GetMAValue(fastM5, 2);
double slow1 = GetMAValue(slowM5, 1);
double slow2 = GetMAValue(slowM5, 2);
if(fast1 == 0 || slow1 == 0)
return false;
bool crossover =
fast2 >= slow2 &&
fast1 < slow1;
return crossover;
}
//==================== BUY ===========================================//
void OpenBuy()
{
double atr = GetATR();
if(atr <= 0)
return;
double ask =
SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double slDistance =
atr * SL_ATR_Multiplier;
double tpDistance =
atr * TP_ATR_Multiplier;
double lot =
CalculateLot(slDistance);
double sl =
ask - slDistance;
double tp =
ask + tpDistance;
trade.Buy(
lot,
_Symbol,
ask,
NormalizeDouble(sl, _Digits),
NormalizeDouble(tp, _Digits),
"MTF HEALTH BUY"
);
}
//==================== SELL ==========================================//
void OpenSell()
{
double atr = GetATR();
if(atr <= 0)
return;
double bid =
SymbolInfoDouble(_Symbol, SYMBOL_BID);
double slDistance =
atr * SL_ATR_Multiplier;
double tpDistance =
atr * TP_ATR_Multiplier;
double lot =
CalculateLot(slDistance);
double sl =
bid + slDistance;
double tp =
bid - tpDistance;
trade.Sell(
lot,
_Symbol,
bid,
NormalizeDouble(sl, _Digits),
NormalizeDouble(tp, _Digits),
"MTF HEALTH SELL"
);
}
//==================== POSITION MANAGEMENT ===========================//
void ManagePosition()
{
if(!PositionSelect(_Symbol))
return;
double atr = GetATR();
if(atr <= 0)
return;
long type =
PositionGetInteger(POSITION_TYPE);
double open =
PositionGetDouble(POSITION_PRICE_OPEN);
double sl =
PositionGetDouble(POSITION_SL);
double tp =
PositionGetDouble(POSITION_TP);
double bid =
SymbolInfoDouble(_Symbol, SYMBOL_BID);
double ask =
SymbolInfoDouble(_Symbol, SYMBOL_ASK);
// BUY
if(type == POSITION_TYPE_BUY)
{
double profit =
bid - open;
// Break-even
if(UseBreakEven &&
profit >= atr * BreakEvenATR)
{
double newSL = open;
if(sl < newSL)
{
trade.PositionModify(
_Symbol,
NormalizeDouble(newSL, _Digits),
tp
);
}
}
// Trailing
if(UseTrailing &&
profit >= atr * TrailingATR)
{
double newSL =
bid - atr * TrailingATR;
if(newSL > sl)
{
trade.PositionModify(
_Symbol,
NormalizeDouble(newSL, _Digits),
tp
);
}
}
}
// SELL
if(type == POSITION_TYPE_SELL)
{
double profit =
open - ask;
// Break-even
if(UseBreakEven &&
profit >= atr * BreakEvenATR)
{
double newSL = open;
if(sl == 0 || sl > newSL)
{
trade.PositionModify(
_Symbol,
NormalizeDouble(newSL, _Digits),
tp
);
}
}
// Trailing
if(UseTrailing &&
profit >= atr * TrailingATR)
{
double newSL =
ask + atr * TrailingATR;
if(sl == 0 || newSL < sl)
{
trade.PositionModify(
_Symbol,
NormalizeDouble(newSL, _Digits),
tp
);
}
}
}
}
//==================== MAIN ==========================================//
void OnTick()
{
// Position management runs continuously
ManagePosition();
// New candle only for entries
if(!IsNewBar())
return;
// Spread protection
if(!SpreadOK())
{
Print("Spread too high - trade skipped.");
return;
}
// Daily trade limit
if(TradesToday() >= MaxTradesPerDay)
{
Print("Daily trade limit reached.");
return;
}
// Daily loss protection
double balance =
AccountInfoDouble(ACCOUNT_BALANCE);
double maxLoss =
balance * MaxDailyLossPercent / 100.0;
if(TodayProfit() <= -maxLoss)
{
Print("Daily loss limit reached.");
return;
}
// One position at a time
if(PositionSelect(_Symbol))
return;
// BUY
if(BuySignal())
{
double score = GetHealthScore(1);
Print("BUY Health Score = ", score);
if(score >= MinHealthScore)
{
OpenBuy();
return;
}
}
// SELL
if(SellSignal())
{
double score = GetHealthScore(-1);
Print("SELL Health Score = ", score);
if(score >= MinHealthScore)
{
OpenSell();
return;
}
}
}
//+------------------------------------------------------------------+