インジケータが破損する - ページ 6

 
Rosh:
OK、待ちます。

20時間以上経過しても、インジケーターが正常に動作している。なんて言っていいのかわからない。


 

ロッシュ、ズームイン/アウト、左右スクロール。64/32bitのどのプラットフォームでテストしていますか?

 
AnkaSoftware:

ロッシュ、ズームイン/アウト、左右スクロール。64/32ビットでテストしているのはどのプラットフォームですか?

私は32ビットで一般的な問題を再現することができます。O/Sが関係していると思われる唯一の方法は、あなたの32ビットシステム(およびRaptorUKの64ビットシステム)がそうでないのに対し、あなたの64ビットシステムが定期的に バー履歴の開始時または途中で新しいデータを取得して いるように見えるのはなぜかという問題です。とにかく、あなたは自分のインジケータを他の人に提供するつもりであるようですし、バー履歴の変更は、あなたのユーザーがブローカーの切断に苦しみ、再接続時に履歴の真ん中に欠けているバーが挿入されるという理由だけでも、その後必ず実生活で遭遇する問題なのです。

すでに説明したように、この「バグ」があなたのコードにあるのか、MT4にあるのかは議論の余地があります。MT4では、インジケータがどのように動作するかという予想があり、あなたのインジケータはそのように動作しません。例えば、MetaEditorを使って新しいインディケータを作成すると、「int counted_bars=IndicatorCounted();」という行が挿入されます。これを削除してIndicatorCounted()を無視しているのです。

私は以下のインジケータを使用して一般的な問題を再現することができます。

#property indicator_chart_window
#property indicator_color1 Red
#property indicator_buffers 1

double indicatorvalues[];

void init()
{
   SetIndexBuffer(0, indicatorvalues);
}

void start()
{
   static bool IsFirstCall = true;
   if (IsFirstCall) {
      IsFirstCall = false;
      for (int i = 0; i < 10; i++) {
         indicatorvalues[i] = High[i];      
      }
   }
}

次に、次のようにすると同じような問題を再現することができます。

* 任意のシンボルのチャートを開く。

* チャートにインジケータを追加する。

* チャートの自動スクロールをオフにする(次のステップを簡単にするため。)

* ホームボタンを押し、チャートの最初に移動します。

* ページアップを押して、余分なデータを強制的にダウンロードする。(注:この時点で実際に余分なデータがチャートに追加されていなければ問題はありません。) * チャートの最後に移動します。

* Endを押して、チャートの最後尾に移動します。高値の間の赤い線の位置がずれているはずです。それは時間的に後方に移動したことになります。

[これらはすべて、RaptorUKがすでに特定したものに肉付けしているだけです]

 

OK、IndicatorCounted()が-veを返すことを確認できますか、この場合、バーがない/インジケータが破損しているのでしょうか? インジケータ配列を再初期化し、ルックバックバーから動きを再描画してみます

 
AnkaSoftware:

OK、IndicatorCounted()が-veを返すことを確認できますか、この場合、バーがない/インジケータが破損している?

いいえ、何が起こるかというと、5ページですでに述べたように、そしてあなた自身で簡単にテストできるように、MT4は、上記のような方法を使用して、新しいバーが履歴の最初に追加されると、IndicatorCounted()をゼロにリセットするのです。これは、通常のインジケータが履歴値をすべて再描画する原因となります。なぜなら、インジケータは通常、BarsとIndicatorCounted()の差を使用して、どのバーが「汚れていて」更新が必要かを判断するためです。IndicatorCounted()がゼロの場合、インディケータは、したがって、すべての履歴バーを再計算します。

IndicatorCounted()のドキュメント(https://docs.mql4.com/customind/IndicatorCounted) は、これを行う一つの例を提供しています。また、https://www.mql5.com/en/forum/132447 のような代替バージョンもあり、https://docs.mql4.com/customind/IndicatorCounted の標準コードは、不必要に「クリーン」である一つのバーを再計算するので、ごくわずかな性能向上を目的としています。
 

IndicatorCounted()のチェックを追加し、IndicatorCounted()が値0を返したときにインジケータを再初期化することで、ヒストリーや追加バーが 挿入されたときに発生するインジケータの移動の問題を解決することができます。

しかし、ヒストリーバーの挿入には関係ないと思われる、インジケータの破損という別の問題が発生しています。同封のサンプルコードでこの問題を再現するためには、IndicatorCounted()が0を返す(インディケータ開始後)インディケータを少なくとも2回再初期化するまで、10数時間実行する必要があります。

ファイル: