180 行
4.1 KiB
Text
180 行
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;
| |||
}
| |||
}
| |||
}
|