Youthcxz 2025-07-15 10:13 采纳率: 0%
浏览 7

mql5 模拟测试能够平仓,实盘就不能平仓了

我写了一个交易黄金辅助的平仓修改止损的小EA,在测试的时候功能都正常,但是挂到实盘运行的时候,修改止损能够运行,但是部分平仓的功能无法实现,不能平仓。希望指点。
具体思路如下:1:检测如果有开仓订单且没有设定止损价格,那么立刻设置一个止损 2:当盈利到一定点数之后,平仓掉部分仓位(这步骤不能平仓) 3:盈利到一定点数的时候把订单止损价格修改到开仓价格。4:再盈利到一定点数后再平仓一部分订单。

void OnTick()
  {
   /* if(jy.danshu(货币,POSITION_TYPE_BUY,0)==0)
      {
        jy.buyplus(货币,0.05,0,0,IntegerToString(0),0);
      }
      
     if(jy.danshu(货币,POSITION_TYPE_SELL,0)==0)
      {
        jy.sellplus(货币,0.05,0,0,IntegerToString(0),0);
      }*/
     kaimodifysltp(货币,POSITION_TYPE_BUY,检测手数1,入场止损点数,0,0);
     kaimodifysltp(货币,POSITION_TYPE_SELL,检测手数1,入场止损点数,0,0);
     closeallbuylot(货币,检测手数1,平仓手数1,盈利点数1,0); 
     closeallselllot(货币,检测手数1,平仓手数1,盈利点数1,0); 
     modifysltp(货币,POSITION_TYPE_BUY,检测手数2,盈利点数2,0,0);
     modifysltp(货币,POSITION_TYPE_SELL,检测手数2,盈利点数2,0,0);
  }


void closeallbuylot(string symbol,double lot,double pinglot,double mm,int magic=0)
 {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
       if(PositionGetTicket(i)>0)
        {
          if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY && PositionGetDouble(POSITION_VOLUME)==lot 
          && sj.getbid(symbol)-PositionGetDouble(POSITION_PRICE_OPEN)>=mm)
           {
              if(magic==0)
               {
                  MqlTradeRequest request={1};
                  MqlTradeResult  result={0};
                  request.action   =TRADE_ACTION_DEAL;                     // 交易操作类型
                  request.symbol   =symbol;                              // 交易品种
                  request.volume   =pinglot; // 0.1手交易量 
                  request.type     =ORDER_TYPE_SELL;                        // 订单类型
                  request.price    =SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格
                  request.type_filling=ORDER_FILLING_IOC;
                  request.deviation=1000; // 允许价格偏差
                  request.position =PositionGetTicket(i);
                  if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误
               }
              else
               {
                  if(PositionGetInteger(POSITION_MAGIC)==magic)
                  {
                     MqlTradeRequest request={1};
                     MqlTradeResult  result={0};
                     request.action   =TRADE_ACTION_DEAL;                     // 交易操作类型
                     request.symbol   =symbol;                              // 交易品种
                     request.volume   =pinglot; // 0.1手交易量 
                     request.type     =ORDER_TYPE_SELL;                        // 订单类型
                     request.price    =SymbolInfoDouble(symbol,SYMBOL_BID); // 持仓价格
                     request.deviation=100; // 允许价格偏差
                     request.type_filling=ORDER_FILLING_IOC;
                     request.position =PositionGetTicket(i);
                     if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误
                  }
               }
             
           }
        }
     }
  
 }
 
void closeallselllot(string symbol,double lot,double pinglot,double mm,int magic=0)
 {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
       if(PositionGetTicket(i)>0)
        {
          if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL && PositionGetDouble(POSITION_VOLUME)==lot 
            && PositionGetDouble(POSITION_PRICE_OPEN)-sj.getask(symbol)>=mm)
           {
              if(magic==0)
               {
                 MqlTradeRequest request={1};
                 MqlTradeResult  result={0};
                  request.action   =TRADE_ACTION_DEAL;                     // 交易操作类型
                  request.symbol   =symbol;                              // 交易品种
                  request.volume   =pinglot; // 0.1手交易量 
                  request.type     =ORDER_TYPE_BUY;                        // 订单类型
                  request.price    =SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
                  request.deviation=1000; // 允许价格偏差
                  request.type_filling=ORDER_FILLING_IOC;
                  request.position =PositionGetTicket(i);
                  if(!OrderSend(request,result))
                  PrintFormat("OrderSend error %d",GetLastError());   // 如果不能发送请求,输出错误
               }
              else
               {
                  if(PositionGetInteger(POSITION_MAGIC)==magic)
                  {
                     MqlTradeRequest request={1};
                     MqlTradeResult  result={0};
                     request.action   =TRADE_ACTION_DEAL;                     // 交易操作类型
                     request.symbol   =symbol;                              // 交易品种
                     request.volume   =pinglot; // 0.1手交易量 
                     request.type     =ORDER_TYPE_BUY;                        // 订单类型
                     request.price    =SymbolInfoDouble(symbol,SYMBOL_ASK); // 持仓价格
                     request.deviation=100; // 允许价格偏差
                     request.type_filling=ORDER_FILLING_IOC;
                     request.position =PositionGetTicket(i);
                     if(!OrderSend(request,result))
                     PrintFormat("OrderSend error %d",GetLastError()); 
                  }
               }
           }
        }
     }
 }
 
 void modifysltp(string symbol,ENUM_POSITION_TYPE type,double lot,double sl,double tp,int magic=0)
 {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
       if(PositionGetTicket(i)>0)
        {
          if(PositionGetString(POSITION_SYMBOL)==symbol)
           {
             if(type==POSITION_TYPE_BUY && PositionGetDouble(POSITION_VOLUME)==lot && sj.getbid(symbol)-PositionGetDouble(POSITION_PRICE_OPEN)>=sl)
              {
                if(magic==0)
                 {
                     if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                     {
                       MqlTradeRequest request={1};
                       MqlTradeResult  result={0};
                       request.action=TRADE_ACTION_SLTP;
                       request.position=PositionGetTicket(i);
                       request.symbol=symbol;
                       request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(!OrderSend(request,result))
                       PrintFormat("OrderSend error %d",GetLastError()); 
                      }
                 }
                else
                 {
                    if(PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                        if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                         {
                          MqlTradeRequest request={1};
                          MqlTradeResult  result={0};
                          request.action=TRADE_ACTION_SLTP;
                          request.position=PositionGetTicket(i);
                          request.symbol=symbol;
                          request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(!OrderSend(request,result))
                          PrintFormat("OrderSend error %d",GetLastError()); 
                         }
                    }
                 }
              }
              if(type==POSITION_TYPE_SELL && PositionGetDouble(POSITION_VOLUME)==lot && PositionGetDouble(POSITION_PRICE_OPEN)-sj.getask(symbol)>=sl)
              {
                 if(magic==0)
                  {
                     if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                      {
                       MqlTradeRequest request={1};
                       MqlTradeResult  result={0};
                       request.action=TRADE_ACTION_SLTP;
                       request.position=PositionGetTicket(i);
                       request.symbol=symbol;
                       request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(!OrderSend(request,result))
                       PrintFormat("OrderSend error %d",GetLastError()); 
                      }
                 }
                else
                 {
                    if(PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                        if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                         {
                          MqlTradeRequest request={1};
                          MqlTradeResult  result={0};
                          request.action=TRADE_ACTION_SLTP;
                          request.position=PositionGetTicket(i);
                          request.symbol=symbol;
                          request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(!OrderSend(request,result))
                          PrintFormat("OrderSend error %d",GetLastError()); 
                         }
                    }
                 }
              }
           } 
        }
     }
 }


void kaimodifysltp(string symbol,ENUM_POSITION_TYPE type,double lot ,double sl,double tp,int magic=0)
 {
   int t=PositionsTotal();
   for(int i=t-1;i>=0;i--)
     {
       if(PositionGetTicket(i)>0)
        {
          if(PositionGetString(POSITION_SYMBOL)==symbol && PositionGetDouble(POSITION_VOLUME)==lot && PositionGetDouble(POSITION_SL)==0)
           {
             if(type==POSITION_TYPE_BUY)
              {
                if(magic==0)
                 {
                     if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                     {
                       MqlTradeRequest request={1};
                       MqlTradeResult  result={0};
                       request.action=TRADE_ACTION_SLTP;
                       request.position=PositionGetTicket(i);
                       request.symbol=symbol;
                       request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(!OrderSend(request,result))
                       PrintFormat("OrderSend error %d",GetLastError()); 
                      }
                 }
                else
                 {
                    if(PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                        if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                         {
                          MqlTradeRequest request={1};
                          MqlTradeResult  result={0};
                          request.action=TRADE_ACTION_SLTP;
                          request.position=PositionGetTicket(i);
                          request.symbol=symbol;
                          request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)-sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(!OrderSend(request,result))
                          PrintFormat("OrderSend error %d",GetLastError()); 
                         }
                    }
                 }
              }
              if(type==POSITION_TYPE_SELL)
              {
                 if(magic==0)
                  {
                     if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                      {
                       MqlTradeRequest request={1};
                       MqlTradeResult  result={0};
                       request.action=TRADE_ACTION_SLTP;
                       request.position=PositionGetTicket(i);
                       request.symbol=symbol;
                       request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                       if(!OrderSend(request,result))
                       PrintFormat("OrderSend error %d",GetLastError()); 
                      }
                 }
                else
                 {
                    if(PositionGetInteger(POSITION_MAGIC)==magic)
                    {
                        if((NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))||NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))!=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS))))
                         {
                          MqlTradeRequest request={1};
                          MqlTradeResult  result={0};
                          request.action=TRADE_ACTION_SLTP;
                          request.position=PositionGetTicket(i);
                          request.symbol=symbol;
                          request.sl=NormalizeDouble(PositionGetDouble(POSITION_PRICE_OPEN)+sl,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          request.tp=NormalizeDouble(tp,(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(sl<0) request.sl=NormalizeDouble(PositionGetDouble(POSITION_SL),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(tp<0) request.tp=NormalizeDouble(PositionGetDouble(POSITION_TP),(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS));
                          if(!OrderSend(request,result))
                          PrintFormat("OrderSend error %d",GetLastError()); 
                         }
                    }
                 }
              }
           } 
        }
     }
 }



  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-07-15 10:14
    关注

    上午好☀️☀️☀️️
    本答案参考通义千问

    你提到的问题是:在MQL5的模拟测试中,平仓功能正常;但在实盘运行时,部分平仓操作无法实现。

    这个问题可能涉及多个方面,包括但不限于:

    • 交易权限问题(实盘账户限制)
    • 订单类型或参数错误
    • API调用方式不正确
    • 交易请求未被正确发送
    • 交易频率限制或延迟
    • 账户资金不足或流动性问题

    ✅ 重点分析

    1. 实盘与模拟盘的差异

    在实盘中,平台对交易行为有更严格的限制,例如:

    • 不能频繁下单/平仓
    • 有些交易品种不允许做市商(Market Maker)模式
    • 某些EA需要申请“自动交易”权限
    • 实盘中可能无法使用 ORDER_FILLING_IOC 等特殊填单方式

    建议:检查实盘账户是否启用了“自动交易”权限,并确认该交易品种是否允许做市商交易。


    2. OrderSend() 的返回值处理

    你在代码中使用了 if(!OrderSend(request, result)) 来判断是否成功,但没有打印出具体错误信息。

    建议:添加详细的错误日志输出,便于定位失败原因。


    3. PositionGetTicket(i)PositionGetInteger(POSITION_TYPE) 使用问题

    MQL5 中 PositionGetTicket(i) 是用于获取订单号的函数,而 PositionsTotal() 返回的是当前所有持仓订单的数量,不是订单编号

    注意:在 MQL5 中,PositionGetTicket(i) 并不是一个标准函数!
    正确的方式是使用 PositionSelectByIndex(i)PositionSelect(ticket) 来遍历持仓。


    4. request.position = PositionGetTicket(i); 无效

    由于 PositionGetTicket(i) 不是合法函数,因此 request.position 可能为0,导致平仓失败。


    ✅ 修改后的完整代码示例

    以下是针对你的代码进行修改后的版本,重点修正了以下几点:

    • 使用正确的持仓遍历方法
    • 增加详细错误日志
    • 修复 request.position 设置
    • 优化逻辑结构
    // 定义变量
    string symbol = "XAUUSD";
    double lot = 0.05;
    double pinglot = 0.02;
    double mm = 10; // 盈利点数
    int magic = 12345;
    
    void OnTick()
    {
        // 检查并设置止损
        kaimodifysltp(symbol, POSITION_TYPE_BUY, lot, 50, 0, 0);
        kaimodifysltp(symbol, POSITION_TYPE_SELL, lot, 50, 0, 0);
    
        // 平仓部分仓位
        closeallbuylot(symbol, lot, pinglot, mm, magic);
        closeallselllot(symbol, lot, pinglot, mm, magic);
    
        // 修改止损到开仓价
        modifysltp(symbol, POSITION_TYPE_BUY, lot, mm, 0, 0);
        modifysltp(symbol, POSITION_TYPE_SELL, lot, mm, 0, 0);
    }
    
    // 平仓部分买单
    void closeallbuylot(string symbol, double lot, double pinglot, double mm, int magic)
    {
        for (int i = PositionsTotal() - 1; i >= 0; i--)
        {
            if (PositionSelectByIndex(i))
            {
                if (PositionGetString(POSITION_SYMBOL) == symbol && 
                    PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY &&
                    PositionGetDouble(POSITION_VOLUME) == lot &&
                    (SymbolInfoDouble(symbol, SYMBOL_BID) - PositionGetDouble(POSITION_PRICE_OPEN)) >= mm)
                {
                    if (magic == 0 || PositionGetInteger(POSITION_MAGIC) == magic)
                    {
                        MqlTradeRequest request = {0};
                        MqlTradeResult result = {0};
    
                        request.action = TRADE_ACTION_DEAL;
                        request.symbol = symbol;
                        request.volume = pinglot;
                        request.type = ORDER_TYPE_SELL;
                        request.price = SymbolInfoDouble(symbol, SYMBOL_BID);
                        request.deviation = 100;
                        request.type_filling = ORDER_FILLING_IOC;
                        request.position = PositionGetInteger(POSITION_TICKET);
    
                        if (!OrderSend(request, result))
                        {
                            PrintFormat("Close Buy Order Error: %d", GetLastError());
                        }
                    }
                }
            }
        }
    }
    
    // 平仓部分卖单
    void closeallselllot(string symbol, double lot, double pinglot, double mm, int magic)
    {
        for (int i = PositionsTotal() - 1; i >= 0; i--)
        {
            if (PositionSelectByIndex(i))
            {
                if (PositionGetString(POSITION_SYMBOL) == symbol && 
                    PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL &&
                    PositionGetDouble(POSITION_VOLUME) == lot &&
                    (PositionGetDouble(POSITION_PRICE_OPEN) - SymbolInfoDouble(symbol, SYMBOL_ASK)) >= mm)
                {
                    if (magic == 0 || PositionGetInteger(POSITION_MAGIC) == magic)
                    {
                        MqlTradeRequest request = {0};
                        MqlTradeResult result = {0};
    
                        request.action = TRADE_ACTION_DEAL;
                        request.symbol = symbol;
                        request.volume = pinglot;
                        request.type = ORDER_TYPE_BUY;
                        request.price = SymbolInfoDouble(symbol, SYMBOL_ASK);
                        request.deviation = 100;
                        request.type_filling = ORDER_FILLING_IOC;
                        request.position = PositionGetInteger(POSITION_TICKET);
    
                        if (!OrderSend(request, result))
                        {
                            PrintFormat("Close Sell Order Error: %d", GetLastError());
                        }
                    }
                }
            }
        }
    }
    

    ✅ 推荐解决方案步骤

    1. 检查实盘账户权限

      • 确保已启用“自动交易”权限
      • 确认该货币对支持做市商交易(Market Maker)
    2. 使用 PositionSelectByIndex() 遍历持仓

      • 避免使用 PositionGetTicket(i) 这个非标准函数
    3. 增加错误日志

      • 打印 GetLastError() 以识别具体失败原因
    4. 调整 request.position 参数

      • 使用 PositionGetInteger(POSITION_TICKET) 获取订单编号
    5. 避免高频交易

      • 实盘中不要过于频繁地执行平仓操作
    6. 测试不同填单方式

      • 尝试使用 ORDER_FILLING_FOKORDER_FILLING_IOC,根据平台支持情况选择

    ✅ 总结

    | 问题 | 解决方案 | |------|----------| | 实盘无法平仓 | 检查账户权限、使用 PositionSelectByIndex() 遍历持仓 | | PositionGetTicket(i) 错误 | 改用 PositionGetInteger(POSITION_TICKET) | | 平仓失败 | 添加 PrintFormat("Error: %d", GetLastError()); 查看具体错误码 | | 高频交易限制 | 控制平仓频率,避免触发风控机制 |


    如果你愿意提供完整的代码和错误日志,我可以进一步帮你排查具体问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月15日