Summary: 黄金趋势网格EA是一款融合趋势过滤与受控网格系统的MQL4智能交易系统。仅沿趋势方向布置网格,基于ATR动态调整间距和手数,适合H1周期稳定运行。
黄金趋势网格EA独特地将趋势跟踪与纪律化的网格方法相结合。与传统的双向网格EA不同,本EA首先使用EMA(50)和ADX(14)确定主趋势。趋势确立后,开立基础仓位并仅在趋势方向布置挂单网格。网格间距和手数递增根据ATR波动率动态调整。EA包含最大网格层数、基于净值的回撤保护以及随网格规模放大的止盈目标。
推荐加载周期: H1
策略核心逻辑:
1. 趋势检测:EMA(50)斜率+价格位置,ADX>25确认趋势市场存在。
2. 基础入场:趋势确认后,以0.01手市价入场。
3. 趋势网格布置:在ATR计算的间距上,沿趋势方向布置挂单(上涨趋势布置buy limit,下跌趋势布置sell limit)。
4. 网格递进:每层手数乘以GridLotMultiplier(例如1.5倍),最多5层。
5. 网格出场:总浮动盈利达到目标点数时全网格平仓,或达到回撤限制时紧急平仓。
```mql4
//+------------------------------------------------------------------+
//| GoldTrendGridEA.mq4 |
//+------------------------------------------------------------------+
#property copyright ""
#property link ""
#property version "1.00"
#property strict
//--- 输入参数及注释
input double BaseLotSize = 0.01; // 基础手数(首层)
input int TrendEMAPeriod = 50; // EMA趋势判断周期
input int ADXPeriod = 14; // ADX趋势强度周期
input int ADXThreshold = 25; // ADX阈值(高于此值才认为有趋势)
input double GridSpacingATR = 1.5; // 网格间距(ATR倍数)
input double GridLotMultiplier = 1.5; // 网格手数倍数(每层递增1.5倍)
input int MaxGridLevels = 5; // 最大网格层数
input int TargetProfitPoints = 800; // 网格止盈目标点数
input double EquityDrawdownLimit = 12.0; // 最大净值回撤百分比(停止并平仓)
input int MagicNumber = 202418; // EA魔术号
input int MaxSpread = 35; // 最大允许点差(单位:点)
input bool UseFridayClose = true; // 周五20:00 GMT前平仓
//--- 全局变量
datetime lastBarTime = 0;
bool fridayCloseExecuted = false;
double currentTrend = 0; // 1=多头, -1=空头, 0=无趋势
double lastATR = 0;
double gridStartPrice = 0;
int currentGridLevel = 0;
double equityStart = 0;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
lastBarTime = 0;
fridayCloseExecuted = false;
equityStart = AccountEquity();
currentTrend = 0;
currentGridLevel = 0;
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA退出函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| 判断趋势方向 |
//+------------------------------------------------------------------+
int GetTrend()
{
double ema = iMA(Symbol(), PERIOD_H1, TrendEMAPeriod, 0, MODE_EMA, PRICE_CLOSE, 1);
double close1 = iClose(Symbol(), PERIOD_H1, 1);
double adx = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MAIN, 1);
double diPlus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_PLUSDI, 1);
double diMinus = iADX(Symbol(), PERIOD_H1, ADXPeriod, PRICE_CLOSE, MODE_MINUSDI, 1);
if(adx < ADXThreshold) return 0;
// 多头:价格高于EMA 且 DI+ > DI-
if(close1 > ema && diPlus > diMinus)
return 1;
// 空头:价格低于EMA 且 DI- > DI+
else if(close1 < ema && diMinus > diPlus)
return -1;
return 0;
}
//+------------------------------------------------------------------+
//| 基于ATR计算动态网格间距 |
//+------------------------------------------------------------------+
double GetGridSpacing()
{
double atr = iATR(Symbol(), PERIOD_H1, 14, 1);
if(atr <= 0) atr = 200 * Point;
lastATR = atr;
return atr * GridSpacingATR;
}
//+------------------------------------------------------------------+
//| 统计当前网格订单数量(市价+挂单) |
//+------------------------------------------------------------------+
int CountGridOrders()
{
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++;
}
}
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_PENDING))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
//| 平仓所有网格订单(市价单和挂单) |
//+------------------------------------------------------------------+
void CloseAllGridOrders()
{
// 平仓市价单
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, 3, clrNONE);
else if(OrderType() == OP_SELL)
OrderClose(OrderTicket(), OrderLots(), Ask, 3, clrNONE);
}
}
}
// 删除挂单
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_PENDING))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
OrderDelete(OrderTicket());
}
}
}
//+------------------------------------------------------------------+
//| 计算网格总浮动盈亏 |
//+------------------------------------------------------------------+
double GetGridFloatingProfit()
{
double profit = 0;
for(int i = OrdersTotal()-1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
profit += OrderProfit() + OrderSwap() + OrderCommission();
}
}
return profit;
}
//+------------------------------------------------------------------+
//| 创建趋势方向的挂单网格 |
//+------------------------------------------------------------------+
void CreateGridOrders()
{
if(currentTrend == 0) return;
double spacing = GetGridSpacing();
double currentPrice = (currentTrend == 1) ? Ask : Bid;
for(int level = 1; level <= MaxGridLevels; level++)
{
double orderPrice;
if(currentTrend == 1) // 多头:buy limit挂在上方
orderPrice = currentPrice + (spacing * level);
else // 空头:sell limit挂在下方
orderPrice = currentPrice - (spacing * level);
double lotSize = BaseLotSize * MathPow(GridLotMultiplier, level - 1);
if(lotSize > 1.0) lotSize = 1.0;
int cmd = (currentTrend == 1) ? OP_BUYLIMIT : OP_SELLLIMIT;
int ticket = OrderSend(Symbol(), cmd, lotSize, orderPrice, 3, 0, 0, "Trend Grid", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("创建网格第", level, "层失败,错误码:", GetLastError());
else
Print("网格第", level, "层已创建,价格:", orderPrice);
}
}
//+------------------------------------------------------------------+
//| 检查网格是否应平仓(止盈或回撤保护) |
//+------------------------------------------------------------------+
bool ShouldCloseGrid()
{
double profit = GetGridFloatingProfit();
// 粗略估算目标盈利:点数 * 手数估算
double targetProfit = TargetProfitPoints * Point * (CountGridOrders() * BaseLotSize * 10);
if(profit >= targetProfit)
return true;
// 回撤保护
double equityDrawdown = (equityStart - AccountEquity()) / equityStart * 100;
if(equityDrawdown >= EquityDrawdownLimit)
return true;
return false;
}
//+------------------------------------------------------------------+
//| EA主循环函数(每Tick执行) |
//+------------------------------------------------------------------+
void OnTick()
{
// 周五收盘保护
if(UseFridayClose && !fridayCloseExecuted)
{
datetime currentTime = TimeCurrent();
if(TimeDayOfWeek(currentTime) == 5 && TimeHour(currentTime) >= 20)
{
CloseAllGridOrders();
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(TimeDayOfYear(TimeCurrent()) != TimeDayOfYear(TimeCurrent() - 86400))
equityStart = AccountEquity();
// 检查网格是否应平仓
if(CountGridOrders() > 0 && ShouldCloseGrid())
{
CloseAllGridOrders();
currentGridLevel = 0;
Comment("网格已平仓(止盈或回撤保护)");
return;
}
// 判断趋势
int newTrend = GetTrend();
currentTrend = newTrend;
// 无现有网格且趋势有效,启动新网格
if(CountGridOrders() == 0 && currentTrend != 0)
{
// 开立基础市价单
double lot = BaseLotSize;
double sl = 0, tp = 0;
int cmd = (currentTrend == 1) ? OP_BUY : OP_SELL;
double price = (cmd == OP_BUY) ? Ask : Bid;
int ticket = OrderSend(Symbol(), cmd, lot, price, 3, sl, tp, "Base Grid", MagicNumber, 0, clrNONE);
if(ticket > 0)
{
Print("趋势方向基础仓位已开仓");
CreateGridOrders();
}
}
else if(CountGridOrders() > 0 && currentTrend == 0)
{
// 趋势减弱,平仓网格
CloseAllGridOrders();
Comment("趋势减弱,网格已平仓");
}
// 状态显示
double profit = GetGridFloatingProfit();
Comment("趋势方向:", currentTrend==1?"多头":(currentTrend==-1?"空头":"无趋势"),
" | 网格订单数:", CountGridOrders(),
" | 浮动盈亏:", DoubleToStr(profit, 2),
" | ATR:", DoubleToStr(lastATR/Point, 1));
}
//+------------------------------------------------------------------+
```
参考来源: 原创MQL4代码,仅供学习参考。
免责声明: 网格交易在强趋势或震荡市场中可能带来较大回撤风险。本EA按“原样”提供,不保证盈利。实盘部署前请在模拟账户测试至少3个月。历史表现不代表未来结果。
```