Summary: 比特币趋势坚甲EA是一款稳定趋势跟踪型MQL4智能交易系统。结合双EMA趋势检测、ADX强度过滤和ATR动态止损,适合H4周期。




比特币趋势坚甲EA专为比特币(BTCUSD)的稳定趋势自动化交易而设计。与高频或网格策略不同,本EA专注于捕捉持续的中期趋势,同时避免假突破和高波动震荡。系统使用双EMA交叉判断趋势方向,ADX过滤弱势/非趋势市场,ATR用于动态止损止盈。独特的波动率动态手数在比特币波动飙升时自动降低敞口。EA包含每日最大回撤保护、点差控制和周末跳空规避。

推荐加载周期: H4
策略核心逻辑:
  • 趋势检测:EMA(20)与EMA(50)交叉确认趋势方向。

  • 趋势强度:ADX(14)必须大于25,确保处于趋势市场。

  • 入场信号:交叉确认后,等待价格回调至EMA20(价格触及或接近),配合MACD动量确认(做多时MACD柱为正且上升,做空时为负且下降)。

  • 风险管理:动态止损为入场价2倍ATR,止盈为4倍ATR。盈利达到1.5倍ATR后启动追踪止损。当ATR超过平均ATR的1.5倍时自动减小手数。


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

    //--- 输入参数及注释
    input double BaseLotSize = 0.01; // 基础手数(0.01 BTC)
    input int FastEMAPeriod = 20; // 快EMA周期(趋势检测)
    input int SlowEMAPeriod = 50; // 慢EMA周期(趋势检测)
    input int ADXPeriod = 14; // ADX周期(趋势强度过滤)
    input int ADXThreshold = 25; // 最小ADX阈值
    input int MACDFast = 12; // MACD快线周期
    input int MACDSlow = 26; // MACD慢线周期
    input int MACDSignal = 9; // MACD信号线周期
    input int ATRPeriod = 14; // ATR周期(动态止损止盈)
    input double ATRStopMultiplier = 2.0; // 止损倍数(ATR倍数)
    input double ATRTakeMultiplier = 4.0; // 止盈倍数(ATR倍数)
    input double TrailingStartMulti = 1.5; // 追踪止损启动倍数(盈利达到此ATR倍数后启动)
    input double TrailingStepMulti = 0.8; // 追踪步长倍数(ATR倍数)
    input double VolatilityLotReduce = 1.5; // 波动率减仓阈值(ATR > avgATR 此值时减小手数)
    input int MagicNumber = 202417; // EA魔术号
    input int MaxSpread = 120; // 最大允许点差(比特币点差较大)
    input double MaxDailyDrawdown = 6.0; // 每日最大回撤百分比
    input bool UseSaturdayClose = true; // 周六22:00 GMT前平仓

    //--- 全局变量
    double dailyStartEquity = 0;
    datetime lastBarTime = 0;
    bool saturdayCloseExecuted = false;
    double avgATR = 0;
    double baseATR = 0;

    //+------------------------------------------------------------------+
    //| EA初始化函数 |
    //+------------------------------------------------------------------+
    int OnInit()
    {
    dailyStartEquity = AccountEquity();
    lastBarTime = 0;
    saturdayCloseExecuted = false;
    avgATR = iATR(Symbol(), PERIOD_H4, ATRPeriod, 1);
    if(avgATR <= 0) avgATR = 800
    Point;
    baseATR = avgATR;
    return(INIT_SUCCEEDED);
    }

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

    //+------------------------------------------------------------------+
    //| 根据当前波动率获取动态手数 |
    //+------------------------------------------------------------------+
    double GetDynamicLotSize(double currentATR)
    {
    double lot = BaseLotSize;
    if(currentATR > avgATR VolatilityLotReduce && avgATR > 0)
    {
    lot = BaseLotSize
    (avgATR / currentATR);
    }
    if(lot < 0.005) lot = 0.005;
    if(lot > 0.5) lot = 0.5;
    lot = NormalizeDouble(lot, 2);
    return lot;
    }

    //+------------------------------------------------------------------+
    //| 使用EMA交叉判断趋势方向 |
    //+------------------------------------------------------------------+
    int GetTrendDirection()
    {
    double fastEMA = iMA(Symbol(), PERIOD_H4, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double slowEMA = iMA(Symbol(), PERIOD_H4, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double fastEMAPrev = iMA(Symbol(), PERIOD_H4, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);
    double slowEMAPrev = iMA(Symbol(), PERIOD_H4, SlowEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 2);

    // 上涨趋势
    if(fastEMA > slowEMA && fastEMAPrev <= slowEMAPrev)
    return 1; // 新鲜金叉
    if(fastEMA > slowEMA)
    return 2; // 已确立的上涨趋势
    // 下跌趋势
    if(fastEMA < slowEMA && fastEMAPrev >= slowEMAPrev)
    return -1; // 新鲜死叉
    if(fastEMA < slowEMA)
    return -2; // 已确立的下跌趋势

    return 0; // 无明确趋势
    }

    //+------------------------------------------------------------------+
    //| 检查MACD看涨动量确认 |
    //+------------------------------------------------------------------+
    bool IsMACDBullish()
    {
    double macdMain = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_MAIN, 1);
    double macdSignal = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_SIGNAL, 1);
    double macdHist = macdMain - macdSignal;
    double macdHistPrev = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_MAIN, 2) -
    iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_SIGNAL, 2);

    return (macdHist > 0 && macdHist > macdHistPrev);
    }

    bool IsMACDBearish()
    {
    double macdMain = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_MAIN, 1);
    double macdSignal = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_SIGNAL, 1);
    double macdHist = macdMain - macdSignal;
    double macdHistPrev = iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_MAIN, 2) -
    iMACD(Symbol(), PERIOD_H4, MACDFast, MACDSlow, MACDSignal, PRICE_CLOSE, MODE_SIGNAL, 2);

    return (macdHist < 0 && macdHist < macdHistPrev);
    }

    //+------------------------------------------------------------------+
    //| 检查价格是否回调至快EMA |
    //+------------------------------------------------------------------+
    bool IsPullbackToEMA(int trendDir)
    {
    double fastEMA = iMA(Symbol(), PERIOD_H4, FastEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
    double close1 = iClose(Symbol(), PERIOD_H4, 1);
    double low1 = iLow(Symbol(), PERIOD_H4, 1);
    double high1 = iHigh(Symbol(), PERIOD_H4, 1);
    double emaRange = fastEMA 0.002; // 比特币使用0.2%容差

    if(trendDir > 0) // 上涨趋势,价格应回调至EMA附近
    {
    return (low1 <= fastEMA + emaRange && close1 > fastEMA);
    }
    else if(trendDir < 0) // 下跌趋势
    {
    return (high1 >= fastEMA - emaRange && close1 < fastEMA);
    }
    return false;
    }

    //+------------------------------------------------------------------+
    //| EA主循环函数(每Tick执行) |
    //+------------------------------------------------------------------+
    void OnTick()
    {
    // 每日回撤保护
    double currentEquity = AccountEquity();
    double drawdownPercent = (dailyStartEquity - currentEquity) / dailyStartEquity
    100;
    if(drawdownPercent >= MaxDailyDrawdown)
    {
    Comment("已达每日最大回撤,停止开新仓");
    if(CountPositions() > 0 && drawdownPercent >= MaxDailyDrawdown + 2)
    CloseAllOrders();
    return;
    }

    // 周六收盘前平仓(规避周末跳空)
    if(UseSaturdayClose && !saturdayCloseExecuted)
    {
    datetime currentTime = TimeCurrent();
    if(TimeDayOfWeek(currentTime) == 6 && TimeHour(currentTime) >= 22)
    {
    CloseAllOrders();
    saturdayCloseExecuted = true;
    return;
    }
    if(TimeDayOfWeek(currentTime) != 6)
    saturdayCloseExecuted = false;
    }

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

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

    // 更新平均ATR用于波动率参考
    double currentATR = iATR(Symbol(), PERIOD_H4, ATRPeriod, 1);
    if(currentATR > 0) avgATR = (avgATR 0.9) + (currentATR 0.1);

    // 管理现有持仓的追踪止损
    if(CountPositions() > 0)
    {
    ManageTrailingStop();
    return;
    }

    // ADX趋势强度过滤
    double adx = iADX(Symbol(), PERIOD_H4, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
    if(adx < ADXThreshold)
    {
    Comment("趋势较弱,ADX: ", adx);
    return;
    }

    // 获取趋势方向
    int trendDir = GetTrendDirection();
    if(trendDir == 0)
    {
    Comment("无明确趋势方向");
    return;
    }

    // 检查回调条件
    if(!IsPullbackToEMA(trendDir))
    {
    Comment("未回调至EMA");
    return;
    }

    int cmd = -1;
    double sl = 0, tp = 0;
    double ask = Ask;
    double bid = Bid;
    double dynamicLot = GetDynamicLotSize(currentATR);

    // 做多信号:上涨趋势,回调确认,MACD看涨动量
    if((trendDir == 1 || trendDir == 2) && IsMACDBullish())
    {
    cmd = OP_BUY;
    sl = bid - (currentATR ATRStopMultiplier);
    tp = bid + (currentATR
    ATRTakeMultiplier);
    }
    // 做空信号:下跌趋势,回调确认,MACD看跌动量
    else if((trendDir == -1 || trendDir == -2) && IsMACDBearish())
    {
    cmd = OP_SELL;
    sl = ask + (currentATR ATRStopMultiplier);
    tp = ask - (currentATR
    ATRTakeMultiplier);
    }

    if(cmd != -1)
    {
    int ticket = OrderSend(Symbol(), cmd, dynamicLot, (cmd==OP_BUY?ask:bid), 5, sl, tp, "BTC Trend Armor", MagicNumber, 0, clrNONE);
    if(ticket < 0)
    Print("开仓失败,错误码:", GetLastError());
    }
    }

    //+------------------------------------------------------------------+
    //| 管理持仓的追踪止损 |
    //+------------------------------------------------------------------+
    void ManageTrailingStop()
    {
    for(int i = OrdersTotal()-1; i >= 0; i--)
    {
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
    {
    if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
    {
    double currentATR = iATR(Symbol(), PERIOD_H4, ATRPeriod, 1);
    if(currentATR <= 0) currentATR = avgATR;

    double trailStartPrice = currentATR TrailingStartMulti;
    double trailStep = currentATR
    TrailingStepMulti;
    double newSL = 0;

    if(OrderType() == OP_BUY)
    {
    double profitPoints = (Bid - OrderOpenPrice());
    if(profitPoints >= trailStartPrice)
    {
    newSL = Bid - trailStep;
    if(newSL > OrderStopLoss())
    {
    if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
    Print("买入追踪止损已更新 #", OrderTicket());
    }
    }
    }
    else if(OrderType() == OP_SELL)
    {
    double profitPoints = (OrderOpenPrice() - Ask);
    if(profitPoints >= trailStartPrice)
    {
    newSL = Ask + trailStep;
    if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
    {
    if(OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE))
    Print("卖出追踪止损已更新 #", OrderTicket());
    }
    }
    }
    break;
    }
    }
    }
    }

    //+------------------------------------------------------------------+
    //| 统计当前魔术号的持仓数量 |
    //+------------------------------------------------------------------+
    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按“原样”提供,不保证盈利。实盘部署前请至少在模拟账户测试3个月。历史表现不代表未来结果。
    ``