最初のストラテジーは、逆方向のクロスでのみ決済しました。今度は、エントリー価格からの損失幅と利益幅も指定します。元のクロスによる決済は残します。

3つの決済理由

この例のロングは、次の3つのイベントで決済できます。

  • 損切りストップ注文の水準に価格が届く。
  • 利益確定の指値注文の水準に価格が届く。
  • 短期平均が長期を下抜けし、成行決済が約定する。

ストップと指値は価格条件付きの注文です。strategy.closeは成行決済です。約定ルールが異なる場合があるため、表で価格と時刻の両方を確認します。

距離か、具体的な価格か

strategy.exitでは、2種類の指定ができます。

引数指定するもの
losstick単位の損失幅
profittick単位の利益幅
stop具体的なストップ価格
limit具体的な指値価格

loss=100は100%でも、必ず100通貨単位というわけでもありません。エントリーから100 tick離れた水準を指定しています。

DEMOのtickサイズは0.01です。100 tickは価格差1、200 tickは2です。ロングのエントリーが200なら、スリッページや約定条件による追加の影響を除き、ストップは199、目標は202になります。

プログラム全体

protected_strategy.pyを作ります。

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


@script.strategy(
    "Crossing Strategy with Exits",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
    commission_type=strategy.commission.percent,
    commission_value=0.1,
    slippage=2,
)
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),
    stop_ticks: int = input.int(100, title="Stop distance (ticks)", minval=1),
    target_ticks: int = input.int(200, title="Target distance (ticks)", minval=1),
):
    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")
    strategy.exit("Bracket", "Long", loss=stop_ticks, profit=target_ticks)
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

Bracketは決済注文グループのIDです。2番目のLongが、対応するエントリーを指定します。lossとprofitには、上の2つの入力を使います。

同じIDで各ローソク足において呼び出します。これは指定した決済ルールを管理する処理であり、呼ぶたびに独立した新しいポジションを開くわけではありません。

デモデータで実行してください。Tradesには、クロスによる成行決済に加え、Bracketによる決済も現れる場合があります。

PyneIDEでprotected_strategy.pyを実行し、ストップや利益目標でも取引を決済する画面。
クロスによる決済に加え、tick単位のストップと利益目標を使います。

保護用の決済はいつ有効になるか

同じ実行内で、エントリーとそれに対応する決済を指示できます。実行環境はtickの距離を、実際のエントリーの約定価格に結び付けられます。

一方、シグナルの終値から具体的なstopを求めると、その水準の基準はシグナル価格です。次の始値が違えば、実際のエントリーからの距離も変わります。

どちらを指定するかは、記述したいルールで決めます。lossはエントリーからのtick距離、stopは具体的な価格です。

ローソク足だけでは全値動きは分からない

OHLCVからは、始値、高値、安値、終値が分かります。ただし、その間のすべての価格の時間順までは自動的には分かりません。

同じ足の高値が目標に届き、安値がストップに届いた場合、4つの価格だけではどちらが先か分かりません。シミュレーターは約定モデルのルールに従います。より短い時間足のデータで、詳しく調べられる場合があります。

この場合は個別に確認し、都合のよい方を手で選ばないでください。モデルの仮定も結果の一部です。

ストップ価格も、同じ価格での約定を保証しません。次の足がストップを飛び越えて始まると、その水準より不利な価格で約定する場合があります。スリッページによる追加の差もあり得ます。

同じ足の中でのストップと利確どちらの経路も同じOHLCの足になります。199のストップと202の利確注文はすでに有効です。下位時間足のデータがない場合、モデルは始値に近い極値へ先に進むため、この例ではストップが先に約定します。別の経路は、価格が動く順序の重要性を示しています。 open: 200; high: 203; low: 198; close: 201. stop: 199; limit: 202. open → low → high → close; open → high → low → close.OHLCモデルの経路別のあり得る順序O → L → H → CO → H → L → C202199202199OLHCOHLCストップが先に約定利確注文が先に約定O = 200 · H = 203 · L = 198 · C = 201買いポジション保有中。決済注文は有効。窓とスリッページは考慮しません。
同じ足の中でのストップと利確どちらの経路も同じOHLCの足になります。199のストップと202の利確注文はすでに有効です。下位時間足のデータがない場合、モデルは始値に近い極値へ先に進むため、この例ではストップが先に約定します。別の経路は、価格が動く順序の重要性を示しています。

距離と金額での損失

数量1、ポイント価値1のロングで、100 tick、tickサイズ0.01なら、価格差による損益は1通貨単位です。数量10なら10倍です。

数量、tickサイズ、ポイント価値の組み合わせが、ストップまでの変動の金額を決めます。さらに手数料と実際の約定条件が影響します。

注文に直接qtyを渡すと、その注文独自の数量になります。この例は既定の数量を使っており、Properties → Order sizeでも上書きできます。

100と200 tickは、DEMOでの説明用の設定です。別の銘柄では、同じ数値でも価格差や金額は異なる場合があります。

自分で試す

短期と長期、数量、費用は変えず、ストップ/目標を100/200、次に200/400で実行します。同じエントリーシグナルがどうなるか確認してください。

解答

Inputsで**Stop distance (ticks)とTarget distance (ticks)**だけを変えます。距離が広がるので、決済の足や理由が変わる場合があります。

クロスによる決済は両方に残っています。目標が遠くても、必ずその価格まで保有し続けるわけではありません。決済ルールは一緒に働きます。

入力の保存後は再計算の完了を待ち、新しい結果を読んでください。後で比べる場合は、書き出しを別名で保存します。

決済理由を探す

決済済みの取引を選び、エントリー価格、指定したtick距離、決済足のOHLCを調べます。決済価格と時刻から、どのルールで説明できるか考えてください。同じ足が複数の水準に触れているなら、約定モデルも考慮します。