本文分享一个完整的移动平均线交叉EA(智能交易系统) 源码,适用于MetaTrader 4平台。当快线向上穿越慢线时产生买入信号,向下穿越时产生卖出信号。代码结构清晰,非常适合学习EA编程基础,可在MetaEditor中直接编译运行。
核心功能:
完整MQL4源码:
```cpp
//+------------------------------------------------------------------+
//| MACrossoverEA.mq4 |
//| Copyright 2025, AutoTrader |
//| https://www.example.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, AutoTrader"
#property link "https://www.example.com"
#property version "1.00"
#property strict
//--- 输入参数
input double LotSize = 0.1; // 固定交易手数
input bool UseRiskPercent = false; // 启用风险百分比模式
input double RiskPercent = 2.0; // 每笔风险占账户余额百分比
input int FastMAPeriod = 5; // 快均线周期
input int SlowMAPeriod = 20; // 慢均线周期
input int MAMethod = MODE_SMA; // 均线类型: 0=SMA,1=EMA,2=SMMA,3=LWMA
input int MAPrice = PRICE_CLOSE; // 应用价格
input int MagicNumber = 12345; // EA识别码
input int Slippage = 3; // 滑点(点数)
input int StopLoss = 300; // 止损点数(0=禁用)
input int TakeProfit = 600; // 止盈点数(0=禁用)
input int TrailingStop = 200; // 移动止损点数(0=禁用)
//--- 全局变量
double fastMA, slowMA;
int ticket;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(FastMAPeriod >= SlowMAPeriod)
{
Print("错误: 快均线周期必须小于慢均线周期");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA退出函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| EA核心报价处理函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 计算当前和上一根K线的均线值
fastMA = iMA(Symbol(), PERIOD_CURRENT, FastMAPeriod, 0, MAMethod, MAPrice, 1);
slowMA = iMA(Symbol(), PERIOD_CURRENT, SlowMAPeriod, 0, MAMethod, MAPrice, 1);
double fastMA_prev = iMA(Symbol(), PERIOD_CURRENT, FastMAPeriod, 0, MAMethod, MAPrice, 2);
double slowMA_prev = iMA(Symbol(), PERIOD_CURRENT, SlowMAPeriod, 0, MAMethod, MAPrice, 2);
// 检查是否已有持仓
if(CountPositions() == 0)
{
// 买入信号: 快线上穿慢线
if(fastMA_prev <= slowMA_prev && fastMA > slowMA)
{
double lot = CalculateLotSize();
ticket = OrderSend(Symbol(), OP_BUY, lot, Ask, Slippage,
StopLoss>0 ? Ask - StopLoss*Point : 0,
TakeProfit>0 ? Ask + TakeProfit*Point : 0,
"MA Cross Buy", MagicNumber, 0, clrGreen);
if(ticket < 0) Print("买入订单失败: ", GetLastError());
}
// 卖出信号: 快线下穿慢线
else if(fastMA_prev >= slowMA_prev && fastMA < slowMA)
{
double lot = CalculateLotSize();
ticket = OrderSend(Symbol(), OP_SELL, lot, Bid, Slippage,
StopLoss>0 ? Bid + StopLoss*Point : 0,
TakeProfit>0 ? Bid - TakeProfit*Point : 0,
"MA Cross Sell", MagicNumber, 0, clrRed);
if(ticket < 0) Print("卖出订单失败: ", GetLastError());
}
}
else
{
// 移动止损管理
if(TrailingStop > 0) TrailingStopLoss();
}
}
//+------------------------------------------------------------------+
//| 统计当前图表上相同MagicNumber的持仓数量 |
//+------------------------------------------------------------------+
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;
}
//+------------------------------------------------------------------+
//| 根据风险百分比计算交易手数 |
//+------------------------------------------------------------------+
double CalculateLotSize()
{
if(!UseRiskPercent) return LotSize;
double balance = AccountBalance();
double riskMoney = balance * RiskPercent / 100.0;
double tickValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double stopPoints = StopLoss;
if(stopPoints <= 0) return LotSize;
double lot = riskMoney / (stopPoints * tickValue);
lot = NormalizeDouble(lot, 2);
double minLot = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot = MarketInfo(Symbol(), MODE_MAXLOT);
if(lot < minLot) lot = minLot;
if(lot > maxLot) lot = maxLot;
return lot;
}
//+------------------------------------------------------------------+
//| 移动止损功能 |
//+------------------------------------------------------------------+
void TrailingStopLoss()
{
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)
{
double newSL = Bid - TrailingStop * Point;
if(OrderStopLoss() < newSL - Point)
if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrBlue))
Print("移动止损修改失败: ", GetLastError());
}
else if(OrderType() == OP_SELL)
{
double newSL = Ask + TrailingStop * Point;
if(OrderStopLoss() > newSL + Point || OrderStopLoss() == 0)
if(!OrderModify(OrderTicket(), OrderOpenPrice(), newSL, OrderTakeProfit(), 0, clrBlue))
Print("移动止损修改失败: ", GetLastError());
}
}
}
}
}
//+------------------------------------------------------------------+
```
使用步骤:
1. 将源码复制到MetaEditor中(MT4:工具 → MetaQuotes语言编辑器)。
2. 保存文件名为 `MACrossoverEA.mq4`。
3. 按F7编译,如有错误请根据提示修正。
4. 在MT4导航器的“智能交易系统”中,将EA拖拽到图表上。
5. 根据个人风险偏好调整输入参数。
参数详解:
重要提示:
参考来源: *由ForexEA Studio自主编译,2025年。核心逻辑基于经典移动平均线交叉策略。*
想要获取更多高级EA策略、专业指标和自动化交易工具,欢迎查看我们的付费EA精选合集 – 每月更新,提供已验证的源码和技术支持。点击侧边栏“订阅”按钮,即可获取最新资源。