[SERVICE DESK】タイマーでシニアTFの時刻を取得する際にエラーが発生!? - ページ 7

 
Ihor Herasko:

はい、その通りです。OnInit()では、結果を確認せずに必要なTFを単純に呼び出し(そこでは当てにならない)、OnCalculateでは、関数IsTFDataReady()を呼び出すのです。要求されたすべてのTFに対してtrueが返されたら、インジケーターのアルゴリズムの実行を開始することができます。

なるほど、整理がつきましたね。しかし、明確にドキュメントを追加しなければ、高速タイマーは開発者に多くの疑問を抱かせることになります。

 
Ihor Herasko:

一般に、端末の接続の 有無が重要視されるのは、どのような問題を解決するためでしょうか。私の理解では、インジケータはデータを視覚化するためのツールです。というデータがあります。新しいデータが届くと、ビジュアライゼーションが更新されます。データが最新であるかどうかの確認は必要ないはずです。これが端末の仕事です。

課題は、先輩TFのデータをいち早く入手すること。Vitaly Gorbunovが IsConnected()について思い出させてくれた。

 
Alexey Kozitsyn:

おいおい...すでにその時期は過ぎています。ご自身のログをご覧ください。

シーケンスです。まず、接続を確認します。接続が確立されると、時刻を取得する。なぜ最初にエラー4066が返され、その後返されないのか、説明してくれ!?前回の呼び出しから20msの間に何が変わったのか?

エラー 4066 データがありません、更新要求が送信されましたと表示されます。

リクエストが送信されると、もう別のリクエストは送信されないので、4066エラーは発生しない。これはすでに何度も議論されてきたことです。

なぜ、インジケーターでタイマーを起動するのですか?こんなに小さいんですね。MT4では、インジケータはインターフェーススレッドで実行されることを理解する必要があります。インターフェーススレッドには、すべてのウィンドメッセージが入ります。

 
Slava:

エラー4066は、データがない、更新要求が送信されたことを示します。

一度送信したリクエストはもう送信されないので、エラー4066は発生しない。これはすでに何度も議論されてきたことです。

なぜ、インジケーターでタイマーを起動するのですか?こんなに小さいんですね。MT4では、インジケータはインターフェイスのスレッドで動作することを理解する必要があります。風のメッセージはすべてインターフェイススレッドを経由する

議論に加わってくれてうれしいです。

フォーラムでの初日ではない+何人かの方がここにコメントされていますが、その方もフォーラムでの初日ではないです。については、誰も何も言っていない。

一度送信したリクエストはもう送信されないので、4066エラーは発生しない。これはすでに何度も議論されてきたことです。

ありがとうございます、わかります。ぜひ、ヘルプに掲載してほしい。ということは、きっとOnTick()/OnCalculate()イベントが発生したときだけ、エラーが「発生」するのでしょうか。

なぜ、インジケーターでタイマーを起動するのですか?こんなに小さいんですね。

数文字からデータを取得する必要があります。できるだけ早く残念ながら、MT4もMT5もシンボルのクォート到着のイベントを受信する機能を備えていません(そのような更新を購読することは不可能です)。したがって、(私の知る限り)唯一の方法は、タイマーで必要なシンボルを照会することです。

MT4では、インジケータはインターフェイスのスレッドで動作することを理解する必要があります。風のメッセージはすべてインターフェイススレッドを経由する

よし、来るぞ、でもそれからどうするんだ?これが悪い/良い/タイマーの動作にどう影響するのか、詳しく教えてください。
 

何度も議論されてきたことです。1リクエスト12ページ「エラー4066」。

また、OnInitでリクエストを送信し、OnCalculateで分析するというのは正しいアドバイスでした。

ミリ秒タイマーは 何のために必要なのでしょうか?クライアント端末の正常な起動を妨げています。風のメッセージが邪魔をするのではなく、自分のタイマーがみんなの邪魔をするんです。もう一度:クライアントのMT4ターミナルのインジケータは、インターフェイスポテンシャルで動作します。

 
Slava:

何度も議論されてきたことです。エラー4066」についての12ページ。

読んでみてください、ありがとうございます。OnCalculate()やOnTick()での動作にのみ問題があり、OnTimer()での動作に問題があります。そして、"error 4066 timer "のリクエストでは、このブランチからしか結果が得られませんでした :(

そして、OnInitでリクエストを送り、OnCalculateで解析するというのが正しいアドバイスでしたね。

アドバイスを聞きましたが、ドキュメントに書かれていないタイマーの扱いの特殊性は変わりません。

なぜミリ秒タイマーが必要なのですか?あなたの行為によって、クライアント端末の正常な立ち上がりを妨げているのです。風のメッセージが邪魔をするのではなく、あなたのタイマーがみんなのタイマーを邪魔しているのです。もう一度:クライアントのMT4ターミナルのインジケータは、インターフェイスポケットで動作しています。

もう一度言いますが、ミリ秒タイマーは、複数のシンボルからできるだけ早く情報を取得するためのものですすなわち、インジケータをロードし、できるだけ早く高いTFのデータを取得し、ミリ秒タイマーで必要なシンボルのビットを監視する、というアルゴリズムです。タイマーを使用する以外に、モニタリングの問題を解決する方法はありますか?

ここに書かれていることをすべて要約して みましょう。間違っていたら訂正してください。

1.タスク:タイマーで複数のシンボルの見積もりを取る。

実装:高頻度タイマーを扱う場合、ターミナル読み込み時のOnCalculate()でサーバーとのIsConnected()が確立するのを待つ必要があり、その場合にのみタイマーにアクセスできるようになります。

2.目的:インディケータ起動後、できるだけ早く上位TFのデータを取得する(インディケータはファストタイマーを使用しています)。

実装:まずOnInit()で必要なデータを要求し、OnCalculate()で接続のIsConnected()を待ち、OnCalculate()で上位TFのデータも取得する。

3.高周波タイマーを起動すると、インターフェイススレッド、ひいてはコンピュータの動作が遅くなり、全く起動しない方が良いのでしょうか?では、課題1をどう解決するか。

4.目的:古いTFの実データをロードする。

実装:データ検索機能がそのようなタイマーで動作するように設計されていないため、このために高周波タイマーを使用しないでください?OnCalculate()のみを使用するのですか?

5.エラー4066を受信してリセットされた場合、OnCalculate()は毎ティックでアームするのでしょうか?

6.MT5のOnTimer()はインターフェイススレッドでは動作しないのでしょうか?

スラバも 一点一点お答えください。

 

1.通常、OnCalculate の 2 回目の呼び出しで IsConnected 状態になります。端末起動直後に1回目の呼び出し、履歴データ到着時に2回目の呼び出し

2.ファストタイマーは使用しないでください。まず、どのようなタイミングなら受け入れられるかを見極める。100ミリ秒かもしれないし、500ミリ秒かもしれない。もともと秒タイマーを導入したのは偶然ではなく、SetMillisecondsTimerはそのわずか3、4年後に5つ(!)導入されたのです。しかし、アーキテクチャが5つも違うのです。

3.1 インスタントメッセージのキューを処理できる強力なコンピュータを入手する。

3.2 ミリ秒タイマーをすぐに起動せず、少なくとも最初のOnCalculateの後に起動する。というか、最初のOnCalculateで、環境を分析できるように、2番目のタイマーを開始します(接続がない場合や休みの日の場合)。そして、すべてのデータが読み込まれ、接続があり、すべてがOKであることを確認したら、秒タイマーを殺し、ミリ秒タイマーをスタートさせる。 そうすれば、狭い玄関を無事にスキップすることができるのだ。最高のシナリオでは(99%の確率で)、スタート時に2秒から5秒のロスが発生します。

4.タイマーが可能です。しかし、すぐにではありません(3.2参照)。そして、50ミリ秒でも十分だと思います。HFTを提供しているわけではないんですよね?

5.4066は他人の期間限定キャラのデータを最初に要求した時だけ表示される。同じ文字期間の次のリクエストでは、4066はそれ以上取得できません。

6.MT5では、インジケータは別のシンボル処理スレッドでカウントされます。そのため、このシンボルに複数のチャートがある場合(またはこのシンボルに他のインジケータがある場合)、それらを遅くすることができます。しかし、それでもインターフェイスのスレッドではありません

 
Slava:

1.通常、OnCalculate の 2 回目の呼び出しで IsConnected 状態になります。端末起動直後に1回目の呼び出し、履歴データ到着時に2回目の呼び出し

2.ファストタイマーは使用しないでください。まず、どのようなタイミングなら受け入れられるかを見極める。100ミリ秒かもしれないし、500ミリ秒かもしれない。もともと秒タイマーを導入したのは偶然ではなく、SetMillisecondsTimerはそのわずか3、4年後に5つ(!)導入されたのです。しかし、アーキテクチャが5つも違うのです。

3.1 インスタントメッセージのキューを処理できる強力なコンピュータを入手する。

3.2 ミリ秒タイマーをすぐに起動せず、少なくとも最初のOnCalculateの後に起動する。というか、最初のOnCalculateで、環境を分析できるように、2番目のタイマーを開始します(接続がない場合や休みの日はどうするか)。そして、すべてのデータが読み込まれ、接続が確立し、問題がないことを確認したら、秒タイマーを止め、ミリ秒タイマーをスタートさせます。 そうすれば、狭い玄関を無事に通り抜けることができます。最高のシナリオでは(99%の確率で)、スタート時に2秒から5秒のロスが発生します。

4.タイマーが可能です。しかし、すぐにではありません(3.2参照)。そして、50ミリ秒でも十分だと思います。HFTを提供しているわけではないんですよね?

5.4066は他人の期間限定キャラのデータを最初に要求した時だけ表示される。同じ期間のキャラクターに対する次のリクエストでは、再び4066を取得することはありません。

6.MT5では、インジケータは別のシンボル処理スレッドでカウントされます。そのため、このシンボルに複数のチャートがある場合(またはこのシンボルに他のインジケータがある場合)、それらを遅くすることができます。しかし、それでもインターフェイスのスレッドではありません

1.まさにその通りです。

2.ここが問題なのです。速ければ速いほどいい。そして、その評価が下された。このインディケータは裁定取引(というより裁定取引の研究)のために書かれたもので、つまり1ミリ秒単位が重要で、気配値をより速く受信するほど良いのです。

3.1.そして今、CPU8600k、SSD端子、16gb DDR4 RAMと、かなり強力なシステムになっています。

3.2.ワオ...OK、メモしました。

4.仲裁タスクは、HFTに関連する可能性が高い。

5.当初は、このことがストレスになっていました。もし、エラーが出続けて、データがまだできていないことが分かっていたら、このスレッドはなかったでしょう。

6.なるほど。

精緻な対応に感謝します。

 
Igor Makanu:

それはあまりにも多くのトラブルではない場合、ここでトピックのトピックです - 古いTFから正しい歴史のロードは、ここでインジケータです: "私は若いTFのバー上の古いTFから "MAを描画する必要があります、私は5分以内にそれをやった、それは98%のために正しく動作します、ここでこのコード2%の "落とし穴 "でバグが発生するのだろうか。

はい、あくまで話題の件ですが。そして、それはすべてここで整理されます。

まず、他のTF/シンボルの時系列を参照する前に、必ずデータが利用可能であることを確認してください(上記のIsTFDataReady()関数を参照)。上記のコードでは、CopyCloseの結果のみが案内されます。しかし、それは歴史のロードについて何も知らない。ですから、まず、データが利用可能であることを確認し、それから要求するのです。

第二に、ある関数を別の関数の引数として呼び出すことは、必ずしも正当化されない。また、上記の場合、原則的に受け入れられません。やはり、iBarsを呼び出した結果も確認する必要があります。そこで、まずiBarsが呼ばれ、その結果をキャッシュしてチェックし、受け取った値だけをCopyClose()に転送しています。

第三に、 CopyCloseの呼び出しの 後、要求されたすべてのデータを取得するためのチェックがないことである。結局、この関数は1本か2本のバーを返すことができ、例えば10本と要求されたのです。そのような結果は、エラーと考えます。

第四に、アプローチの考え方そのものに間違いがある。ループは別のTFのバーで操作することを想定していますが、値が現在のTFを参照している変数rates_totalと計算が混同しています。ここで、2つのアプローチが考えられ、私はこのケースとこのケースで使い分けをしています。

  1. 現在のTFのバーをループし、データ要求の前に現在のTFのバーのインデックスを別のTFのバーインデックスに変換すること(この方法は以下のコードで使用されています)。
  2. 他のTFのバーを循環させる。しかし、その場合、現在のTFがもう一方のTFの後輩である場合のために、追加のループを入れる必要があります。なぜなら、古いTFの1本のバーが、現在のTFの数本のバーに対応することになるからです。

MT4用の正しいコードに興味があります。

この4つのポイントに照らし合わせると、次のようになるはずだ(チェックはしていない、手書きでやったが、感覚的には分かるはずだ)。

   if (!IsTFDataReady(TimeFrame))
      return 0;

   int i,limit;

   static int nOldBars = 0;
   int nBars = iBars(_Symbol, TimeFrame);
   if (nBars == 0)
      return 0;
      
   if (nOldBars == 0 || nBars - nOldBars > 1)
   {
      if(nBars < MAPeriod)
      {
         Comment("Большой период МА!!!, в истории доступно ", nBars," баров");
         return 0;
      }
      
      limit = nBars - fmin(MAPeriod, nBars);
   }
   else
      limit = nBars - nOldBars;  // здесь всегда будет 0 или 1
   
   nOldBars = nBars;
   datetime dtTime = iTime(NULL, TimeFrame, limit);
   if (dtTime == 0)
      return 0;

   limit = iBarShift(NULL, PERIOD_CURRENT, dtTime);

// основной цикл расчета индикатора
   for(i = limit; i >= 0 && !IsStopped(); i--)
   {
      int nOtherTFBarIndex = iBarShift(NULL, TimeFrame, time[i]);
      if (nOtherTFBarIndex < 0 || nOtherTFBarIndex >= nBars)
         continue;
      
      BufMA[i] = iMA(_Symbol,TimeFrame,MAPeriod,0,MODE_SMA,PRICE_CLOSE,nOtherTFBarIndex);
   }
//---
   return rates_total;

ちなみに、私は確認しました。


 
Ihor Herasko:

はい、それがこのスレッドのトピックです。そして、それはもうここに集約されているのです。

まず、他のTF/シンボル・タイムシリーズを参照する前に、データが利用可能であることを確認します(上記のIsTFDataReady()関数を参照してください)。上記のコードでは、CopyCloseの結果のみが案内されます。しかし、それは歴史のロードについて何も知らない。ですから、まず、データが利用可能であることを確認し、それから要求するのです。

第二に、ある関数を別の関数の引数として呼び出すことは、必ずしも正当化されない。また、上記の場合、原則的に受け入れられません。やはり、iBarsを呼び出した結果も確認する必要があります。そこで、まずiBarsが呼ばれ、その結果をキャッシュしてチェックし、受け取った値だけをCopyClose()に転送しています。

第三に、 CopyCloseの呼び出しの 後、要求されたすべてのデータを取得するためのチェックがないことである。結局、この関数は1本か2本のバーを返すことができ、例えば10本と要求されたのです。そのような結果は、エラーと考えます。

第四に、アプローチの考え方そのものに間違いがある。ループは別のTFのバーで操作することを想定していますが、値が現在のTFを参照している変数rates_totalと計算が混同しています。ここで、2つのアプローチが考えられ、私はこのケースとこのケースで使い分けをしています。

  1. 現在のTFのバーをループし、データ要求の前に現在のTFのバーのインデックスを別のTFのバーインデックスに変換すること(この方法は以下のコードで使用されています)。
  2. 他のTFのバーを循環させる。しかし、その場合、現在のTFがもう一方のTFの後輩である場合のために、追加のループを入れる必要があります。結局のところ、古いTFの1バーは、現在のTFの数バーに対応することになります。

これら4つのポイントに照らし合わせると、こうなるはずです(チェックはしていません、手探りでやっていますが、感覚的には分かるはずです)。

ちなみに、私は確認しました。


1.手に取った! ありがとうございます。

2.金言!以前はそう書いていたのですが、時間とともに、コンパクトさを追い求めている他の人のコードを読むと......。私は「簡潔は才能の妹」......にもっと注意を払い、遭遇したバグを探すのに時間を費やしています。

4."簡潔は才能の姉妹"...その通りです!

3. 解析の興味深い点は、CopyClose()が何を返すかです。私は自分でチェックしましたが、要求されたTFの.hst ファイルがない場合、CopyClose()は2048 以上を返しません。