循环和关闭或删除订单

 

这是我看到的最常见的错误之一,部分原因可能是由于像Expert Advisor Builder这样的垃圾。 因此,我认为现在是时候为这个问题建立一个专门的主题,以便将来可以链接到它,供人们参考。

问题

让我们举个简单的例子;我们想要一个函数来关闭我们EA的所有未结订单,有很多例子,但让我们从头开始创建一个。

我们需要一个循环,因为我们想关闭特定EA的所有订单, 这个循环,我们将有代码来选择订单,代码来检查它是正确的符号和魔法数字,最后代码来关闭订单。

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = 0; PositionIndex < TotalNumberOfOrders; PositionIndex++)  //  <-- for loop to loop through all Orders
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?

      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

这段代码是坏的.. . 不要使用它.. . 我将在下一节中解释原因 .

解释

让我们通过上面的代码......一行一行的,一个一个的订单......来工作。

让我们假设我们有以下要关闭的订单,他们都有相同的魔法号码和符号,所以我们希望我们的代码能将他们全部关闭。

位置 票号
0111
1222
2333
3444
4555

循环的第一次运行。

PositionIndex的初始值是0,所以位置0的订单被选中,票号是111,这个订单被成功删除,其余订单的位置变化如下。

位置 票号
0222
1333
2444
3555

循环的第二次运行。

现在PositionIndex 的值是1,所以位置1的订单被选中,票号333, 这个订单被 成功 删除,其余订单的位置变化 如下

位置 票号
0222
1444
2555

循环的第三次运行。

现在 PositionIndex的值 是2,所以位置2的订单被选中,票号是555, 这个订单被 成功 删除,其余订单的位置变化 如下

位置 票号
0222
1444

循环的第四次运行。

现在 PositionIndex的值 是3 OrderSelect()试图选择位置3的订单,但失败了,继续执行代码到循环中的下一个值。


循环的第5次和最后一次运行。

现在 PositionIndex是4,OrderSelect()试图选择位置4的订单, 但失败了,Continue将代码执行到循环中的下一个值。 ...循环已经结束。


我们现在只剩下2个订单,即222和444号票,它们本应被关闭,但却没有。

解决方案

下面的代码是在关闭未结订单或删除待定 订单时的正确做法 ......

关键的区别是,该循环从(TotalNumberOfOrders - 1 ) 递减0

int PositionIndex;    //  <-- this variable is the index used for the loop

int TotalNumberOfOrders;   //  <-- this variable will hold the number of orders currently in the Trade pool

TotalNumberOfOrders = OrdersTotal();    // <-- we store the number of Orders in the variable

for(PositionIndex = TotalNumberOfOrders - 1; PositionIndex >= 0 ; PositionIndex --)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
      if ( ! OrderClose( OrderTicket(), OrderLots(), OrderClosePrice(), Slippage ) )               // <-- try to close the order
         Print("Order Close failed, order number: ", OrderTicket(), " Error: ", GetLastError() );  // <-- if the Order Close failed print some helpful information 
      
   } //  end of For loop

让我们再一次通过上面的代码 ...... 一行一行,一个一个订单 ......

我们有和之前一样的订单。

位置 票数
0111
1222
2333
3444
4555

循环的第一次运行。

PositionIndex的初始值是TotalNumberOfOrders-1,等于5-1=4, 所以位置4的订单被选中,票号555,这个订单被成功删除,其余订单的位置变化如下。

位置 票号
0111
1222
2333
3444

循环的第二次运行。

现在PositionIndex 的值是3,所以位置3的订单被选中,票号444, 这个订单被 成功 删除,其余订单的位置变化 如下

位置 票号
0111
1222
2333

循环的第三次运行。

现在 PositionIndex的值 是2,所以位置2的订单被选中,票号333, 这个订单被 成功 删除,其余订单的位置变化 如下

位置 票号
0111
1222

循环的第4次运行。

现在 PositionIndex的值 是1,所以位置1的订单被选中,票号222, 这个订单被 成功 删除,其余订单的位置变化 如下

位置 票号
0111

第五次也是最后一次运行循环。

现在 PositionIndex 的值 是0 ,所以位置0的订单被选中,票号111, 这个订单被 成功 删除,值0是循环的最后一个有效值 . . . 循环已经结束。

我们已经成功删除了所有匹配的订单 . .

链接到这个主题。 循环和关闭或删除订单

 

让我们举一个更复杂的例子 . . .

假设我们有以下要关闭的订单,它们都有相同的数字,但有些订单的符号与我们的EA不同,我们希望我们的代码能关闭与我们的EA相同符号的订单,EURUSD。

头寸 票号 符号
0111欧元兑美元
1222欧元兑美元
2333英镑兑美元
3444欧元兑美元
4555欧元兑美元


循环的第一次运行。

PositionIndex的初始值是TotalNumberOfOrders - 1,等于5 - 1 = 4,所以位置4的订单被选中,票号555,这个订单与神奇的数字和符号相匹配,所以被成功删除,其余订单的位置变化如下。

位置 票号 符号
0111欧元兑美元
1222欧元兑美元
2333英镑兑美元
3444欧元兑美元

循环的第二次运行。

现在PositionIndex 的值是3,所以位置3的订单被选中,票号444, ,这个订单与神奇的数字和符号相匹配,所以 成功 删除,其余订单的位置变化 如下

位置 票号 符号
0111欧元兑美元
1222欧元兑美元
2333英镑兑美元


循环的第三次运行。

现在 PositionIndex的值 是2,所以位置2的订单被选中,票号333, ,这个订单与神奇的数字匹配,但不是 符号,所以它 ,没有被删除,其余的订单没有变化

位置 票号 符号
0111欧元兑美元
1222欧元兑美元
2333英镑兑美元

循环的第四次运行。

现在 PositionIndex的值 是1,所以位置1的订单被选中,票号222, ,这个订单与魔法号码和符号相匹配,所以 成功 删除,其余订单的位置变化 如下

位置 票号 符号
0111欧元兑美元
1333英镑兑美元

第五次也是最后一次循环。

现在 PositionIndex 的值 是0 ,所以0位置的订单被选中,票号是111, 这个订单被 成功 删除,0值是循环的最后一个有效值 . . . 循环已经结束。

我们已经成功地删除了所有匹配的订单,只剩下一个不匹配我们符号的订单,票号333现在在0位置 ......

位置 票号 符号
0333英镑兑美元


此主题的链接。 循环和关闭或删除订单

 
也请看为什么你必须计时并测试 OrderSelect状态
 

感谢Raptor的这一重要 解释。

Y.

 
这对我来说是非常有帮助的,垃圾专家顾问建造者之王!我很喜欢砍掉这些代码。哦,我是多么享受砍掉所产生的代码。非常感谢。
 

哇。 所有这些信息都是为了关闭一个订单。

我想知道需要多少信息才能每天持续获得50多个点,每天(平均)--在过去的137次交易中没有失败。

告诉我如何做这样的事情,我会认为这是非常有用的信息,大师,将是你的称号,直到永远,阿门。

 
CFx:

哇。 所有这些信息都是为了关闭一个订单。

我想知道需要多少信息才能每天持续地获得50多个点,每天(平均)--在过去137次交易中没有失败。

我对点数没有兴趣......我可以用它们做什么? 我不能花掉它们,GBPPIPS的比率是多少?
 
CFx:

我想知道,在过去的137次交易中,需要多少信息才能每天持续地获得50多个点,(平均而言)--没有失败。

告诉我如何做这样的事情,我会认为这是非常有用的信息,大师,将是你的称号,直到永远,阿门。

  1. 不要用偏离主题的信息来抢占线程
  2. 我们不会给你看的,因为你没有读过规则除了关于MetaQuotes Language 4和自动交易的讨论,其他的讨论都是 禁止的。
 

Raptor,I do know at 1st glance of ur post that u r quite n expert in mql4.this thread again helps clear my doubts!keep up the good works.tnx

 

只是另一个想法。

for(PositionIndex = 0; PositionIndex < OrdersTotal() ; PositionIndex ++)  //  <-- for loop to loop through all Orders . .   COUNT DOWN TO ZERO !
   {
   if( ! OrderSelect(PositionIndex, SELECT_BY_POS, MODE_TRADES) ) continue;   // <-- if the OrderSelect fails advance the loop to the next PositionIndex
   
   if( OrderMagicNumber() == MagicNo       // <-- does the Order's Magic Number match our EA's magic number ? 
      && OrderSymbol() == Symbol()         // <-- does the Order's Symbol match the Symbol our EA is working on ? 
      && ( OrderType() == OP_BUY           // <-- is the Order a Buy Order ? 
      ||   OrderType() == OP_SELL ) )      // <-- or is it a Sell Order ?
   
         add_trade_to_close_queue( OrderTicket());  // <--  You need to model the queue mechanism ...
      
   } //  end of For loop


请注意。

 
abstract_mind:


只是另一个想法。


请注意。

是的,理解MT4背后的逻辑,增加或减少计数器的代码由你决定。
原因: