本文へスキップ
hdknr blog
戻る

kabuステーションAPI はクラウド API ではない — localhost:18080 に立つサイドカー型の正体

免責事項: 本記事は技術的な解説であり、特定の投資戦略や銘柄を推奨するものではない。API を介した自動売買には、プログラムの不具合による意図しない発注のリスクが伴う。必ず検証環境と少額から始め、投資判断は自己責任で行うこと。

日本株の自動売買を考えると、必ず候補に挙がるのが三菱UFJ eスマート証券(旧 auカブコム証券)の API だ。ところが公式サイトを開くと、いきなり足をすくわれる。三菱UFJ eスマート証券のAPI 紹介ページ には「個人のお客さまは『kabu STATION API』をご利用ください」と書かれている。つまり、あのページで説明されている API は個人が契約できないものなのだ。

同じブランド名の下に、設計思想が正反対の 2 つの API がある。この記事では両者を切り分けた上で、個人が実際に使う kabuステーション®API のアーキテクチャと、それが自動売買プログラムの設計に課す制約を一次情報から整理する。

要するに

法人向け API と個人向け kabuステーションAPI を混同しない

まず 2 系統の違いを図と表で押さえる。

法人向け三菱UFJ eスマート証券APIと個人向けkabuステーションAPIの接続形態を左右に並べた比較図。法人向けは事業者のサーバからインターネット経由でOAuth 2.0認可を受けて証券基幹システムRAIDENに接続する。個人向けは1台のWindows PC内で自作プログラムがlocalhost:18080のkabusapiを叩き、GUIアプリkabuステーションを経由して基幹システムに到達する

三菱UFJ eスマート証券のAPI(法人向け)kabuステーションAPI(個人向け)
契約主体法人口座が必須。個人口座は申込不可個人口座で可。法人口座の開設は不要
手続きメール申請 → 一次審査 → 来社面談 → 契約 → 仕様書送付ログイン後の電子契約のみ(書面・捺印なし)
接続形態サーバ間接続。OAuth 2.0。投資法人・投信運用業者には専用線/広域イーサネットも選択可同一 PC の localhost:18080
発注操作発注・訂正・取消発注・取消(訂正なし)
PUSH 配信時価・注文状態変更・建玉状態変更時価のみ
対象商品株式、先物・オプション、投資信託、FX、プチ株®株式、先物、オプション
費用契約・審査・利用はいずれも無料Professional / Premium プラン適用で無料

法人向け API は 2012 年提供開始で、2018 年 7 月に AWS ベースの新基盤と OAuth 2.0 を採用している。想定利用者はプロップファーム、投資助言事業者、取引ツール開発業者、ロボアドバイザー運営業者といった「ツールを作って第三者に提供する側」だ。だから審査と面談がある。

一方 kabuステーションAPI は「自分のためのプログラムを自分で書く個人」向けの窓口である。自作ツールを他人に提供したいなら、個人であっても法人口座を開いて法人向け API の審査を受ける、という線引きになっている。

なお公式ページには主要ネット証券の API 提供状況の比較表もある。2026 年 7 月現在、株式と先物・オプションの両方に対応しているのは同社のみとされている(SBI 証券は先物・オプションのみ、マネックス証券は参照系のみ、楽天証券・松井証券は提供なし)。米国株を含めた選択肢は moomoo証券が米国株API取引に対応 — moomoo OpenAPIで個人投資家も自動売買が可能に も参照してほしい。

サイドカー型アーキテクチャという正体 — Docker・別 PC から叩けない理由

kabuステーションAPI で最も重要な事実は、これがクラウド API ではないということだ。

Windows アプリの kabuステーション を起動して API を有効化すると、そのプロセスがローカルに HTTP サーバを立てる。自作プログラムはそこへリクエストを投げ、kabuステーション が証券基幹システムへ中継する。

本番環境  http://localhost:18080/kabusapi
検証環境  http://localhost:18081/kabusapi
PUSH     ws://localhost:18080/kabusapi/websocket

公式 FAQ はこの構造を明言している。

kabuステーション®APIを使ったリクエストは、kabuステーション®を通してリクエストしています。kabuステーション®APIをご利用になる際は、常にkabuステーション®を起動しておく必要があります。

そして次の一文が、インフラ構成を決定的に縛る。

kabuステーション®APIはkabuステーション®と同一IPからのリクエストのみを受け入れます。そのため、同一PCでご使用ください。

つまり Linux サーバや Docker コンテナから叩く構成は取れない。「Mac で開発して Linux サーバで本番運用」もできず、アプリと同じ Windows マシンの中にプログラムを置くしかない。ポートフォワードで外から繋ぐ抜け道も、公式が明言しているのは「同一 IP のみ受付」までだが、同一 PC での利用を指示している以上は想定外の使い方になる。

VPS・クラウド Windows で動かせるか

GitHub の公式サポート窓口で明確な回答が出ている(issue #1314)。

VPS で回すこと自体は否定されていないが、「Windows デスクトップセッションを維持し続ける」という前提が消えないため、Linux の systemd サービスのような運用感にはならない。

kabuステーションAPI の開通手順 — 電子契約と API システム設定

設定が 2 段階に分かれているのもサイドカー型ゆえだ。証券会社側の契約と、手元の GUI アプリ側の設定という二重の関門になる。片方だけでは動かない。

1. マイページでの利用設定

メンバーズサイト(PC 版)にログインし、「設定・申込」→「らくらく電子契約」→「取引ツール」の設定 → 「kabuステーションAPI利用設定」から、設問に回答して利用規定に同意する。書面や捺印は不要だ。完了後、電子契約画面が「利用可」と表示されていることを確認する。

ここで注意したいのは、申込が完了しても条件を満たしていなければ「利用不可」と表示される点だ。API 利用には Professional プランまたは Premium プランが必要で、Professional プランの継続条件は次の 2 つを両方満たすことである。

なお約定回数のカウントには除外がある。国内信用取引の品受・品渡、先物取引の SQ 決済、株式公開買付(TOB)、外貨の取引は含まれない。

初回ログイン時は Professional プランが自動適用され、翌々月第 1 営業日まで使える。この猶予期間中に条件を整えないと、ある日突然「利用不可」に落ちることになる。

2. kabuステーション側の API システム設定

kabuステーション を起動し、画面右上の </> アイコンを右クリックして「APIシステム設定」を開く。

再起動後、右上のアイコンが緑になれば API が使える状態だ。ソフトリミットは現物・信用が万円単位、先物・オプションが枚単位で、/apisoftlimit から現在値を取得できる。プログラムのバグによる暴走を止める最後の砦なので、本番前に必ず妥当な値へ落としておきたい。実際にどんな壊れ方をするかは Claude Codeで東証の株取引を半自動化する【ペーパートレードで-19万円編】 に生々しい記録がある。

Python での最小実装 — トークン発行・時価取得・発注

BASE が localhost である点を除けば、呼び出し自体はふつうの REST だ。認証は API パスワードをトークンに交換する方式で、以降のリクエストは X-API-KEY ヘッダにトークンを載せる。

import requests

BASE = "http://localhost:18080/kabusapi"  # 検証は 18081

# 1. トークン発行
auth = requests.post(
    f"{BASE}/token",
    json={"APIPassword": "your-api-password"},
).json()
assert auth["ResultCode"] == 0, auth

headers = {"X-API-KEY": auth["Token"], "Content-Type": "application/json"}

# 2. 時価・板情報(銘柄コード@市場コード の形式)
board = requests.get(f"{BASE}/board/9433@1", headers=headers).json()
print(board["CurrentPrice"])
print(board["BidPrice"])  # 注意: これは「売気配」。下記参照
print(board["AskPrice"])  # 注意: これは「買気配」

Bid と Ask が逆になっている

/board のレスポンスには、仕様書自身が謝罪付きで告知している既知の不整合がある。

※①:レスポンスにある「Bid」と「Ask」は、本来の意味である「買気配」と「売気配」と逆になっております。実際に返却される値は日本語の説明に準じたものになりますので、ご注意いただきますようお願い申し上げます。

影響を受けるのは BidQty / BidPrice / BidTime / BidSign と AskQty / AskPrice / AskTime / AskSign だ。英語のキー名を信じて実装すると、売買を取り違えたまま動く。仕様書の日本語説明(BidPrice = 最良売気配値段、AskPrice = 最良買気配値段)が正である。ラッパー層で名前を付け替えてしまうのが安全だろう。

発注は POST /sendorder。必須項目が多く、現物と信用で指定すべき値が変わるのが厄介なところだ。

order = {
    "Symbol": "9433",
    "Exchange": 9,          # 9=SOR, 27=東証+, 1=東証
    "SecurityType": 1,      # 株式
    "Side": "2",            # 1=売, 2=買
    "CashMargin": 1,        # 1=現物, 2=信用新規, 3=信用返済
    "DelivType": 2,         # 現物買は必須。2=お預り金
    "FundType": "AA",       # 現物買は必須。AA=信用代用, 02=保護
    "AccountType": 4,       # 2=一般, 4=特定, 12=法人
    "Qty": 100,
    "FrontOrderType": 20,   # 20=指値, 10=成行
    "Price": 2000,          # 成行なら 0
    "ExpireDay": 0,         # 0=「本日」。引け後は翌取引所営業日として扱われる
}
order_res = requests.post(f"{BASE}/sendorder", headers=headers, json=order).json()

レスポンスで返る OrderId が、以降の取消と照会で注文を指すキーになる。

{"Result": 0, "OrderId": "20200529A01N06848002"}

型指定にも注意が必要だ。ほとんどのコード値は整数なのに、Side(売買区分)と FundType(資産区分)だけは文字列型で定義されている。"Side": 2 と書くとエラーになるので、仕様書の type を確認しながら組む必要がある。

FrontOrderType は執行条件の指定で、値の体系はこうなっている。

系統定義値Price の指定
成行系10 成行 / 13〜16 寄成・引成 / 17 IOC成行0
指値系20 指値 / 21〜24 寄指・引指 / 25・26 不成 / 27 IOC指値発注したい金額
逆指値30指定なし(ReverseLimitOrder の AfterHitPrice で指定)

取消は PUT /cancelorder に OrderId だけを渡す。

requests.put(f"{BASE}/cancelorder", headers=headers, json={"OrderId": order_res["OrderId"]})

市場コードは情報系と発注系でズレる

Exchange には仕様書上の非対称性がある。発注時についてはこう書かれている。

※SORまたは、東証+がメンテナンス中は現物のみ東証への指定が可能です。通常時に東証を指定しての新規発注はできません。

一方、/board/{symbol} や /timeandsales/{symbol} のパスパラメータは [銘柄コード]@[市場コード] 形式で、こちらには次の注記が付く。

※SOR市場は取扱っておりませんのでご注意ください。

つまり板情報は東証(@1)で取り、発注は SOR(9)か東証+(27)で出すという非対称な使い分けになる。同じ「市場コード」という名前の値を、用途によって読み替える必要がある。

信用返済にも別の縛りがある。東証で保有している建玉は SOR や東証+では返済できない。建玉を建てた市場を記録しておかないと返済で詰まる。

PUSH 配信は「時価だけ」

ここが最も誤解されやすい点だ。kabuステーションAPI の WebSocket で流れてくるのは時価・板情報だけである。

流れは次のとおり。

  1. PUT /register に銘柄リストを登録する
  2. ws://localhost:18080/kabusapi/websocket に接続する
  3. 登録銘柄の時価が更新されるたびに JSON が届く

PUSH API リファレンス が定義するフィールドは 63 項目あるが、銘柄コードや市場名といった識別子を除けば、すべて現値・気配・板 10 本・売買高・VWAP・オプションのグリークスといった価格情報だ。注文状態変更や建玉状態変更の PUSH は用意されていない。それらは法人向け API の機能である。

自動売買では「発注した注文が約定したか」を知る必要があるが、それは GET /orders(注文約定照会)を自分でポーリングして追うことになる。「REST + WebSocket Push で発注と約定通知の両方を扱える」という説明は、この API には当てはまらない。自分が過去に書いた 日経225マイクロ先物 × Monte Carlo 自動売買判定 と wiki の kabu ステーション API のページ はこの点で不正確なので、ここで訂正しておく。

PUSH の実務的な仕様も次のとおりだ。

50 銘柄という枠には、さらに見落としやすい仕掛けがある。仕様書の「情報」タグにはこうある。

リクエストされた銘柄は自動でAPI登録銘柄リストに登録されます。

/board や /symbol を叩いただけで登録枠を消費するのだ。銘柄スクリーニングのつもりで多数の銘柄に問い合わせると、PUSH 対象にしたい銘柄が枠から溢れる。PUT /unregister と PUT /unregister/all で明示的に掃除する設計にしておく必要がある(解除系も含め、この API に DELETE メソッドのエンドポイントは 1 つも無い)。これを踏み抜いて 51 件目以降が全部エラーになった実例が ペーパートレードで-19万円編 にある。

トークンは毎朝切れる — 401 を日課として扱う

サイドカー型の帰結として、運用は「1 日 1 サイクル」を前提に組むしかない。

kabuステーションAPIの1日の運用サイクルを示したタイムライン図。早朝6時から6時30分頃の強制ログアウト、その後の再ログインとトークン再発行、9時から11時30分の前場でPUSH配信あり、11時30分から12時30分の場間は配信なし、12時30分から15時30分の後場で配信あり、引け後は翌6時15分まで配信なしという流れが並び、翌朝また同じ手順に戻ることを示す破線の矢印が伸びている。下部にAPIトークンが無効になる4つの契機と、それを踏まえた設計上の帰結が列挙されている

トークンの寿命について、仕様書は次の 4 つの失効契機を挙げている。

・kabuステーションを終了した時 ・kabuステーションからログアウトした時 ・別のトークンが新たに発行された時 ※kabuステーションは早朝、強制的にログアウトいたしますのでご留意ください。

kabuステーション の利用可能時間は 6:30 から翌早朝 6:15 まで(メンテナンス日を除く)で、毎朝 6:00〜6:30 頃に強制ログアウトが走る。前日からログイン状態を維持して翌営業日まで連続運転することはできない。「毎朝起動して夕方に終了する」運用を組むなら、Windows のタスクスケジューラを使うことになる(WSL2 の sshd を Windows 起動時に自動起動する で扱ったセッション周りの罠がそのまま効いてくる)。

「別のトークンが新たに発行された時」も見落としやすい。同時に複数の kabuステーション を起動して API を使うことはできず、開発用スクリプトをうっかり二重起動すると、後から発行したトークンが先のトークンを黙って無効化する。401 の原因がここにあると気づくまで時間を溶かしやすい。

設計への帰結はシンプルだ。

流量制限(発注 5 件/秒)と冪等性 — 訂正 API がない前提の再送設計

ここまではサイドカー型アーキテクチャの直接の帰結だった。以下は、それとは別に効いてくる API 設計上の割り切りである。

流量制限は 5 件/秒で設計する

公式 FAQ と仕様書の記載を突き合わせるとこうなる。

API 種別上限出典
発注5 件/秒FAQ
取引余力・情報・銘柄登録10 件/秒FAQ
歩み値取得(/timeandsales)2 件/秒仕様書の /timeandsales の説明

ここで注意点がある。OpenAPI 仕様書のタグ説明には「発注系のリクエストは秒間10件の流量制限を設けています」と書かれており、FAQ の 5 件/秒と食い違う。ただし issue #1210 での公式回答は「あくまで『1秒間あたりの発注件数を5件以内』という流量の制限」と述べている。保守的に 5 件/秒で設計するのが安全だ。同じ回答では「同一銘柄への同時注文件数に上限はない」ことも明言されている。ただし信用返済は例外で、注文受付時に返済建玉が拘束されるため、同じ建玉に対する返済注文を複数出すことはできない。

冪等キーは存在せず、訂正もできない

同じ issue で、冪等性について踏み込んだ回答が出ている。

拒否・失効の見分け方と注文の繰越

拒否(reject)の検知は一手間かかる。証券会社側でのエラー(余力不足・銘柄停止・価格制限超過・信用枠不足など)は発注レスポンスで返るが、そもそも注文が成立していないので /orders に該当データが存在しない。

取引所側のエラーは /orders に載る。ただし State=5(終了)には発注エラー・取消済・全約定・失効・期限切れが全部混ざっており、State だけでは判別できない。公式回答が示す判定方法は、Details[] の SeqNum が最大のレコードの Details[].State が 4(エラー)かを見るというものだ。

繰越の挙動も把握しておこう。当日限りの注文は引け後に失効して OrderState=5 になり、有効期限が翌営業日以降の注文は未約定のまま繰越されて OrderState=1(待機)になる。自動取消にあたる仕組みはない。

公式サポートは GitHub Issues

この API のもう一つの特徴が、サポート窓口が github.com/kabucom/kabusapi の Issues であることだ。2020 年 8 月に作られたリポジトリで、中身はポータルの静的サイトと言語別サンプルだけだ。クライアントライブラリ本体は無く、Issues がそのまま Q&A 掲示板として運用されている。

仕様書に書かれていない挙動——建玉反映の遅延、逆指値のトリガー後の状態、15:25 以降の取消挙動など——は、たいてい過去の issue で誰かが質問済みだ。実装前に検索する価値は高い。トラブル時のログは %appdata%\KabuS\Log(デバッグログ)と %appdata%\KabuS\Log\APILog(API ログ)にある。

なお開発者ポータルの利用規定には、投稿内容の著作権が同社に帰属する旨や、個別銘柄の推奨・相場動向の断定的判断の投稿禁止といった条項があるので、質問を書くときは目を通しておきたい。

まとめ:自動売買に織り込むべき制約

kabuステーションAPI は、個人が日本株・先物・オプションをプログラムから発注できる数少ない選択肢であり、電子契約だけで開通する手軽さは大きい。だが「証券会社の Web API」という言葉から想像する姿とはかなり違う。

実像は Windows GUI アプリのサイドカーだ。制約は性質ごとに 3 つに分けて理解するとよい。

性質制約
サイドカー型アーキテクチャの直接の帰結同一 PC・同一 IP 制約、GUI の常時起動、毎朝の強制ログアウトとトークン失効、WebSocket 1 本
法人向け API との提供範囲の差訂正 API の不在、時価のみの PUSH、投信・FX 発注の非対応
API 設計上の割り切り冪等キーの不在、発注 5 件/秒の流量制限、State だけでは reject を判別できない

いずれも回避策を探すべきバグではなく、最初から設計に織り込むべき仕様である。

逆に言えば、ここを織り込んだ上で「毎朝起動して夕方に終了する、状態を外部に持つ、約定は自分でポーリングする」という素朴な形に落とせば、想像よりずっと安定して回る。事業として第三者にツールを提供する段階になったら、そのときこそ法人向け API の審査を受ければよい。

参考リンク



前の記事
NEC「部署が丸ごとAI」の中身 — コーポレートAI・Workforce部門の4階層と、人が手放さなかった仕事
次の記事
Mac から Windows の共有に繋がらない — WFP まで降りて犯人(ノートンのスマートファイアウォール)を特定した話