Summary: 黄金K线稳定器EA是一款专为XAUUSD设计的MQL4智能交易系统。识别孕线形态、动量K线和假突破拒绝信号,适合H1周期稳定运行。




黄金K线稳定器EA专注于纯K线分析,不使用传统指标。它识别孕线(窄幅盘整)、动量K线(实体大、影线小)以及假突破拒绝信号(价格刺穿区间但收盘回归)。EA等待压缩形态(孕线)出现,随后动量K线突破区间,在价格回踩确认时入场。基于孕线区间的动态止损和风险控制的盈利目标确保了稳定性。

推荐加载周期: H1
策略核心逻辑:
  • 孕线检测:当前K线最高价 ≤ 前一根K线最高价,且最低价 ≥ 前一根K线最低价。

  • 压缩确认:要求孕线实体的体幅比 > 0.6(强盘整)。

  • 动量信号:下一根K线收盘价高于孕线高点(做多)或低于孕线低点(做空),且实体 > 2倍影线。

  • 回踩入场:等待价格回测被突破的区间边界(50%-80%回撤幅度)再入场。

  • 风险管理:止损设在孕线区间另一侧,止盈为2倍孕线区间,盈利达到1倍区间后启动追踪止损。


  • ``mql4
    //+------------------------------------------------------------------+
    //| GoldKBarStabilizer.mq4 |
    //+------------------------------------------------------------------+
    #property copyright ""
    #property link ""
    #property version "1.00"
    #property strict

    //--- 输入参数及注释
    input double LotSize = 0.01; // 固定交易手数(黄金0.01手)
    input double BodyToRangeMinRatio = 0.6; // 孕线实体最小体幅比(强盘整要求)
    input double MomentumBodyWickRatio = 2.0; // 动量K线实体/影线最小比例
    input double RetracementMinPercent = 0.5; // 最小回撤百分比(突破区间的50%)
    input double RetracementMaxPercent = 0.8; // 最大回撤百分比(突破区间的80%)
    input double StopLossMultiplier = 1.0; // 止损倍数(孕线区间的倍数)
    input double TakeProfitMultiplier = 2.0; // 止盈倍数(孕线区间的倍数)
    input double TrailingActivate = 1.0; // 追踪止损启动(盈利达到x倍孕线区间)
    input double TrailingStep = 0.5; // 追踪步长(孕线区间倍数)
    input int MagicNumber = 202418; // EA魔术号
    input int MaxSpread = 35; // 最大允许点差(黄金单位:点)
    input double DailyLossLimit = 5.0; // 每日亏损限额(账户余额百分比)
    input bool UseFridayClose = true; // 周五21:00 GMT前平仓

    //--- 全局变量
    double dailyStartBalance = 0;
    datetime lastBarTime = 0;
    bool fridayCloseExecuted = false;
    double insideBarHigh = 0;
    double insideBarLow = 0;
    double insideBarRange = 0;
    double breakoutPrice = 0;
    int breakoutDirection = 0; // 1=做多, -1=做空
    datetime insideBarTime = 0;

    //+------------------------------------------------------------------+
    //| EA初始化函数 |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    dailyStartBalance = AccountBalance();
    lastBarTime = 0;
    fridayCloseExecuted = false;
    insideBarHigh = 0;
    insideBarLow = 0;
    breakoutDirection = 0;
    return(INIT_SUCCEEDED);
    }

    //+------------------------------------------------------------------+
    //| EA退出函数 |
    //+------------------------------------------------------------------+
    void OnDeinit(const int reason)
    {
    Comment("");
    }

    //+------------------------------------------------------------------+
    //| 计算K线实体与区间比例 |
    //+------------------------------------------------------------------+
    double BodyToRangeRatio(int shift)
    {
    double open = iOpen(Symbol(), PERIOD_H1, shift);
    double close = iClose(Symbol(), PERIOD_H1, shift);
    double high = iHigh(Symbol(), PERIOD_H1, shift);
    double low = iLow(Symbol(), PERIOD_H1, shift);
    double body = MathAbs(close - open);
    double range = high - low;
    if(range <= 0) return 0;
    return body / range;
    }

    //+------------------------------------------------------------------+
    //| 检测孕线形态 |
    //+------------------------------------------------------------------+
    bool IsInsideBar(int shift)
    {
    double currHigh = iHigh(Symbol(), PERIOD_H1, shift);
    double currLow = iLow(Symbol(), PERIOD_H1, shift);
    double prevHigh = iHigh(Symbol(), PERIOD_H1, shift + 1);
    double prevLow = iLow(Symbol(), PERIOD_H1, shift + 1);

    return (currHigh <= prevHigh && currLow >= prevLow);
    }

    //+------------------------------------------------------------------+
    //| 检测动量K线(实体大,影线小) |
    //+------------------------------------------------------------------+
    bool IsMomentumCandle(int shift, int direction)
    {
    double open = iOpen(Symbol(), PERIOD_H1, shift);
    double close = iClose(Symbol(), PERIOD_H1, shift);
    double high = iHigh(Symbol(), PERIOD_H1, shift);
    double low = iLow(Symbol(), PERIOD_H1, shift);
    double body = MathAbs(close - open);
    double upperWick = high - MathMax(open, close);
    double lowerWick = MathMin(open, close) - low;
    double maxWick = MathMax(upperWick, lowerWick);

    if(maxWick <= 0) return false;
    if(body / maxWick < MomentumBodyWickRatio) return false;

    if(direction == 1) // 看涨动量
    return (close > open && close > insideBarHigh);
    else if(direction == -1) // 看跌动量
    return (close < open && close < insideBarLow);

    return false;
    }

    //+------------------------------------------------------------------+
    //| 检查回撤入场机会 |
    //+------------------------------------------------------------------+
    bool CheckRetracementEntry(int &cmd, double &entryPrice, double &stopLoss, double &takeProfit)
    {
    if(breakoutDirection == 0) return false;
    if(insideBarRange <= 0) return false;

    double currentPrice = (breakoutDirection == 1) ? Bid : Ask;
    double breakoutHigh = insideBarHigh;
    double breakoutLow = insideBarLow;
    double retraceLow = breakoutHigh - (insideBarRange RetracementMaxPercent);
    double retraceHigh = breakoutLow + (insideBarRange
    RetracementMaxPercent);

    if(breakoutDirection == 1) // 做多:价格突破孕线高点,现在回撤
    {
    if(currentPrice <= breakoutHigh && currentPrice >= retraceLow)
    {
    cmd = OP_BUY;
    entryPrice = Ask;
    stopLoss = insideBarLow - (insideBarRange StopLossMultiplier 0.3);
    takeProfit = insideBarHigh + (insideBarRange TakeProfitMultiplier);
    return true;
    }
    }
    else if(breakoutDirection == -1) // 做空:价格跌破孕线低点,现在回抽
    {
    if(currentPrice >= breakoutLow && currentPrice <= retraceHigh)
    {
    cmd = OP_SELL;
    entryPrice = Bid;
    stopLoss = insideBarHigh + (insideBarRange
    StopLossMultiplier 0.3);
    takeProfit = insideBarLow - (insideBarRange
    TakeProfitMultiplier);
    return true;
    }
    }

    return false;
    }

    //+------------------------------------------------------------------+
    //| 管理追踪止损 |
    //+------------------------------------------------------------------+
    void ManageTrailing()
    {
    if(insideBarRange <= 0) return;

    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    double activateLevel = insideBarRange TrailingActivate;
    double step = insideBarRange
    TrailingStep;
    double newSL = 0;

    if(OrderType() == OP_BUY)
    {
    double profit = Bid - OrderOpenPrice();
    if(profit >= activateLevel)
    {
    newSL = Bid - step;
    if(newSL > OrderStopLoss())
    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
    }
    }
    else if(OrderType() == OP_SELL)
    {
    double profit = OrderOpenPrice() - Ask;
    if(profit >= activateLevel)
    {
    newSL = Ask + step;
    if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
    OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
    }
    }
    break;
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| EA主循环函数(每Tick执行) |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // 每日净值保护
    double currentEquity = AccountEquity();
    double lossPercent = (dailyStartBalance - currentEquity) / dailyStartBalance 100;
    if(lossPercent >= DailyLossLimit)
    {
    Comment("已达每日亏损上限,停止开新仓");
    return;
    }

    // 周五收盘前平仓(规避周末跳空)
    if(UseFridayClose && !fridayCloseExecuted)
    {
    datetime currentTime = TimeCurrent();
    if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 21)
    {
    CloseAllOrders();
    fridayCloseExecuted = true;
    return;
    }
    if(TimeDayOfWeek(currentTime) != 5)
    fridayCloseExecuted = false;
    }

    // 点差过滤
    if(MarketInfo(Symbol(), MODE_SPREAD) > MaxSpread)
    {
    Comment("当前点差过大:", MarketInfo(Symbol(), MODE_SPREAD));
    return;
    }

    // 仅在新K线开始时检测入场(H1)
    if(Time[0] == lastBarTime)
    return;
    lastBarTime = Time[0];

    // 管理现有持仓
    if(CountPositions() > 0)
    {
    ManageTrailing();
    return;
    }

    // 如果孕线时间超过5根K线,重置突破状态
    if(insideBarTime > 0 && TimeCurrent() - insideBarTime > 5
    3600)
    {
    breakoutDirection = 0;
    insideBarHigh = 0;
    insideBarLow = 0;
    insideBarRange = 0;
    }

    // 步骤1:检测前一根K线(shift=1)是否为孕线
    if(IsInsideBar(1))
    {
    double ratio = BodyToRangeRatio(1);
    if(ratio >= BodyToRangeMinRatio)
    {
    insideBarHigh = iHigh(Symbol(), PERIOD_H1, 1);
    insideBarLow = iLow(Symbol(), PERIOD_H1, 1);
    insideBarRange = insideBarHigh - insideBarLow;
    insideBarTime = iTime(Symbol(), PERIOD_H1, 1);
    breakoutDirection = 0;
    }
    }

    // 步骤2:孕线检测后,检查当前K线(shift=0)是否有动量突破
    if(insideBarRange > 0 && breakoutDirection == 0)
    {
    if(IsMomentumCandle(0, 1))
    {
    breakoutDirection = 1;
    breakoutPrice = iClose(Symbol(), PERIOD_H1, 0);
    }
    else if(IsMomentumCandle(0, -1))
    {
    breakoutDirection = -1;
    breakoutPrice = iClose(Symbol(), PERIOD_H1, 0);
    }
    }

    // 步骤3:突破后,等待回撤并入场
    if(breakoutDirection != 0 && CountPositions() == 0)
    {
    int cmd = -1;
    double entryPrice = 0, sl = 0, tp = 0;

    if(CheckRetracementEntry(cmd, entryPrice, sl, tp))
    {
    int ticket = OrderSend(Symbol(), cmd, LotSize, entryPrice, 5, sl, tp, "Gold K-Bar", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    {
    Print("开仓失败,错误码:", GetLastError());
    }
    else
    {
    Print("回撤入场成功,方向:", cmd==OP_BUY?"买入":"卖出");
    // 重置以避免同一形态重复入场
    breakoutDirection = 0;
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| 统计当前魔术号的持仓数量 |
    //+------------------------------------------------------------------+
    int CountPositions()
    {
    int count = 0;
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    count++;
    }
    }
    return count;
    }

    //+------------------------------------------------------------------+
    //| 平仓当前品种下所有属于该EA的订单 |
    //+------------------------------------------------------------------+
    void CloseAllOrders()
    {
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    if(OrderType() == OP_BUY)
    OrderClose(OrderTicket(), OrderLots(), Bid, 5, clrNONE);
    else if(OrderType() == OP_SELL)
    OrderClose(OrderTicket(), OrderLots(), Ask, 5, clrNONE);
    }
    }
    }
    }
    //+------------------------------------------------------------------+
    `
    参考来源: 原创MQL4代码,仅供学习参考。
    免责声明: 黄金交易因高波动性和杠杆具有重大风险。本EA按“原样”提供,不保证盈利。实盘交易前请在模拟账户测试至少1个月。历史表现不代表未来结果。
    ``