価格が10本にわたって平均より上にあれば、close > averageは10回真になることがあります。下から上へ抜けたイベントだけを印にしたいなら、前の足での位置関係も必要です。

ある状態と、その始まり

平均が現在も前の足も100だとします。前の終値は99、今は101です。現在は平均より上にあり、前の足から上抜けもしています。

次の終値が102なら、引き続き平均より上です。ただし、前の足でもすでに上にあったので、新しい上抜けではありません。

ta.crossover(first, second)は、現在の第1の値が第2より大きく、前回の実行では以下だった場合に真になります。ta.crossunderはその下抜け版です。

現在の値が等しいだけではクロスになりません。第1の値が第2に届いただけでは、>が真でないからです。一方、前の足で等しかった場合は、今回上に抜ければクロスになります。

上にある状態と上抜けの違い終値が平均を上抜けるのは3本目だけです。4本目も平均より上ですが、新しいシグナルはありません。直前の足で値が等しい場合も、上抜けは成立します。 close: 99 → 100 → 101 → 102. average: 100 → 100 → 100 → 100. close > average: False → False → True → True. ta.crossover(close, average): False → False → True → False.終値average = 100991FalseFalse1002FalseFalse1013TrueTrue1024TrueFalse足close > averageta.crossover(close, average)
上にある状態と上抜けの違い終値が平均を上抜けるのは3本目だけです。4本目も平均より上ですが、新しいシグナルはありません。直前の足で値が等しい場合も、上抜けは成立します。

2本の移動平均のクロス

移動平均で作った2本を使います。短く反応の速い平均を青、長く反応の遅い平均をオレンジにします。短期平均の上抜けを緑の三角、下抜けを赤で示します。

cross_signals.pyを作ります。

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


@script.indicator("Average Crossings", overlay=True)
def main(
    fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
    slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
):
    fast_average = ta.sma(close, fast_length)
    slow_average = ta.sma(close, slow_length)
    crosses_up = ta.crossover(fast_average, slow_average)
    crosses_down = ta.crossunder(fast_average, slow_average)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)
    plotshape(crosses_up, "Cross up", style=shape.triangleup,
              location=location.belowbar, color=color.green)
    plotshape(crosses_down, "Cross down", style=shape.triangledown,
              location=location.abovebar, color=color.red)

既定値の5と20を使い、デモデータで実行します。マーカーはクロスした足にだけ表示されます。青がオレンジより上にある期間が長く続いても、毎回新しい緑の印が付くわけではありません。

cross_signals.pyのチャートに、短期と長期の移動平均、緑と赤のクロスマーカーが表示されている。
2本の移動平均のクロスを、個別のイベントとして表示しています。

クロスを別の行で計算する理由

ta.crossoverとta.crossunderは、すべての足で実行します。そのため、関数にとっての前回の実行が、1本前の処理に対応します。

別の条件を満たしたときだけ呼び出すと、保持している前回の状態が、1本前の足のものとは限らなくなります。描画した線とマーカーが、異なる時系列を調べてしまう可能性があります。

そのため、前の章と同じルールを使います。状態を持つ計算を各ローソク足で行い、得られた値で判断します。

ここでもウォームアップがある

長さ20のSMAは、20本目から有効です。最初の有効値では、前のSMAはまだ欠損しています。現在と前の2本がそろっていないので、クロスを判断できません。

条件には、両方の平均について、現在と前の値が必要です。

シグナルを出すためにnaを0に置き換えるのは避けてください。実際の平均をまだ求められない位置で、0という架空の平均によるクロスが生まれる可能性があります。

データが確定する時点

この本では、確定済みの過去のローソク足で実行します。日足の終値で作るシグナルは、その足が確定した時点の情報を使います。

形成中の足の終値は、まだ変わります。途中で見えたクロスが、確定時には消えることもあります。確定足での確認とは区別してください。

過去のチャートに印があるからといって、その足で自動的に取引が約定したわけではありません。指標は印を描くだけです。注文と約定のタイミングは、ストラテジーで指定します。

自分で試す

price_crossings.pyというコピーを作ります。平均同士のクロスの代わりに、終値が長期平均を上抜け、下抜けしたときに印を付けてください。長期平均はチャートに残します。

解答
crosses_up = ta.crossover(close, slow_average)
crosses_down = ta.crossunder(close, slow_average)

マーカーは2つの論理変数を使うので、plotshapeの行を書き換える必要はありません。ただし、タイトルはPrice cross upとPrice cross downに変えると分かりやすくなります。

短期平均が不要になったら、その計算、描画、入力を削除します。画面には実際に使う設定だけが残ります。

クロスを1つ追う

緑の印のある足を選び、その足と1本前で2本の線の値を確認します。シグナルが真になった2つの比較を説明してください。この方法は、ストラテジーの確認にも使えます。