Skip to content
Go back

ザラ場動的キャンセル機構:発注後の相場急変に自動対応する

Edit page

日本株の自動売買で見落としがちなのが「発注してから約定するまでの間に相場が急変するリスク」だ。寄り付き前に指値注文を出しても、ザラ場(取引時間中)に悪材料が出て株価が急落すれば、その注文はもはや不利な条件で約定する可能性がある。

本記事では、Kabustation API(auカブコム証券のAPI)を使って、ザラ場中に4段階のチェック(S1〜S4)で注文をリアルタイム監視し、条件を満たさなくなった注文を自動キャンセルする「動的キャンセル機構」の設計と実装を記録する。1,507テスト全PASSで実装完了済みだ。


問題の背景

日本株自動売買の注文フロー

日本株の自動売買では、一般的に以下のフローで注文する。

前日夜: シグナル計算・銘柄スクリーニング
当日朝 08:00: 指値注文を一括発注
09:00: 東証オープン(寄り付き)
09:00〜15:30: ザラ場(取引時間)
15:30: 大引け

問題は「08:00の発注」と「09:00の寄り付き」の間に1時間のギャップがあること、さらにザラ場中も相場は刻々と変化することだ。

具体的なリスク

  1. ギャップダウン: 前日終値から大きく下げて始まる。SLを超える価格で寄り付く場合がある
  2. セクター急落: 特定セクターに悪材料。発注済みの同セクター銘柄が一斉に下落
  3. 指数急落: 日経平均が急落。マーケット全体のリスクオフ
  4. 流動性の消失: 板が薄くなり、約定品質が著しく悪化

これらの状況で「出しっぱなしの注文」が不利な価格で約定するのを防ぎたい。


4段階チェック(S1〜S4)

動的キャンセル機構は、ザラ場中に定期的(1分間隔)に4段階のチェックを実行し、いずれかの条件に抵触した注文をキャンセルする。

S1: 価格乖離チェック

現在の株価が、注文時に想定した価格から大きく乖離していないかを確認する。

def check_s1_price_deviation(
    order_price: float,      # 注文価格
    current_price: float,    # 現在価格
    max_deviation_pct: float = 3.0,  # 最大許容乖離率(%)
) -> bool:
    deviation = abs(current_price - order_price) / order_price * 100
    return deviation <= max_deviation_pct

例えば注文時の想定価格が1,000円で、現在価格が970円(-3%以上の下落)なら、この注文はキャンセル対象になる。

S2: ボリュームチェック

出来高が極端に少ない銘柄は、約定後に「板が薄くて逃げられない」リスクがある。

def check_s2_volume(
    current_volume: int,     # 当日の出来高
    avg_volume_20d: int,     # 20日平均出来高
    min_volume_ratio: float = 0.3,  # 最低出来高比率
) -> bool:
    if avg_volume_20d == 0:
        return False
    return current_volume / avg_volume_20d >= min_volume_ratio

当日の出来高が20日平均の30%未満の場合、流動性不足と判断してキャンセルする。

S3: 指数連動チェック

日経平均やTOPIXが急落している場合、個別銘柄の注文を維持するのはリスクが高い。

def check_s3_index_drop(
    nikkei_change_pct: float,  # 日経平均の前日比変動率
    topix_change_pct: float,   # TOPIXの前日比変動率
    max_index_drop: float = -2.0,  # 最大許容下落率(%)
) -> bool:
    return nikkei_change_pct >= max_index_drop and topix_change_pct >= max_index_drop

日経平均が前日比-2%以上下落していたら、全注文をキャンセルする。

S4: スコア再計算チェック

最も重要なチェック。発注時に計算したシグナルスコアを、最新のデータで再計算する。スコアが閾値を下回っていたら、もはやエントリーの根拠がないためキャンセルする。

def check_s4_score_revalidation(
    current_indicators: dict,  # 最新の指標値
    min_score: float,          # エントリー閾値
) -> bool:
    recalculated_score = evaluate_signal(current_indicators)
    return recalculated_score >= min_score

これにより「発注時点では有効だったシグナルが、ザラ場中に無効化された」ケースを捕捉できる。


全体のアーキテクチャ

[launchd: 09:05 JST 起動]

    └─ DynamicCancelMonitor(1分間隔ループ)

         ├─ 未約定注文リスト取得(Kabustation API)

         └─ 各注文に対して S1→S2→S3→S4 チェック

              ├─ 全チェックPASS → 注文維持

              └─ いずれか失敗 → 注文キャンセル(Kabustation API)
                   └─ Slack通知

キャンセルの判断基準

S1〜S4のチェックは「AND条件」ではなく「OR条件」だ。どれか1つでも失敗したらキャンセルする。なぜなら:

約定済み注文への影響

重要な設計ポイントとして、この機構は未約定の注文のみを対象とする。既に約定したポジションには一切影響しない。約定済みポジションの管理は別の仕組み(SL/TP + トレーリングストップ)で行う。


100株単位制約への対応

日本株は100株単位でしか取引できない。ロットサイズの計算結果が150株の場合、100株に切り捨てるか200株に切り上げるかの判断が必要になる。

def round_to_unit(shares: int, unit: int = 100) -> int:
    """100株単位に丸める(切り捨て)"""
    return (shares // unit) * unit

切り捨て(保守的)を採用した。リスク管理上、「少なくトレードする」方が安全だからだ。


テスト戦略

1,507テストを以下の構成で実装した。

テストカテゴリ件数内容
S1単体テスト150価格乖離の境界値テスト
S2単体テスト120出来高ゼロ・異常値テスト
S3単体テスト130指数データ取得失敗時のフォールバック
S4単体テスト200スコア再計算の整合性
統合テスト300S1〜S4の組み合わせシナリオ
API mock テスト200Kabustation API障害時の動作
回帰テスト407既存の取引ロジックへの影響ゼロ確認

API障害時は「キャンセルしない」(安全側=注文維持)とした。APIが壊れているときに大量キャンセルすると、本来約定すべき有利な注文も消してしまうリスクがあるためだ。


学んだこと

1. 「発注して終わり」は片手落ち

自動売買で注力されがちなのは「いつ、何を、いくらで注文するか」だ。しかし「発注済みの注文を、変化した環境に合わせて管理する」のも同じくらい重要だ。発注〜約定の間にも相場は動いている。

2. 4段階チェックのOR条件は過剰に見えて適切

「どれか1つでも引っかかったらキャンセル」は一見厳しすぎるように見える。しかし、不利な約定1件のコスト(数千円〜数万円の損失)と、キャンセルによる機会損失(利益を逃すリスク)を比較すると、前者の方が遥かに痛い。リスク管理は「厳しすぎるくらいでちょうどいい」。

3. テストの重要性は実装の3倍

1,507テストは実装コード量の3倍近い。しかし「本番で1件の誤キャンセルが発生する」コストを考えると、テストへの投資は十分にペイする。特にS3(指数急落)のテストは、実際の暴落データを使ったシナリオテストが不可欠だった。


まとめ

ザラ場動的キャンセル機構の設計で重要なのは以下の3点だ。

  1. 4段階チェック(S1〜S4): 価格乖離・出来高・指数連動・スコア再計算の多面的な判断
  2. OR条件でのキャンセル: 1つでも失敗したらキャンセル。リスク回避は厳しい方が正しい
  3. 未約定注文のみ対象: 約定済みポジションとは独立した管理。責務の明確な分離

「出した注文を守る」のではなく「環境が変わったら撤退する」。この柔軟性が、ザラ場の急変から資産を守る最後の防衛線だ。


Edit page
Share this post on:

Previous Post
VWAP乖離エントリーフィルター:「寄天」損失を構造的に排除する
Next Post
【破産確率0%】EUR_JPY + GBP_JPY Long-only戦略の安定運用