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

 
Stanislav Korotky #:

将来を先読みすることはありません。なぜなら、時刻 X において複数のシンボルにティックが存在する場合、いずれかの銘柄で最初のイベントが発生すると、残りのシンボル(イベントがまだキューにあるもの)には、次のティックではなく、前のティックが表示されることになるからです (例のように、00:04は00:05の前であり、後ではない)。

同期を図るには、コード内でアルゴリズム的に確保する必要があります。例えば、OnTickハンドラ内で、取引を開始する前に、関与するすべての銘柄のティック時刻を取得するなどです。 しかし、原則として、もしアービトラージがティック単位(バーや分単位ではなく)で行われる場合、特定の銘柄ではティックが実際に数秒間欠落することがあるため、信頼性の高い同期を実現することは困難です。

すべては相対的なもので、ある銘柄では遅れが生じ、別の銘柄では先行してしまうことがあります。

そこではすべてが不安定で、デバッガー上ではすべて同期しており、OnTickがほぼ空の状態でも同様です。

テストでは、手数料やスプレッドを正しくシミュレートするために、バーをティック単位で記述せざるを得ません。

カスタムテスターの計算結果がMTと一致するように、これをOnTick内で実行せざるを得ませんでした。

   int size=ArraySize(T);
   if(size==0) return;
   datetime dt1=(datetime)SymbolInfoInteger(name1,SYMBOL_TIME);
   datetime dt2=(datetime)SymbolInfoInteger(name2,SYMBOL_TIME);
   while(sh1<size && T[sh1]<dt1) sh1++;
   while(sh2<size && T[sh2]<dt2) sh2++;
   while(sh1<size && T[sh1]==dt1)
     {if(D1[sh1]>0)  Buy(name1);
      if(D1[sh1]<0) Sell(name1);
      if(D1[sh1]==0) Close(name1);
      sh1++;
     }
   while(sh2<size && T[sh2]==dt2)
     {if(D2[sh2]>0)  Buy(name2,D2[sh2]);
      if(D2[sh2]<0) Sell(name2,fabs(D2[sh2]));
      if(D2[sh2]==0) Close(name2);
      sh2++;
     }
 
Stanislav Korotky #:

同期を行うには、コード内でアルゴリズム的にその仕組みを実装する必要があります。例えば、OnTickハンドラ内で、取引を開始する前に、関与するすべての銘柄のティック時間を照会するなどです。

残念ながら、これではOnTick内で、現在の時刻に対応するティックの列が終了したことを把握できないでしょう。おそらく、ミリ秒単位のOnTimerを使用するしか方法はないでしょう。

 
Rorschach #:

すべては相対的なもので、ある楽器にとっては遅れとなり、別の楽器にとっては先行となる。

(テスターの)現在時刻が存在する場合、それに対してのみ「未来を先読みする」という用語を使用することができる。 現在の時刻をXとし、2つの銘柄についてそれぞれ時刻X-1とX-2のティックデータが存在する場合、それらは最後に判明した最新のティックデータであり、アルゴリズムによる計算にはそれらを用いる必要がある。 もし、時刻X-2の時点で誰かがX-1およびXのティックを計算しようとした場合、それは未来への先読みとなります。しかし、技術的にはテスターはそれを許しません。
 
fxsaber #:

残念ながら、これではOnTickが現在の時刻に対応するティックのキューが終了したことを認識できないと思います。おそらく、ミリ秒単位のOnTimerしか解決策にはならないでしょう。

これは、if文の条件を時間に基づいてどのように記述するかによります。厳密な「>」を使用し、「>=」は避け、条件を満たした原因となったティックはカウントに含めないようにする必要があります。タイマーを使用する場合も同様です。
 
Stanislav Korotky #:
if文の条件を時間に基づいて記述する方法次第ですが、厳密な「>」を使用し、「>=」は使わないようにし、条件を満たすきっかけとなったティックは計算に含めないようにする必要があります。
よくわかりません。
 
Stanislav Korotky #:
タイマーを使えば、同じようにできる。
そちらの方が簡単です
 
fxsaber #:
よく分かりませんでした。

ざっと考えてみると、ミリ秒単位(秒単位も同様)の精度での時刻の特定については:

// TODO: ArrayResize(lookback, <シンボル数>)
MqlTick lookback[];

void OnTickMulti(const string &symbol, const uint &index)
{
   static MqlTick t[1];
   static long timeCurrentMsc;
   
   SymbolInfoTick(symbol, t[0]);
   
   if(t[0].time_msc > timeCurrentMsc)
   {
      if(!timeCurrentMsc) // まだ最初ではないので、これは新しいミリ秒です
      {
         // TODO: 分析および取引に lookback[] ticks を使用する
         // これらはまだ現在のティックを含んでいません。これは、次のミリ秒からのものだからです。
         // ...
      }
      timeCurrentMsc = t[0].time_msc;
   }

   // 分析完了後にのみ、レジストリを新しいタイムスタンプで更新する
   lookback[index] = t[0];
}

しかし(Rorschachさんに向けて)改めて繰り返しますが、これほど微細な間隔での同期は幻想に過ぎません。ある銘柄のティックが数秒間欠けることもあり、その場合、その銘柄のリアルタイム価格は実際には「古くなっている」可能性があります。 もし、すべての価格が同じ[ミリ]秒の時点のものであることが重要である場合は、上記のコード断片(コメントアウトされた分析ブロック)において、ティック時刻の等価性を追加で確認し、この条件が満たされている場合にのみ取引を行う必要があります。

 
Stanislav Korotky #:

ざっと言えば、ミリ秒単位の精度で時刻を特定する場合(秒単位の場合も同様):

この方法では、すべてのシンボルのティックの最新性を保証することはできません。ミリ秒単位の OnTimer を使用する場合にのみ可能です。
 
fxsaber #:
この方法では、すべての銘柄のティックの最新性を保証することはできません。ミリ秒単位のOnTimerを使用する場合にのみ可能です。
「最新性」とは具体的に何を指すのでしょうか(このメソッドはすべての銘柄について、最後に確認されたティックを返すだけですが、もしそれが意図されているのであれば、CopyTicksを使用することも可能です)。また、OnTimerを使用することで、どのように異なる結果が得られるのでしょうか?
 

Stanislav Korotky #:
Что подразумевается под актуальностью (этот метод отдает последние известные тики по всем инструментам)?

「最終確認時刻」のティッカーは表示されなくなります。

では、OnTimerはどのようにして異なる結果をもたらすのでしょうか?

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