本文提供一个完整的、可编译的MQL4 EA源码,基于经典的移动平均线交叉策略。当快速均线上穿或下穿慢速均线时,EA生成买入/卖出信号。适用于任何时间周期和交易品种的趋势跟踪策略。
策略逻辑:
参数详解:
MQL4源码:
```mql4
//+------------------------------------------------------------------+
//| MovingAverageCrossoverEA.mq4 |
//| |
//| 自主编译 / Self-compiled |
//+------------------------------------------------------------------+
#property copyright "外汇交易工具"
#property link ""
#property version "1.00"
#property strict
//--- 输入参数
input int FastMAPeriod = 5;
input int SlowMAPeriod = 21;
input int MA_Method = 1; // 0=SMA,1=EMA,2=SMMA,3=LWMA
input int Apply_Price = 0; // 0=收盘,1=开盘,2=最高,3=最低,4=中间,5=典型,6=加权
input double LotSize = 0.1;
input int StopLoss = 50;
input int TakeProfit = 100;
input int TrailingStop = 30;
input int MagicNumber = 202410;
double fastMA, slowMA;
int ticket;
bool isTrailing = false;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(FastMAPeriod >= SlowMAPeriod)
{
Print("错误:快速均线周期必须小于慢速均线周期");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| EA核心tick函数 |
//+------------------------------------------------------------------+
void OnTick()
{
// 计算均线值
fastMA = iMA(_Symbol,0,FastMAPeriod,0,MA_Method,Apply_Price,1);
slowMA = iMA(_Symbol,0,SlowMAPeriod,0,MA_Method,Apply_Price,1);
double fastMA_prev = iMA(_Symbol,0,FastMAPeriod,0,MA_Method,Apply_Price,2);
double slowMA_prev = iMA(_Symbol,0,SlowMAPeriod,0,MA_Method,Apply_Price,2);
// 移动止损处理
if(TrailingStop > 0)
{
Trailing();
}
// 检查是否有持仓
if(CountOpenOrders() == 0)
{
// 买入信号
if(fastMA_prev <= slowMA_prev && fastMA > slowMA)
{
OpenOrder(OP_BUY);
}
// 卖出信号
else if(fastMA_prev >= slowMA_prev && fastMA < slowMA)
{
OpenOrder(OP_SELL);
}
}
}
//+------------------------------------------------------------------+
//| 开仓函数 |
//+------------------------------------------------------------------+
void OpenOrder(int cmd)
{
double price, sl, tp;
if(cmd == OP_BUY)
{
price = Ask;
if(StopLoss > 0) sl = price - StopLoss * _Point * 10;
if(TakeProfit > 0) tp = price + TakeProfit * _Point * 10;
}
else
{
price = Bid;
if(StopLoss > 0) sl = price + StopLoss * _Point * 10;
if(TakeProfit > 0) tp = price - TakeProfit * _Point * 10;
}
ticket = OrderSend(_Symbol,cmd,LotSize,price,3,sl,tp,"MA交叉EA",MagicNumber,0,clrNONE);
if(ticket < 0)
{
Print("开仓失败,错误码:",GetLastError());
}
}
//+------------------------------------------------------------------+
//| 统计当前EA的持仓数量 |
//+------------------------------------------------------------------+
int CountOpenOrders()
{
int count = 0;
for(int i=0; i
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol)
count++;
}
}
return count;
}
//+------------------------------------------------------------------+
//| 移动止损函数 |
//+------------------------------------------------------------------+
void Trailing()
{
for(int i=0; i
if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
{
if(OrderMagicNumber() == MagicNumber && OrderSymbol() == _Symbol)
{
if(OrderType() == OP_BUY)
{
double newSL = Bid - TrailingStop * _Point * 10;
if(newSL > OrderStopLoss())
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),newSL,OrderTakeProfit(),0,clrNONE))
Print("买单移动止损更新 #",OrderTicket());
}
}
else if(OrderType() == OP_SELL)
{
double newSL = Ask + TrailingStop * _Point * 10;
if(newSL < OrderStopLoss() || OrderStopLoss() == 0)
{
if(OrderModify(OrderTicket(),OrderOpenPrice(),newSL,OrderTakeProfit(),0,clrNONE))
Print("卖单移动止损更新 #",OrderTicket());
}
}
}
}
}
}
//+------------------------------------------------------------------+
```
编译与使用教程:
1. 将源码复制到MetaEditor中(MT4按F4打开)
2. 点击编译按钮(F7)——确保无错误
3. 将EA附加到图表,在输入参数选项卡中调整参数
4. 开启自动交易按钮(绿色)
5. 建议先在模拟账户上测试
常见调试技巧:
参考来源: 自主编译,基于公开领域的交易逻辑。
需要更高级的多策略EA、资金管理系统、新闻过滤功能?欢迎订阅我们的付费EA套餐,获取持续更新和技术支持。