MetaTrader 5 Strategy Tester: バグ、不具合、改善のための提案 - ページ 34

 
Artyom Trishkin:

私も決して見ません。でも、便利な場所を取ってしまう...。

しかし、それは便利な ものでした。

 
Artyom Trishkin:

私も決して見ません。でも、便利な場所を取ってしまう...。

最初にExpert Advisorの 同期、ロードなどに関する テスターからのメッセージがローカルタイムで表示され、次にExpert Advisorとテスト取引サーバーからのメッセージがテストタイムで、時にはテスターからのメッセージがローカルタイムで挟まれても誰もショックを受けないのでしょうか。
 
テスターを加速できる場所を1つ発見。Testerが2つの価格(例えばBuyLimitとTick.ask)を比較するたびに、高価な正規化を介してそれを行うことが判明しました。そんなの必要ない!」。
 
Slava:
最初はローカルタイムでExpert Advisorの 同期やロードなどに関する テスターからのメッセージがあり、次にテストタイムでExpert Advisorやテスト取引サーバーからのメッセージがあり、時にはテスターからのローカルタイムでのメッセージが混在しても誰もショックを受けないのでしょうか?

スラバ 最適な編成を考えてみました。開始時間や同期などを先に送って、あとは-専門家やテスターから重要なメッセージを送るように提案したかったのです。

あなたが提案したのと同じように聞こえます :)

 
fxsaber:
Testerを高速化できる場所を一つ見つけました。Testerが2つの価格(例えば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)
  }
}


結果(EURUSD, 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 


なぜ、そんなことが可能なのか?トレードサーバー側のエラー?

その結果、Testerは実際のシンボル上でも不正な価格でEAを動かしている。


開発者が異なる正規化アルゴリズムを使用したことが問題の ようです。

 
Andrey Khatimlianskii:

intuのパラメータに空値がある不具合を再現しました。

1.EAを組み立てる。

2.両方のパラメーターのいずれかを最適化する。

3.enamのチェックをはずし、xだけを最適化する。

4.第1最適化キャッシュ、第2最適化キャッシュの順に読み込み、その結果から1回の実行を行う。1の代わりにINT_MAXが 表示されます。


1で始まるすべての列挙型に関連する。

tのチェックを外すと、入力が完全に無効になる疑いがある
で、t変数に空の値ではなく、初期化されていないINT_MAXの 値が含まれています。

 
fxsaber:

端末履歴の価格は正規化されていない!


結果(EURUSD, MQ-Beta)


なぜ、そんなことが可能なのか?トレードサーバー側のエラー?

その結果、Testerは実際のシンボル上でも不正な価格でEAを動かしている。


開発者が異なる正規化アルゴリズムを使用したことが問題の ようですね。

これは、決して不正な価格ではありませんかなりノーマライズされています。これは、あなたのプリントを見れば一目瞭然です

トレードサーバーは、取引時に常にイプシロンで着信価格と現在価格を比較します。

<some_real_number>*0.5と<the_same_real_number>2.0の結果が異なる場合があることをご存知でしょうか。

コンパイラによっては、コードを最適化する際に、ある操作を別の操作に置き換えることがあることをご存知でしょうか?しかも、同じプロジェクトの中で、入れ替わるケースと入れ替わらないケースがある。宣戦布告をせずに

 
Roman:

tのチェックを外すと、入力が完全に無効になる疑いがある
で、t変数に空の値ではなく、初期化されていないINT_MAXの 値が含まれています。

中身がどうであるかは重要ではありません。

重要なのは、それを再現し、修正することです。バグが古い。

 
Slava:

これは、決して不正な価格ではありませんかなりノーマライズされています。これは、あなたのプリントを見れば一目瞭然です

この条件をクリアした場合のみ、価格が正規化される。

トレードサーバーは、取引時に常にイプシロンを使用して、入力された価格と現在の価格を比較します。

トレードサーバーがまさにそうであることは正しい。

<some_real_number>*0.5と<the_same_real_number>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
}


現在のポジションの 始値が、その注文・取引の価格と一致しない。