MetaTrader 5策略测试器:缺陷,缺陷,改进建议 - 页 34

 
Artyom Trishkin:

我也从不看它。但它确实占用了有用的空间...

然而,它确实 派上了用场。

 
Artyom Trishkin:

我也从不看它。但它确实占用了有用的空间...

没有人会感到震惊,首先是来自测试人员的关于同步、加载专家顾问 等与当地时间的信息,然后是来自专家顾问和测试交易服务器与测试时间的信息,有时还穿插着来自测试人员与当地时间的信息?
 
找到了其中一个可以加速Tester的地方。事实证明,每次Tester比较两个价格(如BuyLimit和Tick.ask)时,它都要通过昂贵的归一化处理。没有必要这样做!"。
 
Slava:
先是有来自测试人员的关于同步、加载专家顾问 等与当地时间有关的信息,然后又有来自专家顾问和测试交易服务器与测试时间有关的信息,有时还穿插着来自测试人员与当地时间有关的信息,这样会不会让人感到震惊?

斯拉瓦,我一直在思考组织它的最佳方式。我想建议,应该先发送启动时间、同步等,然后再发送其他的--来自专家和测试人员的重要信息。

对我来说,听起来和你的建议一样 :)

 
fxsaber:
我找到了其中一个可以加速Tester的地方。事实证明,每次Tester比较两个价格(如BuyLimit和Tick.ask)时,都要通过昂贵的归一化来进行。没有必要这样做!"。

码头历史上的价格没有正常化!

bool IsNorm( const double Price )
{
  return(NormalizeDouble(Price, _Digits) == Price);
}

#define  TOSTRING(A) #A + " = " + DoubleToString(A, 16) + " "
#define  PRINT(A) Print(TOSTRING(A) + TOSTRING(NormalizeDouble(A, _Digits)))
#define  ISNORM(A) if (!IsNorm(A)) { PRINT(A); Count++; };

void OnStart()
{
  MqlTick Ticks[];
  
  const int Size = CopyTicksRange(_Symbol, Ticks, COPY_TICKS_ALL, 1000 * (long)D'2019.12.01');
  Print(Size);
  
  for (int i = 0, Count  = 0; (i < Size) && (Count < 10); i++)
  {
    ISNORM(Ticks[i].bid)
    ISNORM(Ticks[i].ask)
    ISNORM(Ticks[i].last)
  }
}


结果(欧元兑美元,MQ-Beta)。

Ticks[i].bid = 1.1024100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1024099999999999 
Ticks[i].bid = 1.1024100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1024099999999999 
Ticks[i].bid = 1.1024100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1024099999999999 
Ticks[i].bid = 1.1024100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1024099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 
Ticks[i].bid = 1.1023100000000001 NormalizeDouble(Ticks[i].bid,_Digits) = 1.1023099999999999 


这怎么可能呢?贸易服务器方面的错误?

因此,测试者甚至在真实符号上以歪曲的价格驱动EA。


看起来问题在于,开发者使用了不同的规范化算法

 
Andrey Khatimlianskii:

重现了直觉参数中出现空值的错误。

1.组装EA。

2.对任何两个参数进行优化。

3.取消选中enam,只优化x。

4.加载第1个优化缓存,然后是第2个优化缓存,从结果中运行一个单一的运行。我们得到的不是-1,而是INT_MAX


与所有以-1开头的枚举有关。

有一种怀疑是,当你取消勾选t时,输入就完全失效了。
而t变量包含一个未初始化的INT_MAX 值,而不是一个空值。

 
fxsaber:

码头历史上的价格没有正常化!


结果(欧元兑美元,MQ-Beta)。


这怎么可能呢?贸易服务器方面的错误?

因此,测试者甚至在真实符号上以歪曲的价格驱动EA。


听起来,问题在于开发者使用了不同的规范化算法

这些都不是歪门邪道的价格!他们是相当正常化的。从你的印刷品中可以很清楚地看到这一点

交易服务器在交易时总是使用一个epsilon来比较传入价格和当前价格。

你是否知道<某某实数>*0.5的结果可能与<相同实数>/2.0的结果不同?

你是否意识到有些编译器在优化代码时可能会用一种操作代替另一种操作?此外,在同一项目中,在一种情况下,它被替换,在另一种情况下,它没有被替换。没有宣战。

 
Roman:

有一种怀疑是,当你取消勾选t时,输入就完全失效了。
而t变量包含一个未初始化的INT_MAX 值,而不是一个空值。

里面的原因是什么并不重要。

重要的是,他们重现它并修复它。这个错误是旧的。

 
Slava:

这些都不是歪门邪道的价格!他们是相当正常化的。从你的印刷品中可以很清楚地看到这一点

只有当价格通过这个条件时,才会被正常化。

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

MetaTrader 5策略测试员:缺陷、缺陷、改进建议

fxsaber, 2019.12.11 07:47

bool IsNorm( const double Price )
{
  return(NormalizeDouble(Price, _Digits) == Price);
}

交易服务器在交易时总是使用epsilon来比较传入价格和当前价格。

贸易服务器正是这样做的,这是正确的。

你是否知道<某某实数>*0.5的结果可能与<同一实数>/2.0的结果不同?

你是否知道,有些编译器在优化代码时可以用一种操作代替另一种操作?此外,在同一个项目中,一种情况是替换,另一种情况是不替换。不宣而战。

两个问题的答案都是肯定的--我知道。


再一次,终端的原始价格没有被规范化。因此,这种情况很容易发生。

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

MT4中的非正常化价格

fxsaber, 2019.02.20 23:03

但情况要糟糕得多,在MQ-Demo上是这样的
// 15326434
// wmefo5sa
// MetaQuotes-Demo
void OnStart()
{
  const double Price1 = HistoryOrderSelect(356138100) ? HistoryOrderGetDouble(HistoryOrderGetTicket(0), ORDER_PRICE_CURRENT) : 0;
  const double Price2 = PositionSelectByTicket(356138100) ? PositionGetDouble(POSITION_PRICE_OPEN) : 0;  
  
  Print(Price1 - Price2); // -2.220446049250313e-16
}


当前仓位 的开盘价不等于其订单/交易的价格。