# 移动平均线交叉EA - 完整MQL4源码
本文提供一个完整的MT4自动交易EA源码,基于两条移动平均线的交叉信号进行交易。当快线向上穿过慢线时开多单,向下穿过时开空单。
策略逻辑
EA默认使用简单移动平均线(SMA),所有参数均可调整,支持切换为指数移动平均线(EMA)。每笔交易可配置止损、止盈和移动止损功能。
完整MQL4代码
```mql4
//+------------------------------------------------------------------+
//| MACrossoverEA.mq4 |
//| 由AI助手自动生成编译 |
//| |
//+------------------------------------------------------------------+
#property copyright "AI助手"
#property link ""
#property version "1.00"
#property strict
input double LotSize = 0.1; // 手数大小
input int FastMAPeriod = 5; // 快线周期
input int SlowMAPeriod = 20; // 慢线周期
input int MAType = MODE_SMA; // MA类型: MODE_SMA, MODE_EMA
input int MAPrice = PRICE_CLOSE; // 价格类型: PRICE_CLOSE, PRICE_OPEN
input int StopLoss = 50; // 止损点数
input int TakeProfit = 100; // 止盈点数
input int TrailingStop = 30; // 移动止损点数(0=关闭)
input int MagicNumber = 202410; // EA魔术号
double fastMA_prev = 0, fastMA_curr = 0;
double slowMA_prev = 0, slowMA_curr = 0;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(SlowMAPeriod <= FastMAPeriod)
{
Print("错误: 慢线周期必须大于快线周期");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| EA报价处理函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 计算均线值
fastMA_curr = iMA(Symbol(), 0, FastMAPeriod, 0, MAType, MAPrice, 0);
fastMA_prev = iMA(Symbol(), 0, FastMAPeriod, 0, MAType, MAPrice, 1);
slowMA_curr = iMA(Symbol(), 0, SlowMAPeriod, 0, MAType, MAPrice, 0);
slowMA_prev = iMA(Symbol(), 0, SlowMAPeriod, 0, MAType, MAPrice, 1);
// 检查已有持仓
if(CountPositions() > 0)
{
TrailingStopManagement();
return;
}
// 交叉信号判断
if(fastMA_prev <= slowMA_prev && fastMA_curr > slowMA_curr)
{
CloseAllPositions();
OpenOrder(OP_BUY);
}
else if(fastMA_prev >= slowMA_prev && fastMA_curr < slowMA_curr)
{
CloseAllPositions();
OpenOrder(OP_SELL);
}
}
//+------------------------------------------------------------------+
//| 开仓函数 |
//+------------------------------------------------------------------+
void OpenOrder(int cmd)
{
double price = (cmd == OP_BUY) ? Ask : Bid;
double sl = 0, tp = 0;
if(StopLoss > 0)
sl = (cmd == OP_BUY) ? price - StopLoss * Point * 10 : price + StopLoss * Point * 10;
if(TakeProfit > 0)
tp = (cmd == OP_BUY) ? price + TakeProfit * Point * 10 : price - TakeProfit * Point * 10;
int ticket = OrderSend(Symbol(), cmd, LotSize, price, 3, sl, tp, "MA Crossover", MagicNumber, 0, clrNONE);
if(ticket < 0)
Print("开仓失败: ", GetLastError());
}
//+------------------------------------------------------------------+
//| 平仓所有持仓 |
//+------------------------------------------------------------------+
void CloseAllPositions()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
bool close = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 3, clrNONE);
if(!close)
Print("平仓失败: ", GetLastError());
}
}
}
}
//+------------------------------------------------------------------+
//| 统计持仓数量 |
//+------------------------------------------------------------------+
int CountPositions()
{
int count = 0;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
//| 移动止损管理 |
//+------------------------------------------------------------------+
void TrailingStopManagement()
{
if(TrailingStop == 0) return;
for(int i = 0; i < OrdersTotal(); i++)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double newSL = 0;
if(OrderType() == OP_BUY)
{
newSL = Bid - TrailingStop * Point * 10;
if(newSL > OrderStopLoss())
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
else if(OrderType() == OP_SELL)
{
newSL = Ask + TrailingStop * Point * 10;
if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrNONE);
}
}
}
}
}
//+------------------------------------------------------------------+
```
参数详解
| 参数 | 说明 |
|------|------|
| 手数大小 | 每笔交易的开仓手数 |
| 快线周期 | 快速均线周期(建议5-14) |
| 慢线周期 | 慢速均线周期(建议20-50) |
| MA类型 | MODE_SMA简单均线 / MODE_EMA指数均线 |
| 价格类型 | 收盘价、开盘价、最高价、最低价 |
| 止损点数 | 止损距离(点数) |
| 止盈点数 | 止盈距离(点数) |
| 移动止损 | 跟踪止损距离(设为0关闭) |
| 魔术号 | EA唯一标识码 |
安装与使用说明
1. 复制代码到MT4的MetaEditor(按F4打开)
2. 点击编译按钮(F7)- 确保无错误提示
3. 将EA附加到MT4图表上
4. 在输入参数选项卡中调整参数
5. 启用自动交易按钮(Alt+T)
编译修改技巧
参考来源
本文EA源码为自主编译,基于移动平均线交叉策略的标准算法交易原理编写。
*如需更多包含优化进场过滤器和资金管理的高级EA策略,欢迎查看我们的精选EA合集,附赠完整回测报告。*