例えば、終値の25本分の移動平均線を引くには、過去に25本分の情報が必要になるので、少なくともチャートの最初の25本分の終値が確定するまでは計算することができません。
上記のチャートは、25本の移動平均線のインジケーターを適用して、データの最初の部分を表示したものです。 最初の方のバーは計算ができないので、25本目までは移動平均線が表示されていないことが分かります。
25本の移動平均線を引くためのインジケータのプログラムは、例えば下記のような感じで記述できます。
SetPlotColor(1, Green); // 色: グリーン
SetPlotWidth(1, 3); // 太さ: 3
Plot1(Average(Close, 25));
<div class=”note” ラインを価格のチャートに重ねて表示するには、インジケーターのプロパティ設定で、スケール位置を「元データに軸を合わせる」に設定しておく必要があることに注意してください。 </div>
このようなインジケーターをチャートに適用すると、トレードステーションは内部で自動的に、過去何本分のバーが計算に必要かを計算し、MaxBarsBack
というプロパティに格納します。
この例では、MaxBarsBack
の値は 25 になります。
Print("MaxBarsBack=", MaxBarsBack:0:0); // 25 と表示される
インジケーターの計算処理は、基本的にはバー1本ごとに実行されるのですが、MaxBarsBack
が 25 であれば、最初の 25 本のバーでは計算することができないことが分かっています。
このような場合、トレードステーションは処理を最適化するために、25 本分のバーの計算をスキップするようになっています(26本目のバーからインジケーターの計算処理が行われます)。
現在処理中のバーの番号を取得するためのキーワードとして CurrentBar
や BarNumber
がありますが、この値が1になるのは、チャートの一番最初のバーではなく、MaxBarsBack
の次のバーを示しています(計算処理が始まる最初のバーを示すということ)。
ちなみに、自動売買のためのストラテジを作成するときは、MaxBarsBack
の値は明示的に固定の値を指定する必要があります(ストラテジーのプロパティダイアログで設定することができます)。
ストラテジの MaxBarsBack
の値は、デフォルトでは 50 に設定されています。
MaxBarsBack
が 25 であれば、過去 25 本分のバーの情報を使って、26 本目のバーから計算が行われるはずです(26 本目のバーが CurrentBar==BarNumber[0]==1
となる)。
しかし、実際にはインジケータープログラムはそれとは別に、あらかじめ無条件で 1 回実行されるようです。
そして、その 1 回目の実行中に MaxBarsBack
を参照すると 1 という想定外の値が得られます。
試しに、下記のようなインジケータープログラムを実行すると、
Once begin
Print("MaxBarsBack=", MaxBarsBack:0:0,
", CurrentBar=", CurrentBar:0:0,
", Date=", Date+19000000:8:0);
end;
印刷ログに次のように表示されます。
MaxBarsBack=1, CurrentBar=1, Date=20161108
MaxBarsBack=25, CurrentBar=1, Date=20161213
そもそも Once begin
~ end
で囲まれたブロックは、分析テクニックを適用した最初の 1 回しか実行されないはずなのに、2 回実行されちゃっています。
そして、1 回目の実行時には MaxBarsBack
の値が 1 というおかしな値になっています。
どうやら、移動平均を計算するケースなどでは、MaxBarsBack
などの値を自動計算するために、初期化処理として 1 度だけ無条件でインジケーターの処理が実行されるようです(計算の必要がない場合は、この初期化処理は実行されない)。
そして、その処理によって MaxBarsBack
の値が 25 であることが判明し、25本分のバーをスキップして、改めて Once
ブロックから処理が再実行されるというメカニズムのようです。