Summary: 教育用途的马丁格尔EA源码,含完整MQL4代码。支持仓位倍数、间隔距离、最大层数限制和净值回撤保护。附策略原理说明和风险评估。




# 免费马丁格尔EA源码MT4下载 – 完整网格交易策略

重要风险提示



马丁格尔策略存在极高风险。 虽然它看起来胜率很高,但一次连续亏损就会导致指数级的巨大损失。本EA仅供学习研究,帮助你理解网格和马丁格尔系统的内部运作机制。未经充分测试和严格风控,绝对不要用于实盘账户。

马丁格尔EA的工作原理



逻辑简单但威力巨大:

1. 首单开仓:以基础手数开仓
2. 若亏损达到设定点数:在相同方向加开新订单
3. 每加仓一次:手数乘以上一单的倍数(如2倍)
4. 价格回调时:所有持仓的综合利润达到止盈目标后统一平仓

示例说明



| 加仓次数 | 手数 | 买入价 | 亏损20点时 |
| :--- | :--- | :--- | :--- |
| 1 | 0.01 | 1.1000 | -2美元 |
| 2 | 0.02 | 1.0980 | -4美元 |
| 3 | 0.04 | 1.0960 | -8美元 |
| 4 | 0.08 | 1.0940 | -16美元 |

在1.0940时总浮亏: -30美元。价格回调20点到1.0960时,所有亏损回补并开始盈利。

核心功能



| 功能 | 说明 |
| :--- | :--- |
| 可调节倍数 | 手数递增倍数,通常设为1.5-3倍 |
| 可调节间隔 | 每层网格之间的点数距离 |
| 最大层数限制 | 防止网格无限扩张 |
| 净值回撤保护 | 净值跌幅超限时自动全部平仓 |
| 止盈目标 | 总盈利达到目标后统一平仓 |
| 方向控制 | 只做多、只做空或均线信号判断 |

完整MQL4源码



复制下方完整代码,保存为 `Martingale_Grid_EA.mq4` 至 `MQL4/Experts/` 文件夹,然后编译。

```cpp
//+------------------------------------------------------------------+
//| Martingale_Grid_EA.mq4 |
//| 自主编译 |
//| |
//+------------------------------------------------------------------+
#property copyright "ForexEA博客"
#property link ""
#property version "1.00"
#property strict

//--- 输入参数
input double LotSize = 0.01; // 基础手数
input double LotMultiplier = 2.0; // 手数倍数(1.5-3.0)
input int StepPips = 20; // 加仓间隔点数
input int MaxTrades = 5; // 最大加仓层数
input double TakeProfitPips = 20; // 总体止盈点数
input double MaxEquityDrawdown = 30.0; // 最大净值回撤百分比
input int Slippage = 3; // 滑点
input bool UseMAFilter = false; // 使用均线过滤方向
input int MAPeriod = 50; // 均线周期
input bool TradeBuyOnly = false; // 只做多
input bool TradeSellOnly = false; // 只做空
input int MagicNumber = 20260603; // EA识别码

//--- 全局变量
double point;
int digits;
double step_points;
double tp_points;
bool is_buy_grid = false;
bool is_sell_grid = false;
int buy_trades = 0;
int sell_trades = 0;
double last_buy_price = 0;
double last_sell_price = 0;
double initial_equity;

//+------------------------------------------------------------------+
//| 初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
point = Point;
if(Digits == 3 || Digits == 5)
point = Point * 10;

step_points = StepPips * point;
tp_points = TakeProfitPips * point;
initial_equity = AccountEquity();

Print("马丁格尔EA已启动");
Print("加仓间隔:", StepPips, " 点");
Print("止盈目标:", TakeProfitPips, " 点");
Print("最大层数:", MaxTrades);

return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Print("马丁格尔EA已移除,原因:", reason);
}

//+------------------------------------------------------------------+
//| Tick主函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 净值保护检查
double current_equity = AccountEquity();
double equity_drawdown_pct = (initial_equity - current_equity) / initial_equity * 100;

if(equity_drawdown_pct > MaxEquityDrawdown)
{
Print("达到最大净值回撤(", equity_drawdown_pct, "%),全部平仓。");
CloseAllTrades();
return;
}

//--- 统计当前网格持仓
CountGridTrades();

//--- 检查止盈
CheckTakeProfit();

//--- 开首单
if(!is_buy_grid && buy_trades == 0 && (TradeBuyOnly || (!TradeSellOnly && GetTradeDirection() == 1)))
{
OpenBuyTrade();
}

if(!is_sell_grid && sell_trades == 0 && (TradeSellOnly || (!TradeBuyOnly && GetTradeDirection() == -1)))
{
OpenSellTrade();
}

//--- 价格反向移动时加仓
if(is_buy_grid && buy_trades > 0 && buy_trades < MaxTrades)
{
double current_bid = Bid;
double next_step_price = last_buy_price - step_points;
if(current_bid <= next_step_price)
{
OpenBuyTrade();
}
}

if(is_sell_grid && sell_trades > 0 && sell_trades < MaxTrades)
{
double current_ask = Ask;
double next_step_price = last_sell_price + step_points;
if(current_ask >= next_step_price)
{
OpenSellTrade();
}
}
}

//+------------------------------------------------------------------+
//| 统计网格持仓数量 |
//+------------------------------------------------------------------+
void CountGridTrades()
{
buy_trades = 0;
sell_trades = 0;
is_buy_grid = false;
is_sell_grid = false;
last_buy_price = 0;
last_sell_price = 0;

for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
if(OrderType() == OP_BUY)
{
buy_trades++;
if(OrderOpenPrice() > last_buy_price)
last_buy_price = OrderOpenPrice();
is_buy_grid = true;
}
else if(OrderType() == OP_SELL)
{
sell_trades++;
if(last_sell_price == 0 || OrderOpenPrice() < last_sell_price)
last_sell_price = OrderOpenPrice();
is_sell_grid = true;
}
}
}
}
}

//+------------------------------------------------------------------+
//| 开多单(网格加仓) |
//+------------------------------------------------------------------+
void OpenBuyTrade()
{
double lot = LotSize * MathPow(LotMultiplier, buy_trades);

if(lot > 50) lot = 50; // 安全上限
if(lot < LotSize) lot = LotSize;

lot = NormalizeDouble(lot, 2);

int ticket = OrderSend(Symbol(), OP_BUY, lot, Ask, Slippage, 0, 0, "马丁格尔多单", MagicNumber, 0, clrGreen);

if(ticket > 0)
{
Print("开多单成功 #", ticket, " 手数:", lot);
last_buy_price = Ask;
}
else
{
Print("开多单失败,错误码:", GetLastError());
}
}

//+------------------------------------------------------------------+
//| 开空单(网格加仓) |
//+------------------------------------------------------------------+
void OpenSellTrade()
{
double lot = LotSize * MathPow(LotMultiplier, sell_trades);

if(lot > 50) lot = 50;
if(lot < LotSize) lot = LotSize;

lot = NormalizeDouble(lot, 2);

int ticket = OrderSend(Symbol(), OP_SELL, lot, Bid, Slippage, 0, 0, "马丁格尔空单", MagicNumber, 0, clrRed);

if(ticket > 0)
{
Print("开空单成功 #", ticket, " 手数:", lot);
last_sell_price = Bid;
}
else
{
Print("开空单失败,错误码:", GetLastError());
}
}

//+------------------------------------------------------------------+
//| 检查止盈 – 总盈利达标时全部平仓 |
//+------------------------------------------------------------------+
void CheckTakeProfit()
{
double total_profit_pips = 0;

if(is_buy_grid && buy_trades > 0)
{
double total_price = 0;
double total_lots = 0;

for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == OP_BUY)
{
total_price += OrderOpenPrice() * OrderLots();
total_lots += OrderLots();
}
}
}

if(total_lots > 0)
{
double avg_price = total_price / total_lots;
total_profit_pips = (Bid - avg_price) / point;
}
}
else if(is_sell_grid && sell_trades > 0)
{
double total_price = 0;
double total_lots = 0;

for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() == OP_SELL)
{
total_price += OrderOpenPrice() * OrderLots();
total_lots += OrderLots();
}
}
}

if(total_lots > 0)
{
double avg_price = total_price / total_lots;
total_profit_pips = (avg_price - Ask) / point;
}
}

if(total_profit_pips >= TakeProfitPips)
{
Print("达到止盈目标(", total_profit_pips, " 点),全部平仓。");
CloseAllTrades();
}
}

//+------------------------------------------------------------------+
//| 全部平仓 |
//+------------------------------------------------------------------+
void CloseAllTrades()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
bool closed = false;
if(OrderType() == OP_BUY)
{
closed = OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, clrWhite);
}
else if(OrderType() == OP_SELL)
{
closed = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, clrWhite);
}

if(closed)
Print("已平仓订单 #", OrderTicket());
else
Print("平仓失败 #", OrderTicket(), ",错误码:", GetLastError());
}
}
}

is_buy_grid = false;
is_sell_grid = false;
buy_trades = 0;
sell_trades = 0;
}

//+------------------------------------------------------------------+
//| 获取交易方向(均线过滤) |
//+------------------------------------------------------------------+
int GetTradeDirection()
{
if(UseMAFilter)
{
double ma_current = iMA(Symbol(), 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE, 0);
double ma_previous = iMA(Symbol(), 0, MAPeriod, 0, MODE_SMA, PRICE_CLOSE, 1);

if(ma_current > ma_previous)
return 1; // 做多
else if(ma_current < ma_previous)
return -1; // 做空
}

return 1;
}
//+------------------------------------------------------------------+
```

安装步骤



第1步: 复制上方完整代码
第2步: 打开MT4 → 文件 → 打开数据文件夹 → MQL4 → Experts
第3步: 新建文件 `Martingale_Grid_EA.mq4`
第4步: 粘贴代码,按F7编译
第5步: 编译成功后附加到图表,开启自动交易

参数详解



| 参数 | 默认值 | 说明 |
| :--- | :--- | :--- |
| `LotSize` | 0.01 | 首单基础手数 |
| `LotMultiplier` | 2.0 | 每层加仓的手数倍数 |
| `StepPips` | 20 | 每层网格之间的点数间隔 |
| `MaxTrades` | 5 | 最大加仓层数(安全限制) |
| `TakeProfitPips` | 20 | 总盈利达到此点数后全部平仓 |
| `MaxEquityDrawdown` | 30.0 | 净值回撤超限时紧急全部平仓 |
| `UseMAFilter` | false | 启用均线方向过滤 |
| `TradeBuyOnly` | false | 只做多网格 |
| `TradeSellOnly` | false | 只做空网格 |

风险评估矩阵



| 最大层数 | 手数倍数 | 最坏情况总手数(0.01基础) |
| :--- | :--- | :--- |
| 3 | 2.0 | 0.01 + 0.02 + 0.04 = 0.07手 |
| 5 | 2.0 | 0.01 + 0.02 + 0.04 + 0.08 + 0.16 = 0.31手 |
| 5 | 1.5 | 0.01 + 0.015 + 0.0225 + 0.0338 + 0.0507 = 0.132手 |
| 8 | 2.0 | 快速超过2.5手 – 极其危险 |

强烈建议: 仅在模拟盘使用 `MaxTrades=3` 和 `LotMultiplier=1.5` 起步。

安全使用规则



| 规则 | 说明 |
| :--- | :--- |
| 仅限模拟盘 | 至少模拟运行3个月 |
| 设MaxTrades=3 | 限制网格深度 |
| 小基础手数 | 每1万美元账户用0.01手 |
| 开启净值保护 | 设20-30%回撤限制 |
| 避开新闻时段 | 高波动可能导致间隔跳穿 |
| 仅用于震荡市 | 单边趋势中马丁格尔必死 |

适用市场环境



| 市场状态 | 表现 | 原因 |
| :--- | :--- | :--- |
| 震荡/盘整 | 良好 | 价格来回波动,网格双向获利 |
| 弱趋势(有回调) | 可接受 | 回调时网格平仓 |
| 强单边趋势 | 危险 | 网格持续加仓,无回调平仓机会 |

编译问题排查



| 问题 | 解决方法 |
| :--- | :--- |
| OrderSend错误4109 | 开启自动交易按钮,或检查经纪商权限 |
| 不开单 | 检查UseMAFilter设置或是否在交易时段内 |
| 编译报错 | 确认文件保存在Experts文件夹,扩展名为.mq4 |

---

想要带波动率过滤和时间过滤的专业网格EA? [订阅我们的资讯] 获取包含动态间隔调整的高级EA库。

参考来源:
  • MQL4官方文档 – OrderSend、OrderModify (docs.mql4.com)

  • 自主编译测试于MT4 Build 1420+

  • ```