新人对MQL4和MQL5的任何问题,对算法和代码的帮助和讨论 - 页 493

 
Roman Sharanov:
请您告知,按符号关闭EA所开的所有订单的功能是否正确实现?

架构本身是正确的。错误在于缺乏检查和使用一些功能。

bool OrderCloseAll()
{
   for(int i = OrdersTotal() - 1; i >= 0; i--)
   {
         if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)
            continue;

         if(OrderSymbol() !=Symbol() || OrderMagicNumber() != Magic)
            continue;
         
         if (!OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), slippage, clrWhite))
            return false;
   }

   return true;
}

  1. 在你的案例中,第一次迭代将失败 - 索引为OrdersTotal()的订单不存在。
  2. OrderSelect函数 的结果没有检查。
  3. 对函数OrderClose的结果没有检查。如果订单关闭失败,我们不能停留在同一个函数中,因为我们必须找出关闭不成功的原因。要做到这一点,我们必须让函数的结果为false,然后再决定下一步该怎么做。
  4. 我们不能对所有订单使用一个相同的收盘价。首先,订单可以是不同类型的,其次,价格很可能在执行以前的订单期间(收盘时)发生变化。我们可以使用MT4的一个功能来避免猜测使用什么价格:市场订单在关闭前的OrderClosePrice()值是Bid或Ask价格,取决于订单类型。
 
Ihor Herasko:

架构本身是正确的。错误在于缺乏检查和使用一些功能。

  1. 在你的案例中,第一次迭代将失败 - 索引为OrdersTotal()的订单不存在。
  2. OrderSelect函数 的结果没有检查。
  3. 对函数OrderClose的结果没有检查。如果订单关闭失败,我们不能停留在同一个函数中,因为我们必须找出关闭不成功的原因。要做到这一点,我们必须让函数的结果为false,然后再决定下一步该怎么做。
  4. 我们不能对所有订单使用一个相同的收盘价。首先,订单可以是不同类型的,其次,价格很可能在执行以前的订单期间(收盘时)发生变化。为了避免猜测使用哪个价格,我们可以使用MT4的一个功能:市场订单在关闭前的OrderClosePrice()值是Bid或Ask价格,取决于订单类型。

谢谢你,主要的问题可能是只是使用了相同的价格

 

来自OrderSelect的帮助 " 当使用SELECT_BY_POS参数按顺序选择订单 时,信息是按照来自交易服务器的顺序提供的。不保证获得的订单列表的排序"。

如果我们认为这句话是白白插入帮助中的,那就没问题。如果我们认为它的存在是有原因的,我们就不应该在循环运行订单列表的过程中改变这个列表。在服务器上删除了其中一个订单,并出现了一个新的、具有较小OrdersTotal的当前列表后,这些订单将如何排序,尚不清楚。更可靠的做法是,在不删除的情况下,运行同一个未改变的列表副本,收集(在一个数组中)所有要删除的交易的票号。然后忘掉那个清单,删除交易,按票据选择。

当然,人们愿意相信可修改列表中的有序性是被保留的,如果只是为了这种从无序列表的末尾删除几个订单的情况,但开发人员反对这样做......现在它在工作,如果新的构建出来--"我们警告过"。

 
Vladimir:

来自OrderSelect的帮助 " 当使用SELECT_BY_POS参数按顺序选择订单 时,信息是按照来自交易服务器的顺序提供的。不保证获得的订单列表的排序"。

如果我们认为这句话是白白插入帮助中的,那就没问题。如果我们认为它的存在是有原因的,我们就不应该在循环运行订单列表的过程中改变这个列表。在服务器上删除了其中一个订单,并出现了一个新的、具有较小OrdersTotal的当前列表后,这些订单将如何排序,尚不清楚。更可靠的做法是,在不删除的情况下,运行同一个未改变的列表副本,收集(在一个数组中)所有要删除的交易的票号。然后忘掉那个清单,删除交易,按票据选择。

当然,人们愿意相信可修改列表中的有序性是被保留的,如果只是为了这种从无序列表的末尾删除几个订单的情况,但开发人员反对这样做......现在它在工作,如果新的构建出来--"我们警告过"。

这样的 "美国 "已经开放了大约三百年了 :)

 
Artyom Trishkin:

这样的 "美国 "已经开放了三百年之久 :)

我不认为在这里代表新人提问的人已经自己发现了它。这就是我写作的原因。不是为版主,而是为提问者。看看这个主题的名称。

P.S. 我查了一下这种兴趣的来源。原来,它来自https://www.mql5.com/ru/forum/215783/page8"组织订单周期 "分支。事实证明,在2017年10月,这三百年还没有结束,仍然有新奇感。

Организация цикла перебора ордеров
Организация цикла перебора ордеров
  • 2017.09.16
  • www.mql5.com
MQL4 и MetaTrader 4: Организация цикла перебора ордеров
 
Vladimir:

我不认为在这里代表新人提问的人,自己已经发现了这一点。这就是我写作的原因。不是为版主,而是为提问者。看看这个主题的名称。

P.S. 我看了一下这种兴趣的来源。原来,它来自https://www.mql5.com/ru/forum/215783/page8"组织订单周期 "分支。事实证明,在2017年10月,这三百年还没有结束,仍然有新意。

又错了 :)三百年开始回到mql4.com--曾经有一段时间在那里被积极讨论。甚至还有那些时刻,你在"现在可以了,新的构建将出来--"我们警告过你 " 中描述的。只有在没有警告的情况下,如此几次--这取决于,这不取决于排序......

而且,是的,有一个专门的线程来回答此类问题。

Особенности языка mql4, тонкости и приёмы работы
Особенности языка mql4, тонкости и приёмы работы
  • 2017.02.24
  • www.mql5.com
В данной теме будут обсуждаться недокументированные приёмы работы с языком mql4, примеры решения тех, или иных задач...
 
Vladimir:

来自OrderSelect的帮助 " 当使用SELECT_BY_POS参数按顺序选择订单 时,信息是按照来自交易服务器的顺序提供的。不保证获得的订单列表的排序"。

如果我们认为这句话是白白插入帮助中的,那就没问题。如果我们认为它的存在是有原因的,我们就不应该在循环运行订单列表的过程中改变这个列表。在服务器上删除了其中一个订单,并出现了一个新的、具有较小OrdersTotal的当前列表后,这些订单将如何排序,尚不清楚。更可靠的做法是,在不删除的情况下,运行同一个未改变的列表副本,收集(在一个数组中)所有要删除的交易的票号。然后忘掉那个清单,删除交易,按票据选择。

当然,我愿意相信,至少在这种从无序列表的末尾删除几个订单的情况下,修改后的列表中的排序是被保留的,但开发人员反对这样做......现在它在工作,如果有新的构建出来,"我们警告过你"。

作为一个好主意(考虑到可以有几个专家顾问+交易员在账户上并行工作),你根本不能在一个循环中执行交易。收到必要的订单,执行操作,整个OnTick()再次被执行(不一定有新的tick到来)。以此类推,直到所有必要的操作被执行。

因此,形成一个数组来删除订单,相当于在循环中删除订单。

 

有一个 "停止 "按钮,我如何在按下后将其文字改为 "开始"?

bool stop;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
//Closed at Profit
   ObjectCreate(0,"Stop",OBJ_BUTTON,0,0,0);
   ObjectSetInteger(0,"Stop",OBJPROP_XDISTANCE,10);
   ObjectSetInteger(0,"Stop",OBJPROP_YDISTANCE,105);
   ObjectSetInteger(0,"Stop",OBJPROP_XSIZE,100);
   ObjectSetInteger(0,"Stop",OBJPROP_YSIZE,25);

   ObjectSetString(0,"Stop",OBJPROP_TEXT,"Stop");

   ObjectSetInteger(0,"Stop",OBJPROP_COLOR,White);
   ObjectSetInteger(0,"Stop",OBJPROP_BGCOLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_COLOR,Green);
   ObjectSetInteger(0,"Stop",OBJPROP_BORDER_TYPE,BORDER_FLAT);
   ObjectSetInteger(0,"Stop",OBJPROP_HIDDEN,true);
   ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
   ObjectSetInteger(0,"Stop",OBJPROP_FONTSIZE,12);
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
if(sparam=="Stop")
     {
      ObjectSetInteger(0,"Stop",OBJPROP_STATE,false);
      CloseAtProfit();
      stop=true;
     }
     }
 
lil_lil: 有一个 "停止 "按钮,我如何在按下后将其文字改为 "开始"?

请看我的专家实例

附加的文件:
ToFile.mq4  11 kb
 
STARIJ:

看看我的专家顾问例子

谢谢你,这正是我需要的。

可能有帮助的是,在缺失头寸方面有一个错误--- ToFile EURUSD,H1: 在'ToFile.mq4' (62,39)中除以零。

/*62*/  Строка=DoubleToStr(AccountEquity()/AccountMargin()*100,2)+"%"; // Уровень=Средства/Залог
文本在测试器中没有变化,有没有这样的选项?
原因: