ローソク足の列をたどるのは実行環境です。ただし、1本の処理内でも繰り返しが必要になることがあります。例えば、直近5つの終値を足す処理です。そのためにループを使えます。

forとrange

for offset in range(5):
    total += close[offset]

range(5)では、offsetに0、1、2、3、4を順に代入します。5は含みません。字下げされた行を、その値ごとに1回実行します。

そのためclose[offset]は、現在、1本前、2本前、3本前、4本前の終値を順に表します。ちょうど5つを足します。

totalはループの前に0にします。その足の計算の途中結果であり、次の足まで保持するカウンターではありません。

range(1, 5)なら1、2、3、4です。開始値は含み、終了値は含みません。開始値を省略すると0から始まります。

自分で書く移動平均

manual_average.pyを作ります。

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, ta


@script.indicator("Manual Average Check", overlay=False)
def main(
    length: int = input.int(5, title="Length", minval=1, maxval=100),
):
    total = 0.0
    for offset in range(length):
        total += close[offset]
    manual_average = total / length
    builtin_average = ta.sma(close, length)
    difference = manual_average - builtin_average
    plot(difference, "Difference", color=color.blue)

デモデータで実行してください。線は、自分の平均から組み込みSMAを引いた差です。ウォームアップ後は0、または数値表現の誤差によって0にごく近い値になるはずです。

manual_average.pyの横の別パネルに、2つの平均の差を示す線が表示されている。
ループで求めた平均と組み込みSMAの差は、ウォームアップ後は0付近になります。

線を2本重ねると小さな違いを見落としやすいため、差を描いています。2つの計算が一致するかを直接確認できます。

1回の実行で行うこと

長さ5の場合の順序です。

  1. totalを0にします。
  2. 現在と過去4本の終値をループで足します。
  3. 合計を5で割ります。
  4. 組み込みSMAも求め、自分の結果と組み込み値の差を計算します。
  5. 差の線に点を1つ描きます。

その後、実行環境が次の足へ進みます。totalは再び0から始まり、ループは新しい足に対応する5つの値を足します。

totalをPersistentにすると、次の足でも前の合計から続けてしまいます。毎回さらに5つを足すことになり、現在のウィンドウの平均ではなくなります。

過去の値が足りない場合

先頭の4本では、5つの値のうち少なくとも1つが欠けています。合計にnaが入るため、自分の平均も欠損します。長さ5の組み込みSMAも、有効になるのは5本目からです。

この本のデモデータでは、すべての終値が有効です。途中にも欠損があるデータでは、ta.smaの欠損処理は、単にローソク足のオフセットで足す方法とは異なる場合があります。そのため、この例の確認には指定したデータを使います。

何回繰り返すか

ウィンドウが100本なら、1本の処理で100回足します。2000本では、ループの処理は200000回です。

組み込みのta.smaは、このよく使う処理を専用の計算で行うためにあります。ここでのループは、理解と比較のためのものです。必要な処理をしてくれる場合は、組み込み関数を使ってください。

ループは終わりが分かり、回数が制限されている必要があります。入力の最大値によって、利用者が1本の処理で要求できる仕事量も制限しています。

breakとcontinue

breakはループを終了します。continueは、その回の残りの処理を飛ばして、次の繰り返しへ進みます。

平均では慎重に使ってください。3つだけ足して止めたなら、5つ足したつもりで5で割ることはできません。途中を飛ばすと、計算の意味が変わります。

自分で試す

長さを3にします。ある足で、ループが使うオフセットと対応する3つの価格を書き出してください。その後、コードを変更して、自分の平均と組み込み平均を重ね表示で描きます。

解答

オフセットは0、1、2です。デコレーターをoverlay=Trueにし、計算の後に次を置きます。

plot(manual_average, "Manual average", color=color.blue, linewidth=2)
plot(builtin_average, "Built-in average", color=color.orange)

この表示から差の描画は外してください。0付近の差と価格付近の平均を同じスケールに置くと読みにくくなります。確認用として、元の差のパネルは別のプログラム版に残せます。

ずれたウィンドウを考える

range(1, length + 1)に変えたらどうなるか考えてください。要素は5つのままですが、現在が外れ、5本前が入ります。現在ではなく、1本前の平均ウィンドウになります。