在特定经纪商的真实账户中存在多个订单输入问题 - 页 2

 
Malacarne:

你好,BlindMist,检查你的本地数据库以验证你的账户是否与经纪商服务器同步,这确实 是有意义的。

请看一下建议的帖子,解决这个问题。

我刚刚看了建议帖,它没有提到如何防止订单被多次执行......

即使使用Sleep()函数,你要等多久才能确定交易失败?

在我的EA中,我让订单发送请求在10秒后超时,然后再尝试......但有时订单会在初始请求的15-20秒后被执行;因此,导致不必要的双重交易。

 
BlindMist:

我刚刚看了建议的帖子,它没有提到如何防止订单被多次执行......

即使有Sleep()函数,你要等多久才能确定交易失败?

在我的EA中,我让订单发送请求在10秒后超时,然后再尝试......但有时订单会在初始请求的15-20秒后被执行;因此,导致不必要的双重交易。

嗨,BlindMist,我对这个问题的想法,我仍然认为是检查它的唯一方法(而不是仅仅测试PositionSelect或仅仅是一个Sleep),是在等待很长一段时间后创建一个类似致命错误的东西,或者在你有符号位置时立即跳转(下面的代码)。

这个问题唯一的好处是,可能PositionSelect,无论早晚,都会从服务器上得到更新的位置,所以我们要做的是等待一个最大的时间(我们的超时)来表示一个致命的错误,并做一些小的样本来检查是否正常(在我的例子中是100ms)。

bool fatalError=false; // atention: declare this as global

....

if (fatalError==false) {
  if (m_Trade.PositionOpen(Symbol(), ORDER_TYPE_BUY, LotSize, Price, 0, 0)) {
    Print("Position opened in ", Symbol());
    int maxTimeout=0;
    while (!PositionSelect(Symbol())) {
       Sleep(100);
       maxTimeout++;
       if (maxTimeout>100) {
          Print("### PositionSelect fatal error!");
          fatalError=true;
          break;
       }
    }
    Print("--> PositionSelect delay=",maxTimeout*100);
    break;
  }
}

另一个更模块化的方法是创建一个函数 来控制超时,比如说。

bool PositionSelectTimeout(string symbol,int timeout) 
  { // timeout in seconds
   int maxTimeout=0;
   while(!PositionSelect(symbol)) 
     {
      Sleep(100);
      maxTimeout++;
      if(maxTimeout>(timeout*10)) return(false); // fatal error (timeout)
     }
   return(true); // position selected
  }

这里的主要想法是我的PositionSelectTimeout()取代原来的PositionSelect(),当然是作为一种变通,因为只有MQ可以解决一个真正好的、明确的解决方案。

比如说。

if (PositionSelectTimeout(Symbol(),60)) { // 60 seconds timeout
 ...
}

// instead of ...

if (PositionSelect(Symbol())) {
 ...
}

所以,在我看来,FinanceEngineer 必须做同样的事情来解决这个问题,并在他的循环中插入这个测试,以仔细检查位置是否可以休息。

 
figurelli:

嗨,BlindMist,我对这个问题的想法是,我仍然认为这是检查它的唯一方法(而不是只对PositionSelect进行一次测试或只进行一次Sleep),是在等待了很长时间后创建一个类似致命错误的东西,或者在你得到符号位置后立即跳转(代码如下)。

这个问题的唯一好处是,可能PositionSelect,无论早晚,都会从服务器上得到更新的位置,所以我们要做的是等待一个最大的时间(我们的超时)来表示一个致命的错误,并做一些小的样本来检查是否正常(在我的例子中是100ms)。

另一个更模块化的方法是创建一个函数来控制超时,比如说。

这里的主要想法是我的PositionSelectTimeout()取代原来的PositionSelect(),当然是作为一种变通,因为只有MQ可以解决一个真正好的、明确的解决方案。

比如说。

因此,在我看来,FinanceEngineer 必须做同样的事情来解决这个问题,并在他的循环中插入这个测试,以仔细检查位置是否可以休息。

谢谢figurelli,非常详细的回答。我会给它一个机会,看看它是否能改善我的系统。
 
BlindMist:
谢谢figurelli,非常详细的答复。我将给它一个机会,看看它是否能改善我的系统。
谢谢你,不客气。
 
BlindMist:

我刚刚看了建议的帖子,它没有提到如何防止订单被多次执行......

即使有Sleep()函数,你要等多久才能确定交易失败?

在我的EA中,我让订单发送请求在10秒后超时,然后再尝试......但有时订单会在最初请求的15-20秒后被执行;因此,导致不需要的双重交易。

15秒内执行 一个订单。这真的很糟糕。这里的问题是,我们不能从经纪商的服务器上得到任何东西(例如,即使是简单的状态检查代码等)。
 
FinanceEngineer:
一个订单的执行 需要15秒。这真的很糟糕。这里的问题是,我们无法从经纪商的服务器上获得任何东西(例如,即使是简单的状态检查代码等)。

你好,金融工程师,你是对的,但首先要做的是选择一个低延迟的经纪商,因为市场每次都会更快,这将是通常的问题。

另外,考虑到最坏的情况总是好的,因为你可以有一个低延迟的经纪人,但在一天中的某些时刻会有很大的延迟,例如当你有相关的新闻。

总之,MT5的OrderSend()不像MT4那么容易管理,因为MT4的返回值是一个Ticket。在MT5中,这种改变是必要的,因为MQL5架构中引入了股票市场的异步通信,可以与经纪人的OMS协议(例如FIX)进行通信。

但我认为这是OMS在订单管理方面的重大变化,因为很难获得实时票据,而MT5已经更新到这种新情况,主要是如果我们使用股票市场,我们有更多的延迟。

从这个意义上说,在MT5的OrderSend()之后,你做的更相关的事情是检查PositionSelect(),我强烈建议使用我提出的PositionSelectTimeout()的变通方法,因为上述所有原因。

我认为考虑最坏情况的唯一方法是在向市场发送订单后管理所有的if { } else { }条件,以一种你可以管理任何情况的方式。

我也希望有catch { },但我们可以使用GetLastError()来做与此接近的事情。

这是因为你也需要票据来确认头寸,而MT5 OrderSend()并不像MT4那样同步返回票据。

 
BlindMist:

我刚刚看了建议的帖子,它没有提到如何防止订单被多次执行......

即使有Sleep()函数,你要等多久才能确定交易失败?

在我的EA中,我让订单发送请求在10秒后超时,然后再尝试......但有时订单会在初始请求的15-20秒后被执行;因此,导致不必要的双重交易。

这是我目前正在使用的代码。到目前为止,我没有任何问题。你可以试试这段代码,如果它对该经纪人有效的话。

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

 
FinanceEngineer:

这是我目前正在使用的代码。到目前为止,我没有任何问题。你可以试试这个代码,如果它对该经纪人有效的话。

      bool checkOrderSend = OrderSend(request, result);
     
      if(result.retcode==10009 || result.retcode==10008)
      {
          Print("OrderSend was successful. Code: ",result.retcode);

          
          break;
      }
      else
      {
          Print(ResultRetcodeDescription(result.retcode));
      }
     

你是如何处理checkOrderSend 变量的?

你如何防止多个订单在没有检查服务器交易完成的情况下被执行?

 
figurelli:

你是如何处理checkOrderSend变量的?

如何防止多个订单在没有检查服务器交易完成的情况下被执行?

你好,figurelli

我的观点是在OrderSend函数 结束时同时检查10009和10008代码。 因为我发现许多人只检查其中一个返回代码(即10009或10008),并得到许多多个订单,因为他们通常放置一个for循环以避免没有订单的情况。

在我的例子中,如果我没有收到该经纪人的任何订单,我的for循环将尝试10次。 因此,可能值得澄清的是,如果有人得到多个订单,那么他们应该检查他们是否通过检查10009和10008来停止其Ordersending循环。

然而,讽刺的是,在模拟账户中,只检查一个返回代码就可以了。它不会给你带来任何多单问题。所以在这里我发现真实账户和模拟账户的行为略有不同。

问候您。

 
FinanceEngineer:

你好,figurelli

我的观点是在OrderSend函数 结束时同时检查10009和10008代码。 因为我发现许多人只检查其中一个返回代码(即10009或10008),并得到许多多个订单,因为他们通常放置一个for循环以避免没有订单的情况。

在我的例子中,如果我没有收到该经纪人的任何订单,我的for循环将尝试10次。 因此,可能值得澄清的是,如果有人得到多个订单,那么他们应该检查他们是否通过检查10009和10008来停止其Ordersending循环。

然而,讽刺的是,在模拟账户中,只检查一个返回代码就可以了。它不会给你带来任何多单问题。所以在这里我发现真实账户和模拟账户的行为略有不同。

问候您。

你好,FinanceEngineer,也许最好开始检查你的原始代码的多单问题,因为如果我们这样做,可能会解决其他关键点,不要失去重点,你怎么看?