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




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

推荐加载周期: H4
策略核心逻辑:
1. 趋势检测:EMA(20)与EMA(50)交叉确认趋势方向。
2. 趋势强度:ADX(14)必须大于25,确保处于趋势市场。
3. 入场信号:交叉确认后,等待价格回调至EMA20(价格触及或接近),配合MACD动量确认(做多时MACD柱为正且上升,做空时为负且下降)。
4. 风险管理:动态止损为入场价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个月。历史表现不代表未来结果。
```