📅 财经日历 📊 实时波动 📈 大盘云图 📶 行情走势 🆚 投机情绪 🚀 今日热点

    5分钟动量交易系统EA有错误,能帮忙分析下吗?

    2026-03-25 · 172 阅读
    5分钟动量交易系统EA有错误,能帮忙分析下吗?
    ""
    还没有人打赏,支持一下
    回复

    举报

     

    回答|共 3 个

    队长别开枪 LV5

    发表于 2026-3-25 16:48:08 | 显示全部楼层

    正常的啊,回测可以正常下单

    心想事成63116 LV0

    发表于 2026-3-25 17:36:53 | 显示全部楼层

    //+------------------------------------------------------------------+
    //|                                               五分钟动量交易系统.mq4|
    //|                               修正版:修复逻辑与风控缺陷           |
    //+------------------------------------------------------------------+

    #property strict

    // 输入参数
    input int      MAPeriod = 20;          // 指数均线周期(修正为int)
    input double   StopLossSpred = 20.0;   // 初始止损离均线的点数(标准点)
    input double   CloseSpred = 15.0;      // 后半仓止损离均线的点数(标准点)
    input double   Lots = 0.2;             // 总持仓手数(必须为偶数)
    input int      MagicNumber = 197658;   // 订单识别码(允许自定义,避免多实例冲突)

    // 全局变量:用于跟踪半仓后是否已修改止损至开仓价
    bool HalfClosed = false;

    //+------------------------------------------------------------------+
    //| 专家初始化函数                                                   |
    //+------------------------------------------------------------------+
    int OnInit()
    {
       // 检查手数是否为偶数(原要求)
       if (MathMod(Lots, 0.2) != 0)
       {
          Print("错误:手数必须为0.2的整数倍!");
          return(INIT_PARAMETERS_INCORRECT);
       }
       return(INIT_SUCCEEDED);
    }

    //+------------------------------------------------------------------+
    //| 专家主函数                                                       |
    //+------------------------------------------------------------------+
    void OnTick()
    {
       double MacdCurrent, MacdPrevious, Ma;
       int total;

       if (Bars < 100)
       {
          Print("K线少于100根!");
          return;
       }

       // 计算指标
       MacdCurrent = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 1);
       MacdPrevious = iMACD(NULL, 0, 12, 26, 9, PRICE_CLOSE, MODE_MAIN, 2);
       Ma = iMA(NULL, 0, MAPeriod, 0, MODE_EMA, PRICE_CLOSE, 0);

       // 获取点数值(适应5位/3位报价)
       double point = Point;
       if (Digits == 3 || Digits == 5)
          point = Point * 10;   // 将输入点数转换为实际点数

       total = OrdersTotal();

       // ================== 开仓逻辑 ==================
       if (total < 1) // 无持仓时才开仓
       {
          // 动态检查保证金
          double marginReq = MarketInfo(Symbol(), MODE_MARGINREQUIRED);
          if (AccountFreeMargin() < marginReq * Lots)
          {
             Print("资金不足: ", AccountFreeMargin());
             return;
          }

          // 开多单条件:MACD首红且汇价位于均线上20点内
          if (MacdCurrent > 0 && MacdPrevious < 0 &&
              Ask > Ma && Ask <= Ma + 20 * point)
          {
             double sl = Ma - StopLossSpred * point;
             int ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, sl, 0,
                                    "lbs-buy", MagicNumber, 0, clrRed);
             if (ticket > 0)
             {
                Print("开多单成功,价格:", Ask, " 止损:", sl);
                HalfClosed = false; // 重置半仓标志
             }
             else
                Print("开多单错误:", GetLastError());
             return;
          }

          // 开空单条件:MACD首绿且汇价位于均线下20点内
          if (MacdCurrent < 0 && MacdPrevious > 0 &&
              Bid < Ma && Bid >= Ma - 20 * point)
          {
             double sl = Ma + StopLossSpred * point;
             int ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, sl, 0,
                                    "lbs-sell", MagicNumber, 0, clrGreen);
             if (ticket > 0)
             {
                Print("开空单成功,价格:", Bid, " 止损:", sl);
                HalfClosed = false;
             }
             else
                Print("开空单错误:", GetLastError());
             return;
          }
          return;
       }

       // ================== 持仓管理 ==================
       for (int cnt = 0; cnt < total; cnt++)
       {
          if (!OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES))
             continue;
          if (OrderSymbol() != Symbol() || OrderMagicNumber() != MagicNumber)
             continue;

          int type = OrderType();
          if (type > OP_SELL) continue; // 仅处理多空订单

          double openPrice = OrderOpenPrice();
          double currentStop = OrderStopLoss();
          double currentLots = OrderLots();
          double profitDist = (type == OP_BUY) ? (Ask - openPrice) : (openPrice - Bid);
          double initialStopDist = (type == OP_BUY) ? (openPrice - currentStop) : (currentStop - openPrice);
          double halfLots = Lots / 2;

          // ---------- 多单管理 ----------
          if (type == OP_BUY)
          {
             // 1. 减仓检查:盈利达到初始止损距离(且尚未减仓)
             if (currentLots == Lots && profitDist >= initialStopDist && initialStopDist > 0)
             {
                // 平掉一半仓位
                if (OrderClose(OrderTicket(), halfLots, Bid, 3, clrViolet))
                {
                   Print("多单减仓成功,平仓价:", Bid);
                   // 立即将剩余半仓止损移至开仓价(盈亏平衡)
                   if (OrderSelect(OrderTicket(), SELECT_BY_TICKET, MODE_TRADES) && OrderLots() == halfLots)
                   {
                      if (OrderModify(OrderTicket(), openPrice, openPrice, OrderTakeProfit(), 0, clrRed))
                         Print("多单剩余半仓止损移至开仓价成功");
                      else
                         Print("多单止损修改失败:", GetLastError());
                      HalfClosed = true; // 标记已减仓且止损移至开仓价
                   }
                }
                else
                   Print("多单减仓失败:", GetLastError());
                return;
             }

             // 2. 移动止损至均线下CloseSpred点(仅在已减仓且止损仍在开仓价时触发)
             if (HalfClosed && currentLots == halfLots && currentStop == openPrice)
             {
                double newStop = Ma - CloseSpred * point;
                if (newStop > currentStop) // 只允许上移止损
                {
                   if (OrderModify(OrderTicket(), openPrice, newStop, OrderTakeProfit(), 0, clrRed))
                      Print("多单止损移至均线下 ", CloseSpred, " 点,新止损:", newStop);
                   else
                      Print("多单移动止损失败:", GetLastError());
                   return;
                }
             }
          }

          // ---------- 空单管理 ----------
          else if (type == OP_SELL)
          {
             // 1. 减仓检查:盈利达到初始止损距离(且尚未减仓)
             if (currentLots == Lots && profitDist >= initialStopDist && initialStopDist > 0)
             {
                if (OrderClose(OrderTicket(), halfLots, Ask, 3, clrViolet))
                {
                   Print("空单减仓成功,平仓价:", Ask);
                   if (OrderSelect(OrderTicket(), SELECT_BY_TICKET, MODE_TRADES) && OrderLots() == halfLots)
                   {
                      if (OrderModify(OrderTicket(), openPrice, openPrice, OrderTakeProfit(), 0, clrGreen))
                         Print("空单剩余半仓止损移至开仓价成功");
                      else
                         Print("空单止损修改失败:", GetLastError());
                      HalfClosed = true;
                   }
                }
                else
                   Print("空单减仓失败:", GetLastError());
                return;
             }

             // 2. 移动止损至均线上CloseSpred点(仅在已减仓且止损仍在开仓价时触发)
             if (HalfClosed && currentLots == halfLots && currentStop == openPrice)
             {
                double newStop = Ma + CloseSpred * point;
                if (newStop < currentStop) // 只允许下移止损
                {
                   if (OrderModify(OrderTicket(), openPrice, newStop, OrderTakeProfit(), 0, clrGreen))
                      Print("空单止损移至均线上 ", CloseSpred, " 点,新止损:", newStop);
                   else
                      Print("空单移动止损失败:", GetLastError());
                   return;
                }
             }
          }
       }
    }
    //+------------------------------------------------------------------+你试试看 这是我训练了半年的模型AI写的

    GGGcsjdj LV3

    发表于 2026-3-26 08:55:06 | 显示全部楼层

    extern int    _MagicNumber = 1123;
    extern double MAPeriod=26; //指数均线周期
    extern double StopLossSpred = 100; //初始止损离均线的点数
    extern double CloseSpred = 150; //后半仓止损离均线的点数
    extern double Lots=0.02; //持仓,必须为偶数


    //+------------------------------------------------------------------+
    //|                                                                  |
    //+------------------------------------------------------------------+
    int start()
      {
       double MacdCurrent, MacdPrevious, Ma;
       int cnt, ticket, total;

       if(Bars<100)
         {
          Print("K线少于100根!");
          return(0);  
         }

       MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1);
       MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,2);
       Ma=iMA(NULL,0,MAPeriod,0,MODE_EMA,PRICE_CLOSE,0);
       
       total=OrdersTotal();
       
       //开单检查
       if(total<1) //持仓单数小于1才开单
         {
          // 检查资金
          if(AccountFreeMargin()<(1000*Lots))//资金大于才开单
            {
             Print("资金不足: ", AccountFreeMargin());
             return(0);  
            }
          // 检查开多单的可能性
          if(MacdCurrent>0 && MacdPrevious<0 && Ask>Ma && Ask<=Ma+200*Point)  //MACD首红且汇价位于均线上20点内做多
            {
             ticket=OrderSend(Symbol(),OP_BUYSTOP,Lots,Ma+100*Point,3,Ma-StopLossSpred*Point,0,"lbs-buy", _MagicNumber,TimeCurrent()+Period()*1440,Red);
             if(ticket>0)
               {
                if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("开多单成功 : ",OrderOpenPrice());
               }
             else Print("开多单发生错误 : ",GetLastError());
             return(0);
            }
          // 检查开空单的可能性
          if(MacdCurrent<0 && MacdPrevious>0 && Bid<Ma && Bid>=Ma-200*Point) //MACD首绿且汇价位于均线下20点内做空
            {
             ticket=OrderSend(Symbol(),OP_SELLSTOP,Lots,Ma-100*Point,3,Ma+StopLossSpred*Point,0,"lbs-sell", _MagicNumber,TimeCurrent()+Period()*1440,Green);
             if(ticket>0)
               {
                if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("开空单成功 : ",OrderOpenPrice());
               }
             else Print("开空单发生错误 : ",GetLastError());
             return(0);
            }
          return(0);
         }
         
       //减仓及平仓检查   
       for(cnt=0;cnt<total;cnt++)
         {
          OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
          if ( OrderMagicNumber() != _MagicNumber ) continue;
          if(OrderType()<=OP_SELL && OrderSymbol()==Symbol())  // check for symbol
            {
             if(OrderType()==OP_BUY)   // 如果有做多单存在
               {
                
                //多单减仓检查
                if(Ask-OrderOpenPrice()>=OrderOpenPrice()-OrderStopLoss() && OrderOpenPrice()>OrderStopLoss() && OrderLots()==Lots)
                  {
                    ticket=OrderClose(OrderTicket(),Lots/2,Bid,3,Violet); // 平掉一半仓位
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("多单减仓成功 : ",OrderOpenPrice());
                      }
                    else Print("多单减仓发生错误 : ",GetLastError());
                    return(0);
                  }
                
                //修改后半仓位的止损价到盈亏平衡点
                if(Ask-OrderOpenPrice()>OrderOpenPrice()-OrderStopLoss() && OrderOpenPrice()>OrderStopLoss() && OrderLots()==Lots/2)
                  {
                    ticket=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Red);
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("多单盈亏平衡点修改成功 : ",OrderOpenPrice());
                      }
                    else Print("多单盈亏平衡点修改发生错误 : ",GetLastError());
                    return(0);
                  }
                
                //根据行情发展修改剩余仓位的止损价到均线下15点
                if(Ma-CloseSpred*Point>OrderStopLoss() && OrderOpenPrice()<=OrderStopLoss() && OrderLots()==Lots/2)
                  {
                    ticket=OrderModify(OrderTicket(),OrderOpenPrice(),Ma-CloseSpred*Point,OrderTakeProfit(),0,Red);
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("多单止损修改成功 : ",OrderOpenPrice());
                      }
                    else Print("多单止损修改发生错误 : ",GetLastError());
                    return(0);
                  }  
              }
             else // 如果有做空单存在
               {
                //空单减仓检查
                if(OrderOpenPrice()-Bid>OrderStopLoss()-OrderOpenPrice() && OrderOpenPrice()<OrderStopLoss() && OrderLots()==Lots)
                  {
                    ticket=OrderClose(OrderTicket(),Lots/2,Ask,3,Violet); // 平掉一半仓位
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("空单减仓成功 : ",OrderOpenPrice());
                      }
                    else Print("空单减仓发生错误 : ",GetLastError());
                    return(0);
                  }
                
                //修改后半仓位的止损价到盈亏平衡点
                if(OrderOpenPrice()-Bid>OrderStopLoss()-OrderOpenPrice() && OrderOpenPrice()<OrderStopLoss() && OrderLots()==Lots/2)
                  {
                    ticket=OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("空单盈亏平衡点修改成功 : ",OrderOpenPrice());
                      }
                    else Print("空单盈亏平衡点修改发生错误 : ",GetLastError());
                    return(0);
                  }
                
                //根据行情发展修改剩余仓位的止损价到均线下15点
                if(Ma+CloseSpred*Point<OrderStopLoss() && OrderOpenPrice()>=OrderStopLoss() && OrderLots()==Lots/2)
                  {
                    ticket=OrderModify(OrderTicket(),OrderOpenPrice(),Ma+CloseSpred*Point,OrderTakeProfit(),0,Green);
                    if(ticket>0)
                      {
                        if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("空单止损修改成功 : ",OrderOpenPrice());
                      }
                    else Print("空单止损修改发生错误 : ",GetLastError());
                    return(0);
                  }
               }
            }
         }

       return(0);
      }用这个,
    您需要登录后才可以回帖 登录 | 注册

    提醒: 禁止引战、谩骂、灌水内容

    微信二维码

    有问题联系客服