180 lines
4.1 KiB
Text
180 lines
4.1 KiB
Text
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| SMC Liquidity + BOS + Retest Bot |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
#property strict
|
||
|
|
|
||
|
|
// === INPUTS (EDIT THESE) ===
|
||
|
|
input ENUM_TIMEFRAMES lowerTF = PERIOD_M15;
|
||
|
|
input ENUM_TIMEFRAMES higherTF = PERIOD_H1;
|
||
|
|
|
||
|
|
input double lotSize = 0.1;
|
||
|
|
input int stopLossPips = 20;
|
||
|
|
input int takeProfitPips = 40;
|
||
|
|
|
||
|
|
input int lookback = 10; // candles to detect highs/lows
|
||
|
|
input double retestBuffer = 5; // points tolerance for retest
|
||
|
|
|
||
|
|
// === GLOBAL VARIABLES ===
|
||
|
|
double lastHigh, lastLow;
|
||
|
|
bool sweepDetected = false;
|
||
|
|
bool bosDetected = false;
|
||
|
|
double bosLevel = 0;
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Get Highest High |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double GetRecentHigh(ENUM_TIMEFRAMES tf)
|
||
|
|
{
|
||
|
|
int index = iHighest(_Symbol, tf, MODE_HIGH, lookback, 1);
|
||
|
|
return iHigh(_Symbol, tf, index);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Get Lowest Low |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
double GetRecentLow(ENUM_TIMEFRAMES tf)
|
||
|
|
{
|
||
|
|
int index = iLowest(_Symbol, tf, MODE_LOW, lookback, 1);
|
||
|
|
return iLow(_Symbol, tf, index);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Detect Liquidity Sweep |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool DetectLiquiditySweep()
|
||
|
|
{
|
||
|
|
double prevLow = GetRecentLow(lowerTF);
|
||
|
|
double currentLow = iLow(_Symbol, lowerTF, 0);
|
||
|
|
|
||
|
|
// Sweep below lows (Buy setup)
|
||
|
|
if(currentLow < prevLow)
|
||
|
|
{
|
||
|
|
lastLow = prevLow;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
double prevHigh = GetRecentHigh(lowerTF);
|
||
|
|
double currentHigh = iHigh(_Symbol, lowerTF, 0);
|
||
|
|
|
||
|
|
// Sweep above highs (Sell setup)
|
||
|
|
if(currentHigh > prevHigh)
|
||
|
|
{
|
||
|
|
lastHigh = prevHigh;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Detect Market Structure Break (BOS) |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool DetectBOS()
|
||
|
|
{
|
||
|
|
double high = GetRecentHigh(higherTF);
|
||
|
|
double low = GetRecentLow(higherTF);
|
||
|
|
double close = iClose(_Symbol, higherTF, 0);
|
||
|
|
|
||
|
|
// Bullish BOS
|
||
|
|
if(close > high)
|
||
|
|
{
|
||
|
|
bosLevel = high;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Bearish BOS
|
||
|
|
if(close < low)
|
||
|
|
{
|
||
|
|
bosLevel = low;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Check Retest Entry |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CheckRetest()
|
||
|
|
{
|
||
|
|
double price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
|
||
|
|
if(MathAbs(price - bosLevel) <= retestBuffer * _Point)
|
||
|
|
return true;
|
||
|
|
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Execute Trade |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void ExecuteTrade(bool isBuy)
|
||
|
|
{
|
||
|
|
double sl, tp, price;
|
||
|
|
|
||
|
|
if(isBuy)
|
||
|
|
{
|
||
|
|
price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
|
||
|
|
sl = price - stopLossPips * _Point;
|
||
|
|
tp = price + takeProfitPips * _Point;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
|
||
|
|
sl = price + stopLossPips * _Point;
|
||
|
|
tp = price - takeProfitPips * _Point;
|
||
|
|
}
|
||
|
|
|
||
|
|
MqlTradeRequest request;
|
||
|
|
MqlTradeResult result;
|
||
|
|
|
||
|
|
ZeroMemory(request);
|
||
|
|
ZeroMemory(result);
|
||
|
|
|
||
|
|
request.action = TRADE_ACTION_DEAL;
|
||
|
|
request.symbol = _Symbol;
|
||
|
|
request.volume = lotSize;
|
||
|
|
request.type = isBuy ? ORDER_TYPE_BUY : ORDER_TYPE_SELL;
|
||
|
|
request.price = price;
|
||
|
|
request.sl = sl;
|
||
|
|
request.tp = tp;
|
||
|
|
request.deviation = 10;
|
||
|
|
request.magic = 123456;
|
||
|
|
request.comment = "SMC Bot";
|
||
|
|
|
||
|
|
OrderSend(request, result);
|
||
|
|
}
|
||
|
|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Main Tick Function |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void OnTick()
|
||
|
|
{
|
||
|
|
// Step 1: Detect Liquidity Sweep
|
||
|
|
if(!sweepDetected)
|
||
|
|
{
|
||
|
|
sweepDetected = DetectLiquiditySweep();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Step 2: Confirm BOS
|
||
|
|
if(sweepDetected && !bosDetected)
|
||
|
|
{
|
||
|
|
bosDetected = DetectBOS();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Step 3: Wait for Retest
|
||
|
|
if(sweepDetected && bosDetected)
|
||
|
|
{
|
||
|
|
if(CheckRetest())
|
||
|
|
{
|
||
|
|
bool isBuy = (iClose(_Symbol, higherTF, 0) > bosLevel);
|
||
|
|
ExecuteTrade(isBuy);
|
||
|
|
|
||
|
|
// Reset after trade
|
||
|
|
sweepDetected = false;
|
||
|
|
bosDetected = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|