最初のストラテジー
クロスのシグナルから、バックテスト用のエントリーと決済のルールを作ります。
クロスの章では、平均がクロスした位置に指標で印を描きました。今度は同じイベントから、シミュレーションの注文を出します。上抜けで買いポジションを開き、下抜けで決済します。
ストラテジーがすること
指標は計算と表示を行います。ストラテジーはそれに加え、バックテストのシミュレーターへ注文を出します。シミュレーターは、過去のローソク足と指定したルールに従い、注文、ポジション、損益を追跡します。
この過去データでの検証をバックテストと呼びます。この章の注文はすべてシミュレーションです。Run Pyne codeを実行しても、実際の取引口座に注文は出しません。
ポジションは、エントリーが約定した後に保有している建玉です。注文は指示であり、約定はポジションを作ったり変えたりする出来事です。この3つは区別して使います。
先にルールを文章にする
今回のルールは次のとおりです。
- 各ローソク足で長さ5と20のSMAを求める。
- 上抜けで、1単位のロングポジションのエントリー注文を出す。
- 下抜けで、
Longというエントリーに対応するポジションを決済する。 - 計算には、確定済みの過去のローソク足を使う。
ロングは、価格が上がると価値が増え、下がると減るポジションです。この例ではショートは開きません。
すべての上抜けが利益になるというルールではありません。この操作を指定したデータで行ったらどうなったかを調べるのが、バックテストです。
プログラム全体
crossover_strategy.pyを作ります。
"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta
@script.strategy(
"Average Crossing Strategy",
overlay=True,
initial_capital=10000,
default_qty_type=strategy.fixed,
default_qty_value=1,
pyramiding=1,
)
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)
if crosses_up:
strategy.entry("Long", strategy.long)
if crosses_down:
strategy.close("Long")
plot(fast_average, "Fast average", color=color.blue, linewidth=2)
plot(slow_average, "Slow average", color=color.orange, linewidth=2)@script.strategyは、main()がストラテジーであることを指定します。計算と2本の線はそのまま使えます。新しくインポートするstrategyには、注文操作やストラテジーのデータがあります。
デコレーターの呼び出しは複数行です。こちらの設定がストラテジーの実行を定め、main()のパラメーターは自分の計算の入力です。
初期資金と数量
initial_capital=10000は、シミュレーションの開始残高です。単位や価格水準は、デモデータに付属する市場メタデータに従います。
default_qty_type=strategy.fixedは固定数量です。default_qty_value=1で1単位を注文します。資金の1%でも、必ず1通貨単位というわけでもありません。
pyramiding=1は、同方向のエントリーを最大1つに制限します。この例では、すでにあるポジションにロングを追加しません。
学習では小さな固定数量を使い、操作を追います。数量計算の違いを同時にいくつも考えずに、結果の変化を調べられます。
エントリーと決済の名前
strategy.entry("Long", strategy.long)の最初の引数は注文IDです。Longという文字列はプログラムで決めた名前で、方向は2つ目の引数が指定します。
strategy.close("Long")は、同じIDを参照します。名前は一致させます。"Buy"でエントリーした場合、"Long"の決済はそのエントリーを対象にしません。
ここでの下抜けは決済であり、ショートのエントリーではありません。その名前のポジションがなければ、決済するものもありません。
PyneIDEで実行する
- プログラム全体を保存します。
- Run Pyne codeで
demoを選びます。 - 2本のSMAと取引マーカーを確認します。
- チャート下のパネルを開き、Tradesタブを選びます。

取引がない場合は、ストラテジーのファイルを実行したか、@script.strategyが残っているか確認してください。2つの入力の実際の値も確認します。同じデータから同じ長さで計算するSMA同士は、クロスしません。
シグナルと約定の時点
ここで使う既定設定では、足の終値データから成行注文を出します。通常、次の足の始値で約定します。そのため、シグナルの足とエントリーの足が異なる場合があります。
成行決済も同じです。下抜けで出した決済注文が、次の始値でポジションを閉じます。
最後の足で注文しても、ファイルには次の足がありません。約定しない場合があります。また、前に開いたポジションが最後まで残る場合もあります。
約定方法は設定の一部です。次の章ではPropertiesでも確認します。結果は常に、その実行で使った約定方法と合わせて読み取ってください。
自分で試す
ストラテジーの入力を開き、短期と長期を両方20にします。2本の線の位置関係と、クロスによる取引が何回あるかを予想してください。
解答
同じ価格と同じウィンドウを使うため、SMAは一致します。一方が他方を上抜け、下抜けする足はありません。このルールからはエントリーしません。
入力を保存し、再計算が完了して初めて、チャートがその結果を示します。確認後は5と20に戻してください。
エントリーを1つ選ぶ
約定したエントリーを探し、前の足の2つの平均を調べます。上抜けはシグナルの足で起きているはずです。取引価格は、シグナルの終値だと思い込まず、エントリーした足の始値と比較してください。