FVG结合ATR形成的策略

| 发表于 2026-3-22 00:52:00 | 显示全部楼层 |复制链接
  1. //+------------------------------------------------------------------+
  2. //|                                              FVG_ATR_Strategy.mq5 |
  3. //| Combines Fair Value Gap (FVG) theory with ATR for trading signals |
  4. //+------------------------------------------------------------------+
  5. #property copyright "Your Name"
  6. #property link      "https://www.example.com"
  7. #property version   "1.00"
  8. //--- Input Parameters
  9. input double RiskPercent = 1.0;         // Risk per trade (% of account equity)
  10. input int ATR_Period = 14;              // ATR Period
  11. input double ATR_SL_Multiplier = 1.5;   // ATR multiplier for Stop Loss
  12. input double ATR_TP_Multiplier = 3.0;   // ATR multiplier for Take Profit
  13. input int SMA_Period = 200;             // SMA Period for trend filter
  14. input int MaxFVGs = 10;                 // Maximum FVGs to track
  15. input int Lookback = 50;                // Lookback period for FVG detection
  16. //--- Global Variables
  17. struct FVG {
  18.    double high;       // High of FVG zone
  19.    double low;        // Low of FVG zone
  20.    bool isBullish;    // True for bullish FVG, false for bearish
  21.    bool active;       // True if FVG is still valid
  22. };
  23. FVG fvgArray[];       // Array to store FVGs
  24. int fvgCount = 0;     // Current number of FVGs
  25. double atrValue;      // Current ATR value
  26. double smaValue;      // Current SMA value
  27. //--- Handles for Indicators
  28. int atrHandle;
  29. int smaHandle;
  30. //+------------------------------------------------------------------+
  31. //| Expert initialization function                                     |
  32. //+------------------------------------------------------------------+
  33. int OnInit()
  34. {
  35.    // Initialize array for FVGs
  36.    ArrayResize(fvgArray, MaxFVGs);
  37.    for(int i = 0; i < MaxFVGs; i++)
  38.    {
  39.       fvgArray.high = 0.0;
  40.       fvgArray.low = 0.0;
  41.       fvgArray.isBullish = false;
  42.       fvgArray.active = false;
  43.    }
  44.    // Create indicator handles
  45.    atrHandle = iATR(_Symbol, _Period, ATR_Period);
  46.    smaHandle = iMA(_Symbol, _Period, SMA_Period, 0, MODE_SMA, PRICE_CLOSE);
  47.    if(atrHandle == INVALID_HANDLE || smaHandle == INVALID_HANDLE)
  48.    {
  49.       Print("Failed to create indicator handle");
  50.       return(INIT_FAILED);
  51.    }
  52.    return(INIT_SUCCEEDED);
  53. }
  54. //+------------------------------------------------------------------+
  55. //| Expert deinitialization function                                   |
  56. //+------------------------------------------------------------------+
  57. void OnDeinit(const int reason)
  58. {
  59.    IndicatorRelease(atrHandle);
  60.    IndicatorRelease(smaHandle);
  61. }
  62. //+------------------------------------------------------------------+
  63. //| Expert tick function                                              |
  64. //+------------------------------------------------------------------+
  65. void OnTick()
  66. {
  67.    // Update indicators
  68.    double atrBuffer[];
  69.    double smaBuffer[];
  70.    ArraySetAsSeries(atrBuffer, true);
  71.    ArraySetAsSeries(smaBuffer, true);
  72.    CopyBuffer(atrHandle, 0, 0, 1, atrBuffer);
  73.    CopyBuffer(smaHandle, 0, 0, 1, smaBuffer);
  74.    atrValue = atrBuffer[0];
  75.    smaValue = smaBuffer[0];
  76.    // Get current price
  77.    MqlTick tick;
  78.    SymbolInfoTick(_Symbol, tick);
  79.    double currentPrice = tick.bid;
  80.    // Detect new FVGs
  81.    DetectFVGs();
  82.    // Check for trading signals
  83.    CheckTradingSignals(currentPrice);
  84. }
  85. //+------------------------------------------------------------------+
  86. //| Detect Fair Value Gaps                                            |
  87. //+------------------------------------------------------------------+
  88. void DetectFVGs()
  89. {
  90.    // Get candle data
  91.    double high[], low[], close[];
  92.    ArraySetAsSeries(high, true);
  93.    ArraySetAsSeries(low, true);
  94.    ArraySetAsSeries(close, true);
  95.    CopyHigh(_Symbol, _Period, 0, Lookback, high);
  96.    CopyLow(_Symbol, _Period, 0, Lookback, low);
  97.    CopyClose(_Symbol, _Period, 0, Lookback, close);
  98.    // Reset active FVGs
  99.    for(int i = 0; i < fvgCount; i++)
  100.       fvgArray.active = false;
  101.    fvgCount = 0;
  102.    // Look for FVGs (3-candle pattern)
  103.    for(int i = 2; i < Lookback - 1 && fvgCount < MaxFVGs; i++)
  104.    {
  105.       // Bullish FVG: low of middle candle > high of previous and next candles
  106.       if(low > high[i+1] && low > high[i-1])
  107.       {
  108.          fvgArray[fvgCount].high = low;
  109.          fvgArray[fvgCount].low = MathMax(high[i+1], high[i-1]);
  110.          fvgArray[fvgCount].isBullish = true;
  111.          fvgArray[fvgCount].active = true;
  112.          fvgCount++;
  113.       }
  114.       // Bearish FVG: high of middle candle < low of previous and next candles
  115.       else if(high < low[i+1] && high < low[i-1])
  116.       {
  117.          fvgArray[fvgCount].high = MathMin(low[i+1], low[i-1]);
  118.          fvgArray[fvgCount].low = high;
  119.          fvgArray[fvgCount].isBullish = false;
  120.          fvgArray[fvgCount].active = true;
  121.          fvgCount++;
  122.       }
  123.    }
  124. }
  125. //+------------------------------------------------------------------+
  126. //| Check for trading signals                                         |
  127. //+------------------------------------------------------------------+
  128. void CheckTradingSignals(double currentPrice)
  129. {
  130.    // Check if any position is open
  131.    if(PositionSelect(_Symbol)) return;
  132.    // Check trend direction
  133.    bool isBullishTrend = currentPrice > smaValue;
  134.    bool isBearishTrend = currentPrice < smaValue;
  135.    // Iterate through FVGs
  136.    for(int i = 0; i < fvgCount; i++)
  137.    {
  138.       if(!fvgArray.active) continue;
  139.       // Bullish FVG entry
  140.       if(fvgArray.isBullish && isBullishTrend)
  141.       {
  142.          if(currentPrice >= fvgArray.low && currentPrice <= fvgArray.high)
  143.          {
  144.             double sl = currentPrice - atrValue * ATR_SL_Multiplier;
  145.             double tp = currentPrice + atrValue * ATR_TP_Multiplier;
  146.             double lotSize = CalculateLotSize(sl, currentPrice);
  147.             trade.Buy(lotSize, _Symbol, currentPrice, sl, tp, "Bullish FVG Entry");
  148.             fvgArray.active = false; // Deactivate FVG after entry
  149.             break;
  150.          }
  151.       }
  152.       // Bearish FVG entry
  153.       else if(!fvgArray.isBullish && isBearishTrend)
  154.       {
  155.          if(currentPrice <= fvgArray.high && currentPrice >= fvgArray.low)
  156.          {
  157.             double sl = currentPrice + atrValue * ATR_SL_Multiplier;
  158.             double tp = currentPrice - atrValue * ATR_TP_Multiplier;
  159.             double lotSize = CalculateLotSize(currentPrice, sl);
  160.             trade.Sell(lotSize, _Symbol, currentPrice, sl, tp, "Bearish FVG Entry");
  161.             fvgArray.active = false; // Deactivate FVG after entry
  162.             break;
  163.          }
  164.       }
  165.    }
  166. }
  167. //+------------------------------------------------------------------+
  168. //| Calculate lot size based on risk                                   |
  169. //+------------------------------------------------------------------+
  170. double CalculateLotSize(double entryPrice, double stopLossPrice)
  171. {
  172.    double accountEquity = AccountInfoDouble(ACCOUNT_EQUITY);
  173.    double riskAmount = accountEquity * RiskPercent / 100.0;
  174.    double pointSize = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
  175.    double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
  176.    double tickValue = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
  177.    // Calculate pip value
  178.    double pipValue = MathAbs(entryPrice - stopLossPrice) / pointSize;
  179.    double lotSize = riskAmount / (pipValue * tickValue);
  180.    // Normalize lot size
  181.    double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
  182.    double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
  183.    double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
  184.    lotSize = MathRound(lotSize / lotStep) * lotStep;
  185.    lotSize = MathMax(minLot, MathMin(maxLot, lotSize));
  186.    return lotSize;
  187. }
  188. //+------------------------------------------------------------------+
  189. //| Trade object for executing trades                                 |
  190. //+------------------------------------------------------------------+
  191. #include <Trade\Trade.mqh>
  192. CTrade trade;
  193. //+------------------------------------------------------------------+
复制代码
143138nhryezg5yggdi5oo.png
ScreenShot_2026-03-22_005213_484.png
举报

评论 使用道具

精彩评论1

话糙理不糙
D
| 发表于 2026-5-7 17:47:59 | 显示全部楼层
是你自己写的么大神
举报

点赞 评论 使用道具

发新帖
EA交易
您需要登录后才可以评论 登录 | 立即注册