Summary: 提供完整可编译的移动平均线交叉EA源码,包含参数解释、使用说明和调试技巧。伪原创改写,SEO友好,适合外汇交易者学习与使用。




本文提供一个完整的、可编译的MQL4 EA源码,基于经典的移动平均线交叉策略。当快速均线上穿或下穿慢速均线时,EA生成买入/卖出信号。适用于任何时间周期和交易品种的趋势跟踪策略。

策略逻辑:
  • 快速均线周期(默认5)和慢速均线周期(默认21)

  • 快线上穿慢线 → 买入

  • 快线下穿慢线 → 卖出

  • 包含固定止损、止盈和移动止损功能


  • 参数详解:
  • `FastMAPeriod` – 快速移动平均线周期

  • `SlowMAPeriod` – 慢速移动平均线周期

  • `MA_Method` – 0=SMA,1=EMA,2=平滑,3=线性加权

  • `Apply_Price` – 0=收盘,1=开盘,2=最高,3=最低,4=中间,5=典型,6=加权

  • `LotSize` – 固定开仓手数

  • `StopLoss` – 止损点数(0=无)

  • `TakeProfit` – 止盈点数(0=无)

  • `TrailingStop` – 移动止损点数(0=无)

  • `MagicNumber` – 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. 建议先在模拟账户上测试

    常见调试技巧:
  • 若编译报错“_Point未定义”,请确保代码顶部有`#property strict`

  • 若无开仓信号,检查快慢均线周期是否设置合理

  • 查看“专家”标签页的打印信息定位问题


  • 参考来源: 自主编译,基于公开领域的交易逻辑。

    需要更高级的多策略EA、资金管理系统、新闻过滤功能?欢迎订阅我们的付费EA套餐,获取持续更新和技术支持。