mql5语言的特点、微妙之处以及技巧 - 页 88

 

关于交易、自动交易系统和交易策略测试的论坛

虫子,虫子,问题

fxsaber, 2016.07.19 12:41

如果只有HistoryDealGetInteger(TicketDeal, DEAL_TICKET)可以应用,那么ENUM_DEAL_PROPERTY_INTEGER::DEAL_TICKET 有什么意义?

通过ORDER_TICKET的例子,想法应该很清楚。

关于交易、自动交易系统和测试交易策略的论坛

MQL5中的OrderCloseTime()?

fxsaber, 2018.07.18 03:51

datetime OrderCloseTime( const ulong Ticket )
{
  return((HistoryOrderGetInteger(Ticket, ORDER_TICKET) == Ticket) || HistoryOrderSelect(Ticket) ? (datetime)HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE) : 0);
}

所以我们可以检查之前通过HistorySelect-function生成的当前历史表是否包含我们需要的记录。这同样适用于DEAL_TICKET。

 

关于交易、自动交易系统和交易策略测试的论坛

通过清算保存头寸价格水平(可能吗?)

fxsaber, 2018.07.17 20:45

// Возвращает цену открытия выбранной позиции без учета клиринга
double GetSummaryPositionPrice()
{
  double TotalVolume = 0;
  double TotalDealPrice = 0;
  
  if (HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)))
  {
    const int DealsTotal = HistoryDealsTotal();
    
    for (int i = 0; i < DealsTotal; i++)
    {
      const ulong DealTicket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(DealTicket, DEAL_ORDER))
      {
        const double DealVolume = (HistoryDealGetInteger(DealTicket, DEAL_TYPE) ? -1 : 1) * HistoryDealGetDouble(DealTicket, DEAL_VOLUME);
        const double DealPrice = HistoryDealGetDouble(DealTicket, DEAL_PRICE);
  
        if (TotalVolume * DealVolume >= 0)
          TotalDealPrice = (TotalDealPrice * TotalVolume + DealPrice * DealVolume) / (TotalVolume + DealVolume);
        else if (MathAbs(DealVolume) - MathAbs(TotalVolume) > 0.005)
          TotalDealPrice = DealPrice;
          
        TotalVolume += DealVolume;
      }      
    }
  }
  
  return(TotalDealPrice);
}
 

并非所有人都知道,GetMicrosecondCount函数与GetTickCount不同,它与本地计算机时间 相关联。 这意味着,如果这个时间发生变化(例如由于与互联网时间同步),GetMicrosecondCount的值也会发生相应变化。如果这个函数被用来测量时间间隔,应该记住这一点;事实上,它不应该被用于这个目的。 另一方面,GetTickCount没有这些问题。

作为演示,你可以运行这段代码,并在运行中改变计算机的时间。

  datetime time= TimeLocal();
  ulong    microsec= GetMicrosecondCount();
  uint     ticks= GetTickCount();
  
  while(!IsStopped())
  {
    Comment(int(TimeLocal()-time),"   ",(GetMicrosecondCount()-microsec)/1000000,"   ",(GetTickCount()-ticks)/1000);
    Sleep(10);
  }
 
阿列克谢-纳沃伊科夫

也许不是所有人都知道,GetMicrosecondCount函数与GetTickCount不同,是与本地计算机时间联系在一起的。

我不知道,谢谢你!

 

GetTickCount函数 的一个变体,可以避免溢出(前提是调用该函数的间隔时间不超过50天)。

ulong GetTickCountLong()
{
  static ulong sum=0;
  static uint  lasttickcount=0;
  uint tickcount= GetTickCount();
  if (tickcount<lasttickcount) sum+=0x100000000;
  lasttickcount= tickcount;
  return sum + tickcount;
}
 
Alexey Navoykov:

人们可能不知道,与GetTickCount不同,GetMicrosecondCount函数与本地计算机时间相关联。 这意味着,如果这个时间发生变化(例如由于与互联网时间同步),GetMicrosecondCount的值也会发生相应变化。如果这个函数被用来测量时间间隔,应该记住这一点;事实上,它不应该被用于这个目的。 另一方面,GetTickCount没有这些问题。

为了证明这一点,你可以运行这段代码,并在执行代码的过程中改变计算机的时间。

嗯,这是一个开发者应该修复的错误。那么这个功能就不符合描述。

Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента начала работы MQL5-программы.
GetTickCount 相比,这个函数的价值是微秒,而不是毫秒(精确度高1000倍)。它也是不能充气的。
这就是为什么说它的可替代性是不太正确的。
 
阿列克谢-纳沃伊科夫

并非所有人都知道,GetMicrosecondCount函数与GetTickCount不同,它与本地计算机时间相关联。 这意味着,如果这个时间发生变化(例如由于与互联网时间同步),GetMicrosecondCount的值也会发生相应变化。如果这个函数被用来测量时间间隔,应该记住这一点;事实上,它不应该被用于这个目的。 另一方面,GetTickCount则没有这些问题。

为了证明这一点,你可以运行这段代码,并在运行中改变计算机的时间。

还有一个重要的看法--由此可见,使用GetTickCount函数而不是GetMicrosecondCount是绝对不合适的。
我认为这对许多人来说将是一个惊喜。

通过检查一个简单的脚本的操作。

void OnStart()
  {
   uint i=GetTickCount();
   uint i0=GetTickCount();
   while(i==i0) i0=GetTickCount(); 
   
   int N1=1;
   ulong t1=GetMicrosecondCount();
   uint i1=GetTickCount();
   uint i2=GetTickCount();
   while(i1==i2) { i2=GetTickCount(); N1++;}
   t1=GetMicrosecondCount()-t1;
   
   ulong t=GetMicrosecondCount();
   ulong t0=GetMicrosecondCount();
   while(t==t0) t0=GetMicrosecondCount(); 
   int N2=1;
   ulong t2=GetMicrosecondCount();
   ulong t3=GetMicrosecondCount();
   while(t2==t3) { t3=GetMicrosecondCount(); N2++;}
   ulong t4=t3-t2;

   Print("1 значение в милисекундах:  " +(string)i1+", следующее значение   "+ (string)i2 + ", разница - " +(string)t1 + 
   " микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = " +DoubleToString((double)t1*1000.0/N1,3)+ " наносекунды");
   
   Print("1 значение в микросекундах: " +(string)t2+", следующее значение   "+ (string)t3 + ", разница - " +(string)t4 + 
   " микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = " +DoubleToString((double)t4*1000.0/N2,3)+ " наносекунды");
  }

工作的结果。

2018.07.27 00:23:02.261 TestTimeCount   1 значение в милисекундах:  25225093, следующее значение   25225109, разница - 15663 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.323 наносекунды
2018.07.27 00:23:02.261 TestTimeCount   1 значение в микросекундах: 20247, следующее значение   20248, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 33.333 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в милисекундах:  25226421, следующее значение   25226437, разница - 15586 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.324 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в микросекундах: 22835, следующее значение   22836, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 30.303 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в милисекундах:  25227750, следующее значение   25227765, разница - 15657 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.309 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в микросекундах: 23701, следующее значение   23702, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 27.027 наносекунды

我们可以得出以下结论。

  • GetTickCount()函数 的值不是每毫秒 变化一次,而是每15.625毫秒(一秒的1/64,64=2^6)变化一次,而GetMicrosecondCount()函数的值是每 微型 第二。这意味着GetMicrosecondCount函数比GetTickCount要精确15625倍,而不是1000倍。
  • 但GetTickCount()函数比GetMicrosecondCount()大约快12-15倍。
 
尼古拉-森科

那么,这是一个开发者最好修复的错误。因为这样一来,功能就与描述不一致了。

与GetTickCount相比,这个函数的值是微秒,而不是毫秒(精确1000倍)。它也是不充气的。
这就是为什么说它的可替代性是不太正确的。

如果你测量一些程序段的执行时间,系统性能的波动会抹平所有的准确性,并且会有几毫秒甚至几十毫秒的误差。 如果你测量持续时间小于1毫秒的非常小的片段,那么这有什么意义。 测量误差的份额会非常高。

 
阿列克谢-纳沃伊科夫

我还没有看到微秒的实际用途。 如果你测量一些程序段的执行时间,系统性能的波动会把所有这些精度拉平,误差在毫秒,甚至几十毫秒上。 如果你测量持续时间小于1毫秒的非常小的片段,那还有什么意义。 测量误差会非常高。

  1. 见我以前的帖子
  2. 我有很多关于微秒的实际使用的例子。

 
尼古拉-森科

另一个重要的观察结果表明,使用GetTickCount函数而不是GetMicrosecondCount是绝对不合适的。
我认为这对许多程序员来说将是一个惊喜。

通过检查一个简单的脚本的操作。

可以得出以下结论。

  • GetTickCount()函数 的值每15.6毫秒 变化一次,而不是每毫秒 一次,而GetMicrosecondCount()函数的值则是每 微型 第二。这意味着GetMicrosecondCount比GetTickCount要准确15600倍,而不是1000倍。
  • 但GetTickCount()比GetMicrosecondCount()大约快12-15倍。

重要的论点