【问题标题】:OrderClose function not working correctlyOrderClose 功能无法正常工作
【发布时间】:2021-05-25 15:04:24
【问题描述】:

这是OrderClose()的正确实现吗?

 for(int ii = 0; ii < OrdersTotal(); ii++)
 {
  if(OrderSelect(ii, SELECT_BY_POS, MODE_TRADES))
    {
     if(OrderType() == OP_BUY && OrderMagicNumber() == MagicStart && OrderSymbol() == symb)
       {
        int tikt = OrderTicket();
        if(!OrderClose(tikt,OrderLots(),bid,4,clrPurple))
          {
           Print("Close Error", GetLastError());
          }
       }
       
     if(OrderType() == OP_SELL && OrderMagicNumber() == MagicStart && OrderSymbol() == symb)
       {
        int tikt = OrderTicket();
        if(!OrderClose(tikt,OrderLots(),ask,4,clrPurple))
          {
           Print("Close Error", GetLastError());
          }
       }
    }
 }

我在开始交易之前使用此代码。例如,如果有买入信号,则先关闭卖出,然后打开买入;如果有卖出信号,则先关闭卖出,然后打开买入。

但它只是第一次这样做,之后就不会工作了。假设有卖出信号。然后它将关闭买入并打开卖出,但是当有第二个买入信号时,它不会关闭卖出,也不会打开买入。

专家选项卡中没有错误。我在专家选项卡中收到的唯一信息是这样的消息:Positions order mismatch。它不像错误或警告那样显示,它只是作为消息显示。

【问题讨论】:

    标签: mql4 mt4


    【解决方案1】:

    如果要关闭所有订单,则需要从最新的订单位置开始迭代到第一个位置。 试试这个:

    for(int i = OrdersTotal()-1; i >= 0; i--)
     {
      if(OrderSelect(i, SELECT_BY_POS))
        {
         if(OrderType() == OP_BUY)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Bid, 0))
              {
               Print("Error closing order: ", GetLastError());
              }
           }
         if(OrderType() == OP_SELL)
           {
            if(!OrderClose(OrderTicket(), OrderLots(), Ask, 0))
              {
               Print("Error closing order: ", GetLastError());
              }
           }
        }
     }
    

    当你关闭订单时,你不应该从 0 开始迭代,因为 OrdersTotal() 函数 decrement 在你遍历所有订单并一一关闭它们时它的值。

    例如(在您的循环中)您有 5 个订单:

    1. i = 0, OrdersTotal() = 5 -> 平仓 0 仓。
    2. i = 1, OrdersTotal() = 4 -> 平仓 1 的订单。
    3. i = 2, OrdersTotal() = 3 -> 平仓 2 的订单。
    4. i = 3,现在循环结束,因为 i == OrdersTotal()。

    另外,不用int tikt= OrderTicket();,只需在OrderClose()函数中使用OrderTicket()

    【讨论】:

    • 您的for(int i = OrdersTotal(); i &gt;= 0; i--) 声明应为for(int i=OrdersTotal()-1; i&gt;=0; i--)
    • @tomgny 我也试过了,但仍然是同样的问题,在第二次尝试时它由于某种原因停止工作
    • 你能展示执行关闭订单函数的部分代码吗?
    【解决方案2】:

    尝试以下更健壮的代码,并且不假定要关闭的订单与运行 EA 的图表的交易品种相同。这将关闭帐户上的所有订单。如果您想将此限制在 EA 运行的图表上的订单,或仅由 EA 开立的订单,您应该在关闭订单之前使用OrderSymbol()OrderMagicNumber() 过滤订单。

       if(OrdersTotal()>0)
       {
          for(int i=OrdersTotal()-1; i>=0; i--)
          {
             if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
             {
                if(OrderType()==OP_BUY || OrderType()==OP_SELL)
                {
                   double price;
                   if(OrderType()==OP_BUY) price=MarketInfo(OrderSymbol(),MODE_BID); else price=MarketInfo(OrderSymbol(),MODE_ASK);
                   int ticket=OrderTicket();
                   bool res=OrderClose(ticket, OrderLots(), price, 50, clrNONE);
                   if(!res) Print("Error Closing Ticket #", IntegerToString(ticket));
                }
                else
                {
                   int ticket=OrderTicket();
                   bool res=OrderDelete(ticket);
                   if(!res) Print("Error Closing Ticket #", IntegerToString(ticket));
                }
             }
          }
       }
    

    【讨论】: