株の自動売買を実運用する前に安全対策を実装|二重注文・異常データをどう防ぐ?

AIツール

Pythonで日本株の投資支援・自動売買ツールを自作しています。

前回は、三菱UFJ eスマート証券のAPIから実際の株価・出来高・板などを取得し、分析できるところまで進みました。

ここまで来ると、次は注文機能をつないで売買したくなります。

しかし、その前に一度立ち止まりました。

実際のお金を扱うシステムでは、

「正しい売買判断ができるか」だけでは不十分

だからです。

例えば、

  • 同じ注文を二重に送ってしまう
  • 古い株価を使って注文してしまう
  • 異常な価格データを正常だと判断してしまう
  • 注文が通ったか分からないのに、もう一度送ってしまう
  • 再起動後に証券会社と自分の記録が食い違う

といった問題が起きれば、売買ロジックが正しくても損失につながる可能性があります。

そこで今回は、実際のお金を使わない模擬運用へ進む前に、こうした事故を防ぐための安全対策をまとめて実装しました。


「動くシステム」と「実際に使えるシステム」は違う

これまでの開発では、売買ルールのバックテストだけでなく、注文を管理する仕組みや証券会社から市場データを取得する機能まで作ってきました。

しかし、本番運用を想定して改めて全体を確認すると、まだ危険なケースが残っていました。

特に気になったのは、

正常なときではなく、何かがおかしくなったときにどう動くか

です。

APIから正常なデータが返り、注文も一度で成功するならシステムは動きます。

問題はそうならなかった場合です。

そこで今回の安全対策では、基本方針を一つにしました。

状態を確認できないときは、無理に取引を続けない。

判断できない状態を推測で補って注文するより、一度止めて確認する設計を優先しています。


APIパスワードや認証情報を残さない

最初に見直したのがセキュリティです。

証券会社APIを使うようになると、APIパスワードや認証用の情報を扱います。

通常のプログラムならエラー内容を詳しくログへ残すことはデバッグに役立ちますが、証券口座につながるシステムでは、それが新しいリスクになります。

そこで、

  • ログ
  • エラーメッセージ
  • データベース
  • API通信時の診断情報

などに重要な認証情報が残らないようにしました。

また、APIとの通信先についても制限し、意図しない外部サーバーへ認証情報付きの通信が飛ばないようにしています。

売買ロジック以前に、

証券口座へ接続する情報そのものを守る

ための対策です。


再起動したら証券会社と自分の記録を照合する

次に対策したのが、システムを再起動したときの問題です。

例えば、自分のツールには、

「100株の買い注文を出した」

と記録されているのに、証券会社側ではすでに約定しているかもしれません。

逆に、注文を送信した直後に通信が切れ、

注文が証券会社へ届いたのか分からない

というケースも考えられます。

この状態で、

「たぶん注文されていないだろう」

と判断してもう一度100株を注文すると、実際には200株買ってしまう可能性があります。

そこで起動時には、

  • 保有株
  • 注文状況
  • 口座情報

について、自分のシステムに保存されている記録と証券会社側の状態を照合するようにしました。

一致しなければ、新しい注文を止めます。

自動的にどちらかを正しいことにするのではなく、状態を確認してから再開する仕組みです。


同じ注文を二重に送らない

注文処理そのものも見直しました。

特に避けたいのが二重注文です。

例えば100株の買い注文を送信する処理が同時に2回動けば、意図せず200株買ってしまう可能性があります。

そこで、証券会社へ注文を送る前に、

「この注文は今から送信する」

という状態をシステム側で確定させるようにしました。

すでに別の処理が送信を始めている注文は、もう一度送れません。

また、注文の状態についても、

  • 送信中
  • 送信結果が不明
  • キャンセル依頼中
  • キャンセル結果が不明
  • 約定済み
  • 期限切れ

などを区別できるようにしました。

特に重要なのは、

「注文結果が分からない」を「注文失敗」と同じ扱いにしないこと

です。

結果が分からない状態で自動的に注文を送り直すと、二重注文につながる可能性があるためです。


人間が承認した注文にも有効期限を付ける

最初の実運用では、AIが判断した注文をそのまま自動送信する予定ではありません。

最終的には自分で確認してから注文する

形で始める予定です。

ただし、人間が一度「OK」と判断したからといって、その注文をいつまでも有効にするのも危険です。

例えば10時に確認した注文を、相場が大きく動いた14時にそのまま送るのは、同じ取引とは言えません。

そこで、人間による承認にも有効期限を設定しました。

さらに注文を送る直前には、

  • 現在の口座状況
  • 保有株
  • 未完了の注文
  • 現在のリスク

をもう一度確認します。

「一度確認したから大丈夫」ではなく、実際に注文する直前にも確認する

仕組みです。


取引時間と日足データも安全側に判定

時間の扱いも見直しました。

日本株では前場と後場があり、取引できる時間が決まっています。

ツール側でも取引可能時間を判定し、取引日かどうか確認できない場合には注文しないようにしました。

また、日足を使った売買判断では、まだ取引が終わっていない当日の日足を「確定済み」として扱わないようにしました。
例えば、当日の終値を使って売買シグナルを判定できるのは、その日の取引が終了して終値が確定した後です。
そのため、確定した日足で判断し、次の取引可能日以降に注文するという時間関係を明確にしました。

バックテストと実運用で条件がずれないための対策でもあります。


取得できた株価なら何でも使えるわけではない

市場データについても安全対策を追加しました。

前回の記事では、実際のAPIから複数銘柄を取得した際、一部だけ取得に失敗するケースがありました。

そこで今回は、

「データを取得できたか」だけでなく、「そのデータを注文判断に使ってよいか」

まで確認します。

例えば、

  • データが古すぎないか
  • 数値として扱えない値が入っていないか
  • 株価が不正な値になっていないか
  • 出来高などがマイナスになっていないか
  • 高値・安値・始値・終値の関係がおかしくないか
  • 板の買値と売値に矛盾がないか

などをチェックします。

そして用途も分けました。

分析には使えても、実際の注文には使わないデータ

という状態を認めています。

ChatGPTで相場を見るための参考情報と、実際のお金を動かすための情報では、求める安全性が違うからです。


データ取得の再試行も「何でも自動」にはしない

通信エラーが起きたときには、もう一度データを取得すれば成功する場合があります。

ただし、すべてのエラーで自動的に再試行するようにはしていません。

例えば、

一時的な通信エラーや時間切れ

については、再取得を許可できます。

一方で、

  • 認証に失敗している
  • データ形式がおかしい
  • 取得したデータが古い
  • 原因を特定できない

といった場合は、自動的に何度も取得しません。

さらに、この再試行は市場データを読む処理だけに限定しています。

注文やキャンセル処理には同じ仕組みを使いません。

株価データの取得はもう一度試せても、

注文をもう一度送ってよいとは限らない

からです。


安全確認した株価と、実際の注文判断に使う株価を同じにする

市場データの安全対策を作る中で、もう一つ重要な点がありました。

例えば、

  1. 株価Aを取得
  2. 株価Aが正常かチェック
  3. その後、別に株価Bを取得
  4. 株価Bを使って注文金額を計算

という流れでは、株価Aを安全確認した意味が薄れてしまいます。

そこで、

安全確認を通過した同じ市場データを、そのまま注文前のリスク計算にも使う

構造にしました。

さらに、

  • リスク確認前
  • 注文処理を確定する前
  • 証券会社へ送る直前

にも、データが古くなっていないか確認します。

途中で有効期限を超えた場合は注文しません。


安全対策を追加したら51件のテストが失敗した

ここまで安全対策を追加したあと、すべてのテストをまとめて実行しました。

すると最初は、

51件のテストが失敗しました。

一見すると大きな問題に見えます。

ただ、原因を確認すると、新しく追加した安全ルールに対して、以前のテスト側が対応できていないことが主な原因でした。

例えば以前は、

「リスク判定がOKなら注文できる」

という前提だった部分があります。

しかし今回からは、それだけでは足りません。

安全性を確認した市場データが存在することなど、新しい条件も必要になりました。

ここで古いテストを通すために安全条件を緩めることはせず、テスト側を新しい仕組みに合わせて修正しました。


最終的に494件のテストをすべて通過

修正後、もう一度すべてのテストを実行しました。

結果は、

494 tests PASS

となりました。

今回重要なのは、単純にテスト件数が増えたことではありません。

証券会社APIへ接続したあとに、

「実際のお金を扱うなら何が危険なのか」

を洗い出し、その状態では注文しない仕組みを追加したことです。

現在は、

市場データ取得
↓
データが正常か確認
↓
必要な場合だけ限定的に再取得
↓
売買判断・リスク確認
↓
人間による承認
↓
注文直前にもう一度確認
↓
二重注文を防いで証券会社へ送る

という流れになっています。

本文画像

ただし、これは実資金で安全に完全自動売買できることを意味するものではありません。

まだPaper Tradingで実際に動かし続けた検証は行っていません。


次は「安全に注文できるか」から「いくらまで注文してよいか」へ

今回までで、

異常な状態では注文を止める

ための仕組みはかなり増えました。

次に必要なのは資金管理です。

例えば、

  • 100万円のうち1銘柄へいくらまで使うか
  • 同時に何銘柄まで持つか
  • 注文中の買付資金も使用済みとして扱うか
  • 1日の損失が一定額を超えたら止めるか
  • 緊急時にすべての新規取引を止められるか

といった部分です。

現在は、この資金管理・損失制限・緊急停止の仕組みを作る段階に入っています。

それが完成したら、いよいよ実際のお金を使わないPaper Tradingへ進む予定です。


まとめ

証券会社APIから実際の市場データを取得できても、それだけでは自動売買を始められませんでした。

今回の開発では、

  • 認証情報を不用意に残さない
  • 証券会社と自分の記録が違えば止める
  • 注文結果が分からなければ再送しない
  • 二重注文を防ぐ
  • 古い承認を使わない
  • 異常な市場データでは注文しない
  • 再取得してよいエラーを限定する
  • 注文直前にも状態を確認する

といった安全対策を追加しました。

最終的には既存機能を含む494件のテストをすべて通過しています。

バックテストでは、

「どう売買すれば利益が残るか」

を中心に考えてきました。

実運用に近づくにつれて、それと同じくらい、

「どんなときには売買してはいけないか」

を決めることが重要になってきました。

次は資金管理と緊急停止の仕組みを作り、Paper Tradingへ進む準備を続けます。

自動売買ツール開発の現在地

バックテスト・売買ルールの検証
✓ 完了

↓

実運用を想定した売買システムの土台
✓ 完了

↓

証券会社API・実際の市場データ取得
✓ 完了

↓

誤発注・異常データ・セキュリティ対策
✓ 今回ここまで

↓

資金管理・損失上限・緊急停止機能
→ 開発中

↓

実際のお金を使わないPaper Trading

↓

少額で、注文前に自分で確認する実運用

↓

実運用の結果を確認しながら段階的に自動化

コメント

タイトルとURLをコピーしました