- //+------------------------------------------------------------------+
- //| 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;
-
- //+------------------------------------------------------------------+
复制代码
|