インジケータ導入時と稼動時の表示が違う

スポンサーリンク

こんにちは。キリンです。
タイトルの件、巷に出回ってるインジケータによくある現象ですよね。

インジケータ導入時はちゃんとサインが出るのに….
・稼動し続けてると表示しなくなる
・連続してサインが出続ける
・サインが消えたり点いたり(リペイント)する・・・etc

リペイントの問題はどうしようもないというか、
仕様なので仕方ないですが、
連続してサインが出続けたり、
稼動し続けているとちゃんと表示しなくなるのは困りますよね。
どうしてそのようなことが起こるのでしょうか?
■リペイントの問題
作成者の意図からして仕方ないことが多いですが、
リペイントの問題は、インジケータを表示している足より右側の表示を参照することより起こります。
ZigZagのインジケータなどがその典型です。
矢印やインジケータの曲がりの位置を、表示部の右側の動きを参照して表示させているのです。
言い換えれば、未来の動きをあらかじめ参照した上で表示させている。
リペイントするインジケータが勝てそうに見えるのは仕方ありません・・・。
この問題については有名ですよね。
■連続してサインが出続ける
このインジケータに出会ったときは、何が目的で作っているのかよく分かりませんでした。
作成者がちょっと調べれば動作がおかしいことは分かっているはずなのに。
しかも、僕が見つけたのは有償の商材でなんですよね・・・。
名前の明記は避けますが、こういうのも出回っているみたいです。
もちろん、表示させたときはすごい勝てるように見えるけど・・・
■超直感!MT4(MQL)プログラミング講座■
動かしてみるとひどい。
■超直感!MT4(MQL)プログラミング講座■
原因は作成者の怠慢としか言えません・・・。
せめてリペイントくらいにしようよ….
■稼動し続けていると表示しなくなる
改善の余地がある内容かもしれません。
不具合であることは間違いないでしょう。
考えうる原因の多くは、初回起動時はちゃんと動くが、
通常稼動状態になると、データが当てはめられていない変数を使用してしまっています。
たとえば、下記のようなプログラムがあったとします。

int start() {
 //—-

 EX="";
 int limit = BarsIndicatorCounted();
 double atr[];
 ArrayResize(atr,Bars);
 for(int i=i=limit1;i>=0;i–){
  atr[i]=iATR(NULL, 0, 16, i);
  if(atr[i]>atr[i+1]){
    //インジケータのバッファに値を代入する
  }
 }
 return(0);
}

一見、正常に動作しそうですよね。
確かに初回起動時はさほど問題ありません。
しかし、常時稼動時には問題が生じます。
それはなぜでしょうか?
問題はこの部分にあります。
if(atr[i]>atr[i+1])
このatr[i+1]には値が割り当てられていない可能性があるのです。
常時稼動時、変数limit基本的に i には1か2しか割り当てられません。
i=limitのときの動作を考えて見ましょう。
atr[limit]>atr[limit+1]となりますよね。
atr[limit]には、
atr[i]=iATR(NULL, 0, 16, i);
によって値が割り当てられています。
しかしながら、
atr[limit+1]には値が割り当てられていないのです。
(atrはローカル変数だということが重要です。)
このようなプログラムを組む場合には、atrをグローバル変数にしなければなりません。
(もしくはatr[limit+1]にあらかじめ値を割り当てておく)
僕の場合、このようにします。

double atr[];int start()  {//----   int limit = Bars-IndicatorCounted(); 
ArrayResize(atr,Bars)      bool isNewBar = CheckNewBar();
if(isNewBar){
for(i=Bars-1;i>=1;i--){         atr[i] = atr[i-1];      }   }      for(int i=i=limit-1;i>=0;i--){      atr[i]=iATR(NULL, 0, 16, i);
if(atr[i]>atr[i+1]){         //インジケータのバッファに値を代入する      }   } 
   return(0);     }//+------------------------------------------------------------------+
bool CheckNewBar(){   static datetime beforeTime;      if(beforeTime != Time[0]){      beforeTime = Time[0];      return(true);   }   return(false);}

atrをグローバル変数にして、ローソク足が新しくなった際に値を自動で移動させます。
(インジケータのバッファにすれば勝手に移動してくれます。)
こうすれば、atrには常に値が代入され保存されているので、
動作不良を起こすことはありません。
ご参考になれば幸いです。
お読みいただきまして、ありがとうございます。

コメント

  1. おやっさん より:

    SECRET: 0
    PASS:
    ブログ記事とは全然関係ないですが、TOPGUN FXはヒストリーバーの本数を何本必要としているのでしょう?
    MT4を軽くしたいので本数を減らしたいのですがEAが誤動作をすると良くないので質問します。
    また、他の通貨ペアの価格参照を行っていないですよね?
    上記の事とはまた関係ないですが、EA作成で質問します。
    同じマジックナンバーを持つロット数がそれぞれ違う複数のポジション(勿論buyとsellは別のマジックナンバーです)の取得平均価格と総ロット数を簡単に算出する方法は無いでしょうか?
    何か質問ばかりですいません。

  2. SECRET: 0
    PASS:
    >おやっさんさん
    返答したつもりでいました・・
    遅れて申し訳ございません。
    100本あれば充分に動作すると思います。
    ただ、検証をしていないので2000本くらいが妥当かなと思います。
    2つ目の質問の件は、
    繰り返しと条件分岐で全部計算させるしかないですね。
    プログラムの基本は繰り返しをどれだけ効率よく使えるかということから身についてくると思います。
    for文をうまく使えば大丈夫ですよ^^
    具体的なアドバイス希望であれば記事にしますね。

タイトルとURLをコピーしました