ライブラリ: オンティック・マルチ - ページ 4

 
fxsaber #:

「最終確認時刻」によるティックは今後発生しなくなります。

ミリ秒単位のOnTimerは、このタイマーイベントの前にすべてのティックが経過していることを保証します。つまり、すべてのシンボルにおいて、ティックは最新の状態です。

もし、スパイインジケーターが何らかの技術的な理由で「古い」ティックを遅延させ、別の銘柄のより新しいティックよりも後に送信してしまう可能性がある、というのであれば、それは起こり得るでしょう。それ以外であれば、コード自体に直接的な問題はないと思います。

このタイマーが、新しい「イベント」(時間単位のカウントダウン)の前にすべてのティックが経過したことを、それ以上に保証しているとは思いません。 タイマーはローカル時間で動作しますが、ティックに含まれるタイムスタンプはサーバー時間を表しています。そのため、ツール間の同期にはタイマーに頼らない方が良いでしょう。

 
Stanislav Korotky #:

そうですね、同期の複雑さを考えると、ティックに関してはこれで許容範囲でしょう。とはいえ、ミリ秒単位のタイムフレームを設定して、ティックのタイミングを調整することも可能です。

しかし、始値についても同様の現象が見られます。すべての銘柄で始値の時刻は同じであるにもかかわらずです。

そして、このような挙動のせいで、一部のシステムは正常にテストすることができません。

 

問題の再現例。

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> //https://www.mql5.com/ja/code/47647

#include <MT4Orders.mqh> //https://www.mql5.com/ja/code/16006

input bool inTimer = false; // false - OnTick、true - OnTimer

ulong TimeMsc = TimeTradeServer() * 1000 + (inTimer && EventSetMillisecondTimer(1));

void PositionOpen()
{
  for (uint i = ArraySize(OnTickMultiObject.Symbols); (bool)i--;)
  {
    const string SymbName = OnTickMultiObject.Symbols[i];
    
    OrderSend(SymbName, OP_BUY, 1, SymbolInfoDouble(SymbName, SYMBOL_ASK), 0, 0, 0);
  }
}

void OnTimer()
{
  if (TimeMsc++ == 1759280400081) // 2025年10月1日 01:00:00.081
    PositionOpen();
}

// マルチシンボルのOnTick。
void OnTickMulti( const string &Symb, const uint &Index )
{  
  MqlTick Tick;
  
  if (!inTimer && SymbolInfoTick(Symb, Tick) && (Tick.time_msc == 1759280400081) && // 2025年10月1日 01:00:00.081
      !OrdersTotal())
    PositionOpen();
}

スクリーンショットには、MetaQuotes-Demo で再現するためのすべてのデータが示されています。OnTick経由ではティックが同期されていないのに対し、OnTimer(非常に動作が重い)経由では同期されていることがはっきりと分かります。

 
fxsaber #:

OnTick 経由ではティックは同期されませんが、OnTimer 経由(ひどく動作が重くなる) では同期されます。

どうやら、同期モードでの計算を高速化する唯一の方法は、EAToMathのような 数学モードを使うことらしい。


あるいは、この1回のスキャンデータをあらかじめファイルに書き留めておく方法もあります。

#include <fxsaber\OnTickMulti\OnTickMulti.mqh> //https://www.mql5.com/ja/code/47647

// マルチシンボルのOnTick。
void OnTickMulti( const string &Symb, const uint &Index )
{  
  static MqlTick Ticks[];
  static const int Size = ArrayResize(Ticks, ArraySize(OnTickMultiObject.Symbols));  
  
  bool Res = SymbolInfoTick(Symb, Ticks[Index]);

  for (int i = 1; Res && (i < Size); i++)
    Res = (Ticks[i].time_msc == Ticks[i - 1].time_msc);
    
  if (Res)
    ArrayPrint(Ticks);  
}
2025.10.01 01:00:00                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 01:00:00   [0] 2025.10.01 01:00:00 1.17345 1.17363 0.0000        0 1759280400081     134       0.00000
2025.10.01 01:00:00   [1] 2025.10.01 01:00:00 1.34417 1.34501 0.0000        0 1759280400081     134       0.00000
2025.10.01 01:00:00   [2] 2025.10.01 01:00:00 0.66103 0.66122 0.0000        0 1759280400081     134       0.00000
2025.10.01 06:07:02                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 06:07:02   [0] 2025.10.01 06:07:02 1.17388 1.17390 0.0000        0 1759298822726     134       0.00000
2025.10.01 06:07:02   [1] 2025.10.01 06:07:02 1.34417 1.34422 0.0000        0 1759298822726     130       0.00000
2025.10.01 06:07:02   [2] 2025.10.01 06:07:02 0.65959 0.65967 0.0000        0 1759298822726     134       0.00000
2025.10.01 07:30:23                    [time]   [bid]   [ask] [last] [volume]    [time_msc] [flags] [volume_real]
2025.10.01 07:30:23   [0] 2025.10.01 07:30:23 1.17467 1.17469 0.0000        0 1759303823965       4       0.00000
2025.10.01 07:30:23   [1] 2025.10.01 07:30:23 1.34486 1.34490 0.0000        0 1759303823965     134       0.00000
2025.10.01 07:30:23   [2] 2025.10.01 07:30:23 0.65970 0.65978 0.0000        0 1759303823965       4       0.00000

そして、自身のアドバイザー内で、このファイルのデータを使用してOnTickでの同期を行う。そうすれば、高速かつ正確に動作するだろう。

Подробнее о способах ускорения оптимизации советников в MT5.
Подробнее о способах ускорения оптимизации советников в MT5.
  • 2025.09.02
  • www.mql5.com
Классификация советников. Все советники, запускаемые в Оптимизаторе, делятся на два типа. Торговые. Статистические: "обучение", обработка котировочных данных. Каждый из них тоже делится на два типа
 
fxsaber #:

問題の提示。

スクリーンショットには、MetaQuotes-Demo で再現するためのすべてのデータが示されています。OnTickを使用するとティックが同期されていないのに対し、OnTimer(非常に動作が重い)を使用すると同期されていることがはっきりとわかります。

さて、あなたは「==」を用いたエントリー条件を含むコードを使用しています。前述の通り、条件は「>」で厳密に比較する必要があり、「=」は使用してはいけません。 2025年10月1日 01:00:00.081までに判明している最新価格に基づいて、すべての銘柄で同期した取引を行うためには、その時刻より前にティックの監視を開始する必要があります。つまり、デモ用の定数として、 例えば、>1759280400080を デモ用の定として 設定する必要があります。アルゴリズムごとにロジックを修正する必要があり、単に処理タイプの1つを別のものに置き換えるだけではうまくいきません。

PS. ここで言う「同期」とは、最新の既知の価格に基づく取引を意味します。 ミリ秒単位での同期を実現するには、もちろん追加のチェックが必要ですが、そのような状況(異なる銘柄のティックのミリ秒が一致する)が発生する確率は低く、結果として潜在的なシグナルを見逃すことになりかねません。このような同期に実用的な価値があるかどうかは定かではありません。

 
Stanislav Korotky #:

2025年10月1日 01:00:00までに判明している最新価格に基づいて同期取引を行うには。081、すべての銘柄において、この時刻までにティックのモニタリングを開始する必要があります。つまり、例えば >1759280400080 のような値をデモ用の定数として設定してください。

コードでの実装例を拝見させていただきます。
 

同期を行う最も簡単な方法は、使用されるシンボルのティック時間から集合を作成することです。

実行中に、1回のパスで同期を行うのは困難です。

その難しさは、遅れが不確定である点にあります。どのシンボルがマスターとなるかは不明です。

 
fxsaber #:
コードであなたの案を見てみたいと思います。

本格的なテストケースを作成するためには、実際の課題を理解したいのですが――ミリ秒単位の精度で時間が一致したティックのみを基に取引を行う、ということでしょうか?

あらかじめ既知のタイミングで、すべての銘柄でティックが同期しているという、たった1回の取引という人工的な例の場合、人工的な最適アルゴリズムを考案することは可能ですが、それには何の意味があるのでしょうか?

 
Rorschach #:

でも、始値はどの銘柄も同じなのに、すべての銘柄の始値は同じ時刻なのに。

課題を明確にする必要があります。始値について、アルゴリズムが全銘柄のバーの存在を要求する場合、全銘柄のiTime(,,0)が一致するのを待ちます。 このアプローチでは、バー(M1であっても)が存在しないことはめったにないため、通常は論理的な問題はありません。しかし、秒単位やそれより細かい時間単位では、同期のずれが頻繁に発生する可能性があります。そのような場合、どうすればよいでしょうか?

私は、実際には、同期の基準として、ティックタイムスタンプの厳密な一致ではなく、所定のタイムアウト以内の任意の価格が存在することを考慮すべきだと考えています。

 
Stanislav Korotky #:

課題を明確にする必要があります。 始値について、アルゴリズムが全銘柄のバーの存在を必要とする場合、全銘柄のiTime(,,0)が一致するのを待ちます。このアプローチでは、バー(M1であっても)が存在しないことはめったにないため、通常、論理的な問題はありません。

ここでいうのは、始値に基づくテスターモードのことです。

Stanislav Korotky#:
秒単位やそれより細かい時間間隔では、同期のずれが頻繁に発生する可能性があります。そのような場合、どうすればよいでしょうか?

最後に確認された値を適用する。