1
0
Fork 0
This repository has been archived on 2026-07-24. You can view files and clone it, but you cannot make any changes to its state, such as pushing and creating new issues, pull requests or comments.
AiDataTaskRuner/Hybrid EA

988 lines
20 KiB
Text
Raw Permalink Normal View History

//+------------------------------------------------------------------+
//| Institutional Hybrid EA v1.0 |
//| PART 1 - FOUNDATION |
//+------------------------------------------------------------------+
#property strict
#include <Trade/Trade.mqh>
CTrade trade;
//+------------------------------------------------------------------+
//| INPUT PARAMETERS |
//+------------------------------------------------------------------+
input long MagicNumber = 20260601;
// Risk Management
input double RiskPercent = 1.0;
input double MaxDailyDrawdown = 5.0;
input int MaxConsecutiveLosses = 3;
// Fixed Lot Mode
input bool UseFixedLot = true;
input double FixedLotSize = 0.01;
// Trade Management
input int MaxOpenTrades = 5;
input int TradeCooldownMinutes = 2;
// Break Even Settings
input double BreakEvenTriggerR = 1.0;
input double BreakEvenBufferPoints = 50;
// Spread Filter
int MaxSpread = 300;
// ATR Settings
input int ATR_Period = 14;
double ATR_SL_Multiplier = 1.2;
double ATR_TP_Multiplier = 2.5;
input double ATR_Trail_Multiplier = 1.0;
// EMA Settings
input int FastEMA = 5;
input int SlowEMA = 20;
// RSI Settings
input int RSI_Period = 14;
input double RSI_Buy_Level = 50;
input double RSI_Sell_Level = 50;
// ADX Settings
input int ADX_Period = 14;
input double MinADX = 15.0;
// Session Filter
input bool TradeLondonSession = true;
input bool TradeNewYorkSession = true;
//+------------------------------------------------------------------+
//| GLOBAL VARIABLES |
//+------------------------------------------------------------------+
datetime LastTradeTime = 0;
datetime LastResetDay = 0;
datetime LastM15Bar = 0;
double DayStartBalance = 0.0;
int ConsecutiveLosses = 0;
bool TradingEnabled = true;
// Prevent duplicate entries on the same signal
bool BuySignalTriggered = false;
bool SellSignalTriggered = false;
//+------------------------------------------------------------------+
//| INITIALIZATION |
//+------------------------------------------------------------------+
int OnInit()
{
// XAUUSD Optimization
if(XAUUSD_Mode)
{
ATR_SL_Multiplier = 1.5;
ATR_TP_Multiplier = 3.0;
MaxSpread = 500;
}
// Trade Setup
trade.SetExpertMagicNumber(MagicNumber);
trade.SetDeviationInPoints(50);
// Account Information
DayStartBalance =
AccountInfoDouble(
ACCOUNT_BALANCE
);
Print(
"Min Lot = ",
SymbolInfoDouble(
_Symbol,
SYMBOL_VOLUME_MIN
)
);
Print(
"Leverage = ",
AccountInfoInteger(
ACCOUNT_LEVERAGE
)
);
LastResetDay =
TimeCurrent();
TradingEnabled = true;
Print(
"Institutional Hybrid EA v1.0 Started"
);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| DEINITIALIZATION |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("EA Shutdown");
}
//+------------------------------------------------------------------+
//| SPREAD FILTER |
//+------------------------------------------------------------------+
bool CheckSpread()
{
long spread =
SymbolInfoInteger(
_Symbol,
SYMBOL_SPREAD
);
if(spread > MaxSpread)
return false;
return true;
}
//+------------------------------------------------------------------+
//| SESSION FILTER |
//+------------------------------------------------------------------+
bool IsTradingSession()
{
return true;
MqlDateTime tm;
TimeToStruct(TimeCurrent(), tm);
int hour = tm.hour;
bool london =
(hour >= 8 && hour <= 17);
bool newyork =
(hour >= 13 && hour <= 22);
if(TradeLondonSession && london)
return true;
if(TradeNewYorkSession && newyork)
return true;
return false;
}
//+------------------------------------------------------------------+
//| DAILY DRAWDOWN PROTECTION |
//+------------------------------------------------------------------+
bool CheckDailyDrawdown()
{
double equity =
AccountInfoDouble(
ACCOUNT_EQUITY
);
double drawdown =
((DayStartBalance - equity)
/
DayStartBalance) * 100.0;
if(drawdown >= MaxDailyDrawdown)
{
TradingEnabled = false;
Print(
"Maximum Daily Drawdown Hit"
);
return false;
}
return true;
}
//+------------------------------------------------------------------+
//| COOLDOWN CHECK |
//+------------------------------------------------------------------+
bool CooldownPassed()
{
if(LastTradeTime == 0)
return true;
int secondsPassed =
(int)(TimeCurrent()
- LastTradeTime);
return
secondsPassed >=
TradeCooldownMinutes * 60;
}
//+------------------------------------------------------------------+
//| NEW M15 BAR DETECTION |
//+------------------------------------------------------------------+
bool NewM15Bar()
{
datetime currentBar =
iTime(
_Symbol,
PERIOD_M15,
0
);
if(currentBar != LastM15Bar)
{
LastM15Bar = currentBar;
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| ATR VALUE |
//+------------------------------------------------------------------+
double GetATR(
ENUM_TIMEFRAMES tf
)
{
// Create ATR Handle
int handle =
iATR(
_Symbol,
tf,
ATR_Period
);
// Validate Handle
if(handle == INVALID_HANDLE)
{
Print("ATR Handle Creation Failed");
return 0;
}
// ATR Buffer
double buffer[];
// Copy ATR Data
if(CopyBuffer(
handle,
0,
0,
1,
buffer) < 1)
{
Print("ATR Buffer Failed");
IndicatorRelease(handle);
return 0;
}
// Release Indicator Handle
IndicatorRelease(handle);
// Return ATR Value
return buffer[0];
}
//+------------------------------------------------------------------+
//| EMA VALUE |
//+------------------------------------------------------------------+
double GetEMA(
ENUM_TIMEFRAMES tf,
int period
)
{
int handle =
iMA(
_Symbol,
tf,
period,
0,
MODE_EMA,
PRICE_CLOSE
);
if(handle == INVALID_HANDLE)
return 0;
double buffer[];
if(CopyBuffer(
handle,
0,
0,
1,
buffer) < 1)
{
IndicatorRelease(handle);
return 0;
}
IndicatorRelease(handle);
return buffer[0];
}
//+------------------------------------------------------------------+
//| RSI VALUE |
//+------------------------------------------------------------------+
double GetRSI(
ENUM_TIMEFRAMES tf
)
{
int handle =
iRSI(
_Symbol,
tf,
RSI_Period,
PRICE_CLOSE
);
if(handle == INVALID_HANDLE)
return 0;
double buffer[];
if(CopyBuffer(
handle,
0,
0,
1,
buffer) < 1)
{
IndicatorRelease(handle);
return 0;
}
IndicatorRelease(handle);
return buffer[0];
}
//+------------------------------------------------------------------+
//| ADX VALUE |
//+------------------------------------------------------------------+
double GetADX(
ENUM_TIMEFRAMES tf
)
{
int handle =
iADX(
_Symbol,
tf,
ADX_Period
);
if(handle == INVALID_HANDLE)
return 0;
double buffer[];
if(CopyBuffer(
handle,
0,
0,
1,
buffer) < 1)
{
IndicatorRelease(handle);
return 0;
}
IndicatorRelease(handle);
return buffer[0];
}
// Liquidity Detection
input int LiquidityLookback = 20;
input double LiquidityTolerancePoints = 100;
//+------------------------------------------------------------------+
//| TREND STRENGTH |
//+------------------------------------------------------------------+
bool StrongTrend()
{
return GetADX(PERIOD_H1) > MinADX;
}
//+------------------------------------------------------------------+
//| DYNAMIC LOT CALCULATION |
//+------------------------------------------------------------------+
double CalculateLotSize(double stopLossDistance)
{
double balance =
AccountInfoDouble(
ACCOUNT_BALANCE
);
double riskAmount =
balance * (RiskPercent / 100.0);
double tickValue =
SymbolInfoDouble(
_Symbol,
SYMBOL_TRADE_TICK_VALUE
);
if(tickValue <= 0 || stopLossDistance <= 0)
return 0.01;
double lot = 0.01;
// Safety limits
double minLot =
SymbolInfoDouble(
_Symbol,
SYMBOL_VOLUME_MIN
);
double maxLot =
SymbolInfoDouble(
_Symbol,
SYMBOL_VOLUME_MAX
);
double lotStep =
SymbolInfoDouble(
_Symbol,
SYMBOL_VOLUME_STEP
);
// HARD CAP
if(lot > 1.0)
lot = 1.0;
lot =
MathMax(minLot,
MathMin(maxLot, lot));
lot =
NormalizeDouble(
MathFloor(lot / lotStep)
* lotStep,
2
);
return lot;
}
//+------------------------------------------------------------------+
//| POSITION COUNT |
//+------------------------------------------------------------------+
int CountOpenPositions()
{
int count = 0;
for(int i=0;
i<PositionsTotal();
i++)
{
ulong ticket =
PositionGetTicket(i);
if(ticket <= 0)
continue;
if(PositionSelectByTicket(ticket))
{
if(PositionGetInteger(
POSITION_MAGIC)
== MagicNumber)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| H4 MARKET BIAS |
//+------------------------------------------------------------------+
bool H4BullishBias()
{
double ema50 =
GetEMA(PERIOD_H4,50);
double ema200 =
GetEMA(PERIOD_H4,200);
return ema50 > ema200;
}
bool H4BearishBias()
{
double ema50 =
GetEMA(PERIOD_H4,50);
double ema200 =
GetEMA(PERIOD_H4,200);
return ema50 < ema200;
}
//+------------------------------------------------------------------+
//| H1 CONFIRMATION |
//+------------------------------------------------------------------+
bool H1BullishConfirmation()
{
double ema50 =
GetEMA(PERIOD_H1,50);
double ema200 =
GetEMA(PERIOD_H1,200);
return ema50 > ema200;
}
bool H1BearishConfirmation()
{
double ema50 =
GetEMA(PERIOD_H1,50);
double ema200 =
GetEMA(PERIOD_H1,200);
return ema50 < ema200;
}
//+------------------------------------------------------------------+
//| PRICE LOCATION FILTER |
//+------------------------------------------------------------------+
bool PriceAboveH1EMA()
{
double ema =
GetEMA(PERIOD_H1,50);
double bid =
SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
return bid > ema;
}
bool PriceBelowH1EMA()
{
double ema =
GetEMA(PERIOD_H1,50);
double bid =
SymbolInfoDouble(
_Symbol,
SYMBOL_BID
);
return bid < ema;
}
//+------------------------------------------------------------------+
//| M15 MOMENTUM FILTERS |
//+------------------------------------------------------------------+
bool M15BullishMomentum()
{
double fastEMA =
GetEMA(
PERIOD_M15,
FastEMA
);
double slowEMA =
GetEMA(
PERIOD_M15,
SlowEMA
);
double rsi =
GetRSI(
PERIOD_M15
);
double adx =
GetADX(
PERIOD_M15
);
return
fastEMA > slowEMA &&
rsi > RSI_Buy_Level &&
adx > MinADX;
}
bool M15BearishMomentum()
{
double fastEMA =
GetEMA(
PERIOD_M15,
FastEMA
);
double slowEMA =
GetEMA(
PERIOD_M15,
SlowEMA
);
double rsi =
GetRSI(
PERIOD_M15
);
double adx =
GetADX(
PERIOD_M15
);
return
fastEMA < slowEMA &&
rsi < RSI_Sell_Level &&
adx > MinADX;
}
//+------------------------------------------------------------------+
//| PULLBACK BUY |
//+------------------------------------------------------------------+
bool PullbackBuy()
{
double ema20 =
GetEMA(PERIOD_M15,20);
double close =
iClose(_Symbol,PERIOD_M15,1);
double atr =
GetATR(PERIOD_M15);
return
MathAbs(close - ema20)
<= atr * 0.5;
}
//+------------------------------------------------------------------+
//| PULLBACK SELL |
//+------------------------------------------------------------------+
bool PullbackSell()
{
double ema20 =
GetEMA(PERIOD_M15,20);
double close =
iClose(_Symbol,PERIOD_M15,1);
double atr =
GetATR(PERIOD_M15);
return
MathAbs(close - ema20)
<= atr * 0.5;
}
//+------------------------------------------------------------------+
//| BUY SIGNAL |
//+------------------------------------------------------------------+
bool BuySignal()
{
return
H4BullishBias() &&
H1BullishConfirmation() &&
PullbackBuy() &&
M15BullishMomentum();
}
//+------------------------------------------------------------------+
//| SELL SIGNAL |
//+------------------------------------------------------------------+
bool SellSignal()
{
return
H4BearishBias() &&
H1BearishConfirmation() &&
PullbackSell() &&
M15BearishMomentum();
}
//+------------------------------------------------------------------+
//| SIGNAL ENUM |
//+------------------------------------------------------------------+
enum TradeSignal
{
SIGNAL_NONE,
SIGNAL_BUY,
SIGNAL_SELL
};
//+------------------------------------------------------------------+
//| GET SIGNAL |
//+------------------------------------------------------------------+
TradeSignal GetSignal()
{
if(BuySignal())
return SIGNAL_BUY;
if(SellSignal())
return SIGNAL_SELL;
return SIGNAL_NONE;
}
//+------------------------------------------------------------------+
//| EQUAL HIGHS DETECTION |
//+------------------------------------------------------------------+
bool EqualHighs()
{
double point =
SymbolInfoDouble(
_Symbol,
SYMBOL_POINT
);
double tolerance =
LiquidityTolerancePoints * point;
for(int i=2; i<=LiquidityLookback; i++)
{
double high1 =
iHigh(
_Symbol,
PERIOD_M15,
i
);
double high2 =
iHigh(
_Symbol,
PERIOD_M15,
i+1
);
if(MathAbs(high1-high2) <= tolerance)
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| EQUAL LOWS DETECTION |
//+------------------------------------------------------------------+
bool EqualLows()
{
double point =
SymbolInfoDouble(
_Symbol,
SYMBOL_POINT
);
double tolerance =
LiquidityTolerancePoints * point;
for(int i=2; i<=LiquidityLookback; i++)
{
double low1 =
iLow(
_Symbol,
PERIOD_M15,
i
);
double low2 =
iLow(
_Symbol,
PERIOD_M15,
i+1
);
if(MathAbs(low1-low2) <= tolerance)
{
return true;
}
}
return false;
}
//+------------------------------------------------------------------+
//| BULLISH LIQUIDITY SWEEP |
//+------------------------------------------------------------------+
bool LiquiditySweepBuy()
{
double prevLow =
iLow(_Symbol, PERIOD_M15, 2);
double currentLow =
iLow(_Symbol, PERIOD_M15, 1);
double currentClose =
iClose(_Symbol, PERIOD_M15, 1);
return currentLow < prevLow &&
currentClose > prevLow;
}
//+------------------------------------------------------------------+
//| BEARISH LIQUIDITY SWEEP |
//+------------------------------------------------------------------+
bool LiquiditySweepSell()
{
double prevHigh =
iHigh(_Symbol, PERIOD_M15, 2);
double currentHigh =
iHigh(_Symbol, PERIOD_M15, 1);
double currentClose =
iClose(_Symbol, PERIOD_M15, 1);
return currentHigh > prevHigh &&
currentClose < prevHigh;
}
//+------------------------------------------------------------------+
//| MARKET STRUCTURE (BOS + CHOCH) |
//+------------------------------------------------------------------+
input int StructureLookback = 5;
bool IsSwingHigh(int shift)
{
double center =
iHigh(_Symbol, PERIOD_M15, shift);
for(int i=1; i<=SwingStrength; i++)
{
if(center <= iHigh(_Symbol, PERIOD_M15, shift-i))
return false;
if(center <= iHigh(_Symbol, PERIOD_M15, shift+i))
return false;
}
return true;
}
bool IsSwingLow(int shift)
{
double center =
iLow(_Symbol, PERIOD_M15, shift);
for(int i=1; i<=SwingStrength; i++)
{
if(center >= iLow(_Symbol, PERIOD_M15, shift-i))
return false;
if(center >= iLow(_Symbol, PERIOD_M15, shift+i))
return false;
}
return true;
}
double GetLastSwingHigh()
{
for(int i=SwingStrength+1;
i<SwingLookback;
i++)
{
if(IsSwingHigh(i))
{
return iHigh(
_Symbol,
PERIOD_M15,
i
);
}
}
return 0;
}
double GetLastSwingLow()
{
for(int i=SwingStrength+1;
i<SwingLookback;
i++)
{
if(IsSwingLow(i))
{
return iLow(
_Symbol,
PERIOD_M15,
i
);
}
}
return 0;
}
//+------------------------------------------------------------------+
//| Bullish BOS |
//+------------------------------------------------------------------+
bool BullishBOS()
{
double currentClose =
iClose(
_Symbol,
PERIOD_M15,
1
);
double swingHigh =
GetLastSwingHigh();
// Fallback to lookback high if no swing high found
if(swingHigh <= 0)
{
swingHigh =
iHigh(
_Symbol,
PERIOD_M15,
2
);
for(int i = 3; i