KimIV的有用功能 - 页 2

 
不如这样:
if (err==146)
{
while (IsTradeContextBusy())
{
if (IsTradeAllowed()) break;
else
Sleep(1000*1,1);
}}
我认为这是一个更快的解决方案。请分享您的意见。
谢谢你。
 
Red.Line писал (а): 感谢这个有用的话题,虽然我是关于烧饼的,但还是可能有人面对过以μl为单位的大数据集的储备和采样问题。微升和数据库?有没有人朝这个方向想过?
当然,这是一个简单的解决方案,但也有一些东西。 https://forum.mql4.com/ru/9377
 
zhuki:
你对这个变体有什么看法。
if (err==146)
{
  while (IsTradeContextBusy())
  {
    if (IsTradeAllowed()) break;
    else 
    Sleep(1000*1,1);
  }
}
在我看来,这是一个更快的解决方案。我是这样工作的。评论。
谢谢你。

我将会很好地接受。带着理解。暂停的时间更少,工作更快。但你的版本中存在一些不合理的冗余。

IsTradeContextBusy 函数返回贸易线程占用的标志。在第195次建造之前,根本没有这样的功能。因此,我们使用了IsTradeAllowed 函数,该函数返回一个符号,表明EA被允许进行交易,并且交易流是自由的。

我们通过在EA属性对话框(F7键)中勾选 "允许EA进行交易 "的选项,允许EA进行交易。

错误146(贸易流繁忙)与允许专家顾问进行交易没有关系。因此,让我们回顾一下IsTradeAllowed 函数的属性,因为它们只与交易线程有关。

所以,交易线程是自由的,IsTradeAllowed 函数返回True。交易线程很忙,IsTradeAllowed 函数返回False。现在让我们看一下IsTradeContextBusy 函数返回的值。交易线程是自由的,IsTradeContextBusy 函数返回False。交易线程很忙,IsTradeContextBusy 函数返回True。我们可以看到,对于相同的贸易流状态,IsTradeAllowedIsTradeContextBusy 函数的值是相反的。此外,这些功能在贸易流动状态方面是相互重复的,而不是相互补充的。因此,可以排除其中一个。哪一个?IsTradeAllowed 函数,正如我在上面已经提到的,除了交易流状态标志,还返回允许EA交易的标志,在这种情况下,即处理错误146(交易流繁忙)时,对我们来说是没有必要的。因此,只使用一个函数IsTradeContextBusy 就足够了。如果你执行上述缩写,你的代码将被简化为我的。

if (err==146) while (IsTradeContextBusy()) Sleep(1000*1,1);
唯一的区别是停顿的大小。但这是一个品味、个人偏好、交易风格等方面的问题。你可以放一个0.1秒的停顿。这不是什么大问题...我只是更喜欢11秒。
 
但为了准确起见,我还是倾向于在所有类型的交易操作 之间做一个暂停,从5秒到线程的释放。谢谢你。
 

SetOrder 函数中发现了两个错误。

  1. MarketInfo 函数的使用不正确。它应该在检查sy 参数之后被调用,而不是在之前。
  2. 纠正订单设置水平工作不正确的问题。除此之外,停止和接管的价格水平也没有得到纠正。现在它被修复了,而且工作得非常好。我已经用测试脚本测试了这个东西很长时间,我稍后会展示一下。

注意!带 SetOrder 功能的在线交易的帖子已被纠正。这个功能有点长。它不适合放在整个柱子里,所以不得不移到拖车上。

 

在这篇文章中,我决定给出解释SetOrder 函数如何工作的要点。我自己不从事订单工作,也就是说,我在这里是在别人的领域。也许知道SetOrder 函数如何工作的人可以提出改进建议或发现错误。

1.在第一行代码中,局部变量被声明,其中一些变量被初始化。例如,在lsComm中,写的是EA的名称和GetNameTF 函数返回的时间框架的名称。顺便说一下,我不打算在GetNameOPGetNameTFMessage 等函数上多说,只有在有人对它们有疑问时才会说。

string   lsComm=WindowExpertName()+" "+GetNameTF(Period());

2.检查收到的参数。如果sy 是空的,它将以当前工具的名称初始化。图表上图标的颜色变量由操作类型初始化。如果订单的非零到期时间小于当前时间,它将被重置为零。

if (sy=="" || sy=="0") sy=Symbol();
msl=MarketInfo(sy, MODE_STOPLEVEL);
if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell;
if (ex>0 && ex<TimeCurrent()) ex=0;

3.交易尝试周期的主体,其数量由全局变量 NumberOfTry 的值 限制。在SetOrder 函数的主循环内进行的操作更进一步。

for (it=1; it<=NumberOfTry; it++)

4.如果SetOrder 函数在测试器中没有被执行,我们有机会终止其操作。等待贸易流释放周期在此进行。市场环境变量被更新,当前时间被记录。

if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) {
  Print("SetOrder(): Остановка работы функции");
  break;
}
while (!IsTradeAllowed()) Sleep(5000);
RefreshRates();
ot=TimeCurrent();

5.向交易服务器发送一个请求。如果票数是正数,SetOrder 函数就会终止。

ticket=OrderSend(sy, op, ll, pp, Slippage, sl, tp, lsComm, mn, ex, clOpen);
if (ticket>0) {
  if (UseSound) PlaySound(NameFileSound); break;
 

6.如果票数为负数,则进行执行错误的处理
7.如果出现128(超时日期已过)、142(订单已排队)和143(订单已被交易商接受执行)的错误,我们会暂停66秒。暂停之后,使用ExistOrders函数(我们将在后面描述),我们检查在服务器请求和当前时刻之间的时间间隔内是否已经设置了订单。如果命令已经设定,则退出该功能。

err=GetLastError();
if (err==128 || err==142 || err==143) {
  Sleep(1000*66);
  if (ExistOrders(sy, op, mn, ot)) {
    if (UseSound) PlaySound(NameFileSound); break;
  }
  Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
  continue;
}

8.项目大小以及买入和卖出价格都存储在本地变量中。

mp=MarketInfo(sy, MODE_POINT);
pa=MarketInfo(sy, MODE_ASK);
pb=MarketInfo(sy, MODE_BID);

9.在错误130(不正确的止损)的情况下,如果可能的话,订单、止损和取出的价格水平会被纠正。

// Неправильные стопы
if (err==130) {
  switch (op) {
    case OP_BUYLIMIT:
      if (pp>pa-msl*mp) pp=pa-msl*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_BUYSTOP:
      if (pp<pa+(msl+1)*mp) pp=pa+(msl+1)*mp;
      if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp;
      if (tp>0 && tp<pp+(msl+1)*mp) tp=pp+(msl+1)*mp;
      break;
    case OP_SELLLIMIT:
      if (pp<pb+msl*mp) pp=pb+msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
    case OP_SELLSTOP:
      if (pp>pb-msl*mp) pp=pb-msl*mp;
      if (sl>0 && sl<pp+(msl+1)*mp) sl=pp+(msl+1)*mp;
      if (tp>pp-(msl+1)*mp) tp=pp-(msl+1)*mp;
      break;
  }
  Print("SetOrder(): Скорректированы ценовые уровни");
}

10.这些信息,可以帮助解决问题或以后找到错误,显示在报告中。

Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it);
Print("Ask=",pa,"  Bid=",pb,"  sy=",sy,"  ll=",ll,"  op=",GetNameOP(op),
      "  pp=",pp,"  sl=",sl,"  tp=",tp,"  mn=",mn);
if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy);

在最后,我们处理其他错误。有的显示长时间停顿(5分钟),有的封锁专家顾问,有的允许进一步尝试交易,等等。

就这样吧!描述完毕!

 

ExistOrders()函数。

返回一个存在订单的标志。回答订单是否被设定的问题。你可以使用这个功能来请求任何订单,以及更具体的订单。请求过滤器是用功能参数配置的。

  • sy- 对文书的名称施加限制。默认参数是"" - 不受限制,即任何乐器。如果你传递NULL,订单选择将受到当前符号的限制。
  • op- 对订单类型进行限制。默认情况下没有约束,即任何订单类型都被选中。参数的有效值是-1,OP_BUYLIMIT,OP_BUYSTOP,OP_SELLLIMIT和OP_SELLSTOP。
  • mn- 对订单的识别("神奇")数字设置一个限制。默认情况下没有约束,也就是说,具有任何神奇数字的订单都被检查。
  • ot- 对订单设置时间进行限制。它被检查以确保订单的设置晚于该参数的值。默认情况下,没有限制,也就是说,任何设置时间的订单都会被选中。
//+----------------------------------------------------------------------------+
//|  Автор    : Ким Игорь В. aka KimIV,  http://www.kimiv.ru                   |
//+----------------------------------------------------------------------------+
//|  Версия   : 12.03.2008                                                     |
//|  Описание : Возвращает флаг существования ордеров.                         |
//+----------------------------------------------------------------------------+
//|  Параметры:                                                                |
//|    sy - наименование инструмента   (""   - любой символ,                   |
//|                                     NULL - текущий символ)                 |
//|    op - операция                   (-1   - любой ордер)                    |
//|    mn - MagicNumber                (-1   - любой магик)                    |
//|    ot - время открытия             ( 0   - любое время установки)          |
//+----------------------------------------------------------------------------+
bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) {
  int i, k=OrdersTotal(), ty;
 
  if (sy=="0") sy=Symbol();
  for (i=0; i<k; i++) {
    if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) {
      ty=OrderType();
      if (ty>1 && ty<6) {
        if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) {
          if (mn<0 || OrderMagicNumber()==mn) {
            if (ot<=OrderOpenTime()) return(True);
          }
        }
      }
    }
  }
  return(False);
}
 

如何使用ExistOrders()函数的例子。

1.检查任何订单的可用性

ExistOrders();

2.检查当前图表上任何工具的任何订单的可用性

ExistOrders(NULL);

3.检查任何工具上是否存在买入限价单

ExistOrders("", OP_BUYLIMIT);

4.检查欧元兑美元是否有一个神奇号码为123456的卖出止损单

ExistOrders("EURUSD", OP_SELLSTOP, 123456);

5.检查任何设置时间为2小时或更短的订单的可用性

ExistOrders("", -1, -1, TimeCurrent()-2*60*60);
在预告片中,有一个测试ExistOrders 函数的脚本。脚本中的前4个例子被注释掉了。

附加的文件:
 

警告!在 12.03.2008 07:24的帖子中,我已经替换了SetOrder.mq4的附件