本文提供一套完整的、可直接编译运行的MQL4专家顾问源码,基于多周期移动平均线交叉策略构建。均线交叉是外汇交易中最经典且广泛使用的趋势跟踪策略之一。本EA在传统双均线交叉的基础上,增加了更高时间周期的趋势过滤功能,能够有效减少震荡行情中的虚假信号,提高交易胜率。
该EA的核心运作机制为:在当前图表时间周期上计算两条均线(快线和慢线),并可选地通过更高时间周期的第三条均线来确认大趋势方向。当快线自下而上穿越慢线,且高周期趋势为多头时,触发买入信号;反之,当快线自上而下穿越慢线,且高周期趋势为空头时,触发卖出信号。这种多周期融合确认机制大幅提升了策略的鲁棒性,使其能够适应不同市场环境。
核心功能亮点:
以下是该EA的完整源码。请将代码复制到MetaEditor中,编译后挂载到图表即可使用。注意本EA不使用DLL,运行安全稳定。
```mql4
//+------------------------------------------------------------------+
//| MA_Crossover_MTF_EA.mq4 |
//| Copyright 2025, ForexSourceLab |
//| https://www.example.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2025, ForexSourceLab"
#property link "https://www.example.com"
#property version "1.00"
#property strict
//+------------------------------------------------------------------+
//| 输入参数 |
//+------------------------------------------------------------------+
input int FastMAPeriod = 10; // 快速均线周期
input int SlowMAPeriod = 30; // 慢速均线周期
input int SignalMAPeriod = 50; // 信号均线周期(高周期过滤用)
input int MA_Shift = 0; // 均线偏移
input int MA_Method = MODE_SMA; // 均线方法 (0=SMA,1=EMA,2=SMMA,3=LWMA)
input int AppliedPrice = PRICE_CLOSE; // 应用价格
input bool UseHigherTF = true; // 启用高周期趋势过滤
input ENUM_TIMEFRAMES HigherTF = PERIOD_H1; // 高时间周期
input double LotSize = 0.1; // 固定交易手数
input bool UseRiskManagement = false; // 启用风险比例资金管理
input double RiskPercent = 2.0; // 每笔交易风险比例(%)
input int StopLoss = 60; // 止损点数
input int TakeProfit = 120; // 止盈点数
input int BreakevenTrigger = 30; // 保本激活点数
input int BreakevenPips = 5; // 保本偏移点数
input int MagicNumber = 202507; // EA魔术编号
input bool AllowBuy = true; // 允许买入
input bool AllowSell = true; // 允许卖出
input int MaxOrders = 1; // 最大同时持仓数
//+------------------------------------------------------------------+
//| 全局变量 |
//+------------------------------------------------------------------+
datetime lastBarTime = 0;
//+------------------------------------------------------------------+
//| EA初始化函数 |
//+------------------------------------------------------------------+
int OnInit()
{
if(FastMAPeriod <= 0 || SlowMAPeriod <= 0 || FastMAPeriod >= SlowMAPeriod)
return(INIT_PARAMETERS_INCORRECT);
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| EA反初始化函数 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
Comment("");
}
//+------------------------------------------------------------------+
//| EA核心Tick函数 |
//+------------------------------------------------------------------+
void OnTick()
{
//--- 检查新K线,避免同一K线重复触发
if(Time[0] == lastBarTime) return;
lastBarTime = Time[0];
//--- 统计当前EA已开订单数量
int totalOrders = CountTotalOrders(MagicNumber);
if(totalOrders >= MaxOrders) return;
//--- 计算当前图表周期的两条均线值
double fastMA_0 = iMA(NULL, 0, FastMAPeriod, MA_Shift, MA_Method, AppliedPrice, 0);
double fastMA_1 = iMA(NULL, 0, FastMAPeriod, MA_Shift, MA_Method, AppliedPrice, 1);
double slowMA_0 = iMA(NULL, 0, SlowMAPeriod, MA_Shift, MA_Method, AppliedPrice, 0);
double slowMA_1 = iMA(NULL, 0, SlowMAPeriod, MA_Shift, MA_Method, AppliedPrice, 1);
//--- 计算更高时间周期的信号均线趋势(如果启用)
bool higherTrendBull = true;
bool higherTrendBear = true;
if(UseHigherTF)
{
double signalMA_0 = iMA(NULL, HigherTF, SignalMAPeriod, MA_Shift, MA_Method, AppliedPrice, 0);
double signalMA_1 = iMA(NULL, HigherTF, SignalMAPeriod, MA_Shift, MA_Method, AppliedPrice, 1);
double signalMA_2 = iMA(NULL, HigherTF, SignalMAPeriod, MA_Shift, MA_Method, AppliedPrice, 2);
//--- 通过信号均线的斜率定义趋势方向
higherTrendBull = (signalMA_0 > signalMA_1 && signalMA_1 > signalMA_2);
higherTrendBear = (signalMA_0 < signalMA_1 && signalMA_1 < signalMA_2);
}
//--- 检测金叉(看涨交叉)
if(AllowBuy && higherTrendBull && fastMA_1 <= slowMA_1 && fastMA_0 > slowMA_0)
{
if(CountOrdersByType(MagicNumber, OP_BUY) == 0)
{
OpenOrder(OP_BUY);
}
}
//--- 检测死叉(看跌交叉)
if(AllowSell && higherTrendBear && fastMA_1 >= slowMA_1 && fastMA_0 < slowMA_0)
{
if(CountOrdersByType(MagicNumber, OP_SELL) == 0)
{
OpenOrder(OP_SELL);
}
}
//--- 订单管理(保本止损)
ManageOrders();
}
//+------------------------------------------------------------------+
//| 开仓函数 |
//+------------------------------------------------------------------+
void OpenOrder(int cmd)
{
double price = (cmd == OP_BUY) ? Ask : Bid;
double sl = 0, tp = 0;
//--- 如果启用风险资金管理,动态计算手数
double tradeLot = LotSize;
if(UseRiskManagement)
{
double riskAmount = AccountBalance() * RiskPercent / 100.0;
double pipValue = MarketInfo(Symbol(), MODE_TICKVALUE);
double riskPips = StopLoss;
tradeLot = riskAmount / (riskPips * pipValue * 10);
tradeLot = MathMax(tradeLot, MarketInfo(Symbol(), MODE_MINLOT));
tradeLot = MathMin(tradeLot, MarketInfo(Symbol(), MODE_MAXLOT));
tradeLot = NormalizeDouble(tradeLot, 2);
}
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, tradeLot, price, 5, sl, tp, "MA Crossover EA", MagicNumber, 0, clrNONE);
if(ticket < 0)
{
Print("OrderSend failed with error #", GetLastError());
}
}
//+------------------------------------------------------------------+
//| 统计总订单数量 |
//+------------------------------------------------------------------+
int CountTotalOrders(int magic)
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magic)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| 按类型统计订单数量 |
//+------------------------------------------------------------------+
int CountOrdersByType(int magic, int type)
{
int count = 0;
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == magic && OrderType() == type)
{
count++;
}
}
}
return count;
}
//+------------------------------------------------------------------+
//| 订单管理(保本止损) |
//+------------------------------------------------------------------+
void ManageOrders()
{
for(int i = OrdersTotal() - 1; i >= 0; i--)
{
if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
{
if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber)
{
double openPrice = OrderOpenPrice();
double currentSL = OrderStopLoss();
if(OrderType() == OP_BUY)
{
//--- 保本止损逻辑
if(BreakevenTrigger > 0 && currentSL < openPrice)
{
if(Bid - openPrice >= BreakevenTrigger * Point * 10)
{
double newSL = openPrice + BreakevenPips * Point * 10;
if(newSL > currentSL)
{
if(!OrderModify(OrderTicket(), openPrice, newSL, OrderTakeProfit(), 0, clrNONE))
Print("保本止损修改错误: ", GetLastError());
}
}
}
}
else if(OrderType() == OP_SELL)
{
//--- 保本止损逻辑
if(BreakevenTrigger > 0 && (currentSL > openPrice || currentSL == 0))
{
if(openPrice - Ask >= BreakevenTrigger * Point * 10)
{
double newSL = openPrice - BreakevenPips * Point * 10;
if(newSL < currentSL || currentSL == 0)
{
if(!OrderModify(OrderTicket(), openPrice, newSL, OrderTakeProfit(), 0, clrNONE))
Print("保本止损修改错误: ", GetLastError());
}
}
}
}
}
}
}
}
//+------------------------------------------------------------------+
```
详细使用说明:
1. 在MT4中按F4打开MetaEditor。
2. 新建专家顾问,将上述代码完整粘贴进去。
3. 按F7编译代码,确保没有任何错误提示。
4. 将EA拖拽到您选择的货币对图表上。
5. 在“输入参数”选项卡中根据个人交易策略调整各项参数。
6. 启用“允许实时交易”,并确保MT4工具栏上的自动交易按钮处于激活状态。
参数详细解读:
策略优化与扩展思路:
为了使本EA更好地适应不同的市场环境,您可以考虑以下增强方向:
本EA是一个极佳的学习和实战起点,能够帮助您深入理解MQL4编程中多周期数据调用、订单管理、资金管理和风险控制等核心模块。在实际投入实盘之前,请务必在模拟账户上进行充分的回测和前瞻测试,以验证策略的有效性并优化参数组合。
如果您希望获得更强大的交易工具,例如集成机器学习信号过滤、多币种组合管理、以及高级风险分散策略的付费版EA,欢迎关注我们的付费会员体系,我们将为您提供持续的策略升级和专业的技术支持,助您在交易之路上更进一步。
参考来源:自主编译,基于标准MQL4均线交叉逻辑与多周期趋势过滤技术。