|
|
//+------------------------------------------------------------------+
//| FVG_ATR_Strategy.mq5 |
//| Combines Fair Value Gap (FVG) theory with ATR for trading signals |
//+------------------------------------------------------------------+
#property copyright "Your Name"
#property link "https://www.example.com"
#property version "1.00"
//--- Input Parameters
input double RiskPercent = 1.0; // Risk per trade (% of account equity)
input int ATR_Period = 14; // ATR Period
input double ATR_SL_Multiplier = 1.5; // ATR multiplier for Stop Loss
input double ATR_TP_Multiplier = 3.0; // ATR multiplier for Take Profit
input int SMA_Period = 200; // SMA Period for trend filter
input int MaxFVGs = 10; // Maximum FVGs to track
input int Lookback = 50; // Lookback period for FVG detection
//--- Global Variables
struct FVG {
double high; // High of FVG zone
double low; // Low of FVG zone
bool isBullish; // True for bullish FVG, false for bearish
bool active; // True if FVG is still valid
};
FVG fvgArray[]; // Array to store FVGs
int fvgCount = 0; // Current number of FVGs
double atrValue; // Current ATR value
double smaValue; // Current SMA value
//--- Handles for Indicators
int atrHandle;
int smaHandle;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Initialize array for FVGs
ArrayResize(fvgArray, MaxFVGs);
for(int i = 0; i < MaxFVGs; i++)
{
fvgArray.high = 0.0;
fvgArray.low = 0.0;
fvgArray.isBullish = false;
fvgArray.active = false;
}
// Create indicator handles
atrHandle = iATR(_Symbol, _Period, ATR_Period);
smaHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE);
if(atrHandle == INVALID_HANDLE || smaHandle == INVALID_HANDLE)
{
Print("Failed to create indicator handle");
return(INIT_FAILED);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
IndicatorRelease(atrHandle);
IndicatorRelease(smaHandle);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
// Update indicators
double atrBuffer[];
double smaBuffer[];
ArraySetAsSeries(atrBuffer, true);
ArraySetAsSeries(smaBuffer, true);
CopyBuffer(atrHandle, 0, 0, 1, atrBuffer);
CopyBuffer(smaHandle, 0, 0, 1, smaBuffer);
atrValue = atrBuffer[0];
smaValue = smaBuffer[0];
// Get current price
MqlTick tick;
SymbolInfoTick(_Symbol, tick);
double currentPrice = tick.bid;
// Detect new FVGs
DetectFVGs();
// Check for trading signals
CheckTradingSignals(currentPrice);
}
//+------------------------------------------------------------------+
//| Detect Fair Value Gaps |
//+------------------------------------------------------------------+
void DetectFVGs()
{
// Get candle data
double high[], low[], close[];
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(close, true);
CopyHigh(_Symbol, _Period, 0, Lookback, high);
CopyLow(_Symbol, _Period, 0, Lookback, low);
CopyClose(_Symbol, _Period, 0, Lookback, close);
// Reset active FVGs
for(int i = 0; i < fvgCount; i++)
fvgArray.active = false;
fvgCount = 0;
// Look for FVGs (3-candle pattern)
for(int i = 2; i < Lookback - 1 && fvgCount < MaxFVGs; i++)
{
// Bullish FVG: low of middle candle > high of previous and next candles
if(low > high[i+1] && low > high[i-1])
{
fvgArray[fvgCount].high = low;
fvgArray[fvgCount].low = MathMax(high[i+1], high[i-1]);
fvgArray[fvgCount].isBullish = true;
fvgArray[fvgCount].active = true;
fvgCount++;
}
// Bearish FVG: high of middle candle < low of previous and next candles
else if(high < low[i+1] && high < low[i-1])
{
fvgArray[fvgCount].high = MathMin(low[i+1], low[i-1]);
fvgArray[fvgCount].low = high;
fvgArray[fvgCount].isBullish = false;
fvgArray[fvgCount].active = true;
fvgCount++;
}
}
}
//+------------------------------------------------------------------+
//| Check for trading signals |
//+------------------------------------------------------------------+
void CheckTradingSignals(double currentPrice)
{
// Check if any position is open
if(PositionSelect(_Symbol)) return;
// Check trend direction
bool isBullishTrend = currentPrice > smaValue;
bool isBearishTrend = currentPrice < smaValue;
// Iterate through FVGs
for(int i = 0; i < fvgCount; i++)
{
if(!fvgArray.active) continue;
// Bullish FVG entry
if(fvgArray.isBullish && isBullishTrend)
{
if(currentPrice >= fvgArray.low && currentPrice <= fvgArray.high)
{
double sl = currentPrice - atrValue * ATR_SL_Multiplier;
double tp = currentPrice + atrValue * ATR_TP_Multiplier;
double lotSize = CalculateLotSize(sl, currentPrice);
trade.Buy(lotSize, _Symbol, currentPrice, sl, tp, "Bullish FVG Entry");
fvgArray.active = false; // Deactivate FVG after entry
break;
}
}
// Bearish FVG entry
else if(!fvgArray.isBullish && isBearishTrend)
{
if(currentPrice <= fvgArray.high && currentPrice >= fvgArray.low)
{
double sl = currentPrice + atrValue * ATR_SL_Multiplier;
double tp = currentPrice - atrValue * ATR_TP_Multiplier;
double lotSize = CalculateLotSize(currentPrice, sl);
trade.Sell(lotSize, _Symbol, currentPrice, sl, tp, "Bearish FVG Entry");
fvgArray.active = false; // Deactivate FVG after entry
break;
}
}
}
}
//+------------------------------------------------------------------+
//| Calculate lot size based on risk |
//+------------------------------------------------------------------+
double CalculateLotSize(double entryPrice, double stopLossPrice)
{
double accountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
double riskAmount = accountEquity * RiskPercent / 100.0;
double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
// Calculate pip value
double pipValue = MathAbs(entryPrice - stopLossPrice) / pointSize;
double lotSize = riskAmount / (pipValue * tickValue);
// Normalize lot size
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
lotSize = MathRound(lotSize / lotStep) * lotStep;
lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
return lotSize;
}
//+------------------------------------------------------------------+
//| Trade object for executing trades |
//+------------------------------------------------------------------+
#include <Trade\Trade.mqh>
CTrade trade;
//+------------------------------------------------------------------+
复制代码 |
|