トス証券 Open API は何を開くのか
API は人の代わりにプログラムが叩く窓口だ。普段アプリの画面で手作業していた照会や発注を、決められた形式のリクエストで送れるように証券会社が開けた扉だと考えればよい。アプリ画面を自動でクリックする裏技と違い公式の経路なので、口座が制限される心配がない。
機能は五つに分かれている。認証(Auth)、相場・銘柄情報(Market Data・Stock Info・Market Info・Market Indicators・Ranking)、口座・資産(Account・Asset)、注文(Order・Order History・Order Info)、条件注文(Conditional Order・Conditional Order History)だ。対象は韓国(KRX)と米国株式である。
相場・銘柄情報は全ユーザーに同一で提供される客観データなので、トークンだけで呼び出せる。現在値・板・約定・ローソク足(1分足と日足)・値幅制限、銘柄マスタ、買付時の注意事項、為替、韓国と米国の市場カレンダー、売買代金や騰落率のランキング、指数と投資主体別売買代金まで含まれる。
一方で口座・資産、注文、条件注文は自分の口座を直接動かすため、トークンに加えて口座識別ヘッダーが要る。この記事の本題はこちら側だ。
接続方式は現在 REST のみ。リアルタイム配信用の WebSocket は今後対応予定と記載されているため、今は必要な時点で照会するポーリング方式で組むことになる。
どこで、どう申請するのか
申請窓口は開発者向けの申請フォームではなく、トス証券のウェブ取引画面 WTS(tossinvest.com)だ。トス証券の口座がある状態でログインし設定に入ると Open API の項目があり、そこで client_id と client_secret を自分で発行する。審査待ちはなく画面上で完結する。
client_id が ID、client_secret がパスワードに当たる。secret は発行画面を離れると再表示できない場合が多いので、その場で安全な場所に控える。
二つ目の手順が本当の関門だ。同じ画面の下にある許可 IP 管理で、API を呼び出す IP を登録する。登録されていない IP から呼ぶと、鍵が正しくても 403 で遮断される。自分のグローバル IP はターミナルで curl ifconfig.me の一行で確認できる。
自宅やオフィスの回線はグローバル IP が変わり得る点も先に知っておくとよい。ある日突然 403 が出たら、たいていは鍵ではなく IP が変わっている。サーバーやクラウドで自動化を動かす予定なら、その機器の送信元 IP を登録する。
アカウントごとに順次開放される仕組みのため、設定に Open API メニューが見えなければまだ自分の番が来ていない。その場合は案内バナーの事前申請で待機登録しておくと、開放時に通知が届く。
トークンを取得して最初の呼び出しをする
すべての呼び出しは OAuth 2.0 のアクセストークンを必要とする。発行方式は Client Credentials Grant で、人がログイン画面を通るのではなく、プログラムが自分の ID とシークレットでトークンを受け取る方式だ。だから無人自動化に向く。
性質は三つ覚えれば足りる。有効期限は 86400 秒、つまり 24 時間。リフレッシュトークンはないので、期限が切れたら同じエンドポイントで取り直す。そしてクライアントごとに有効なトークンは一つだけで、新たに発行すると直前のトークンは即座に無効になる。複数のスクリプトがそれぞれトークンを取ると互いを無効化してしまうので、発行したトークンはファイルにキャッシュして期限まで共有するほうがよい。
公式ガイドの例は client_id と client_secret をリクエストボディに載せる方式だ。ただし私の環境ではボディ方式が invalid_client で拒否され、HTTP Basic 認証ヘッダーで発行に成功した。通るほうを使えばよい。
トークンを得たら、口座に触れない照会から始める。銘柄情報や現在値はトークンだけで呼べる。次に口座一覧を照会すると accountSeq という番号が得られ、これが以降の保有株・注文・条件注文で使う X-Tossinvest-Account ヘッダーの値になる。
# 1) トークン発行(公式例:ボディ方式)
curl -s -X POST 'https://openapi.tossinvest.com/oauth2/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET'
# invalid_client で弾かれる場合は Basic ヘッダー方式
curl -s -X POST 'https://openapi.tossinvest.com/oauth2/token' \
-u "$TOSS_API_KEY:$TOSS_SECRET_KEY" \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials'
# 2) 銘柄情報(トークンのみ)
curl -s 'https://openapi.tossinvest.com/api/v1/stocks?symbols=005930' \
-H "Authorization: Bearer $TOKEN"
# 3) 保有株(トークン + 口座ヘッダー)
curl -s 'https://openapi.tossinvest.com/api/v1/holdings' \
-H "Authorization: Bearer $TOKEN" \
-H 'X-Tossinvest-Account: 1'Claude Code と Codex とは何か、どう入れるか
Claude Code は Anthropic、Codex は OpenAI が作ったターミナル用の AI コーディングエージェントだ。チャット欄でコードをもらって自分で貼り付けるのではなく、エージェントが自分のパソコン上でファイルを読み書きしコマンドを実行する。だから、ドキュメントを読み、コードを書き、実行して結果を確かめるという繰り返しになる API 連携に向いている。
Node.js が入っていればインストールは一行だ。npm install -g @anthropic-ai/claude-code もしくは npm install -g @openai/codex を実行し、claude または codex コマンドで起動する。初回起動でログインか API キー登録を求められ、Claude Code は有料の Claude サブスクリプション、Codex は ChatGPT アカウントか OpenAI API キーで認証する。
どちらか一つで十分だ。あえて両方使うなら、一方が書いたコードをもう一方に点検させるクロスチェックのためだ。発注を扱うコードなら、その点検は元が取れる。
ここで必ず守る原則が一つある。発行した鍵は .env ファイルに保存し、そのファイルを .gitignore に入れてリポジトリに上がらないようにする。チャット欄やコードの中に鍵を直接書かない。証券口座の鍵は、漏れれば他人が自分の口座で発注できる種類の秘密だ。
もう一つ、承認なしにすべてのコマンドを実行するモードのまま発注 API を扱わない。便利さのためにそのモードを使う人は多いが、実発注が可能な環境ではコマンドごとに確認を取る既定のほうが正しい。
# ターミナル AI エージェント(Node.js が必要)
npm install -g @anthropic-ai/claude-code # 実行: claude
npm install -g @openai/codex # 実行: codex
# 鍵は .env に置きリポジトリから除外する
cat >> .env <<'EOF'
TOSS_API_KEY=発行された_client_id
TOSS_SECRET_KEY=発行された_client_secret
EOF
echo '.env' >> .gitignoreエージェントに何を頼めばよいか
まず頼むべきは公式ドキュメントを読ませることだ。トス証券は機械可読な形式のドキュメントを別途公開しており、仕様の原本 JSON とマークダウン概要がある。その URL を伝えれば、エンドポイントやリクエスト形式を推測せずに正確に合わせてくる。
次は照会から。「.env から鍵を読み、保有銘柄と評価損益を表で出すスクリプトを作って」と頼めば、トークン発行とキャッシュ、口座照会、保有株照会をまとめたスクリプトが出てくる。実行してアプリ画面と数字を目で突き合わせる。この照合を飛ばすと、以降の自動化すべてが未検証の土台の上に積み上がる。
照会が合ったら売買ルールを言葉で説明する。たとえば「高値から 20 パーセント下げたら全部売る」といったものだ。重要なのはルールをどうコードにするかではなく、そのルールがいつ、どの値を基準に判定されるのかを自分が正確に言えるかどうかだ。終値基準か場中価格基準か、一日に何回確認するか、といった点である。
最後に、繰り返し使う作業はエージェントのスキルやコマンドファイルとして固めておく。毎回同じ説明をしなくて済み、安全ルールもその中に一緒に書き込める。
発注を任せる前に置くべきゲート
照会が通った瞬間に発注も通る。同じトークン、同じヘッダーで POST を一度投げれば実際の約定だ。だから発注コードを書く前に安全装置を先に決めておくほうがよい。
安全装置は二層に分けて考えると整理できる。API が既定で提供する層と、自分がスクリプトに載せる層だ。
API 側の代表格が冪等キーだ。注文作成リクエストに clientOrderId を入れておけば、ネットワーク障害で同じリクエストが二度出ても注文は一度しか受け付けられない。同じキーで内容の違う注文を送ると拒否されるので、取り違えも捕まえられる。注文金額が 1 億ウォン以上なら confirmHighValueOrder を true にしないと受け付けない仕組みもある。
私が載せた層はこうだ。既定は常に練習モードで、引数だけでは注文が出ない。実発注は実行フラグと銘柄一致確認を同時に要求する。注文金額の上限をファイルに書いておき、超えたら別フラグなしには拒否する。成行は明示したときだけ開き、既定は指値だ。発注前に、買いは可能金額を、売りは売却可能数量を先に照会して確認する。
この層はそれぞれ自分のコードに合わせて作ればよい。形よりも原則が重要だ。実発注は人がもう一度明示的に確認してから出る、そして自動化が自分の判断で上限を超えられないようにする。
| 層 | 装置 | 何を防ぐか |
|---|---|---|
| API 既定 | clientOrderId 冪等キー | 再送で同じ注文が二度受け付けられること |
| API 既定 | confirmHighValueOrder | 1 億ウォン以上の注文が確認なしに出ること |
| API 既定 | 買付可能金額・売却可能数量の照会 | 残高を超える注文をそのまま投げること |
| 自分のスクリプト | 練習モード既定 | 引数の入力ミスで実発注が出ること |
| 自分のスクリプト | 実行フラグと銘柄確認の同時要求 | 別の銘柄に注文が出ること |
| 自分のスクリプト | 注文金額の上限 | 自動化が意図より大きい金額を執行すること |
| 自分のスクリプト | 既定は指値、成行は明示時のみ | 板が薄いときに成行で押し込まれること |
curl -s -X POST 'https://openapi.tossinvest.com/api/v1/orders' \
-H "Authorization: Bearer $TOKEN" \
-H 'X-Tossinvest-Account: 1' \
-H 'Content-Type: application/json' \
-d '{
"symbol": "005930",
"side": "BUY",
"orderType": "LIMIT",
"quantity": 10,
"price": "70000",
"clientOrderId": "my-order-20260725-001"
}'条件注文 — 監視を証券会社のサーバーに任せる
損切りや利確を自動化するには、普通は価格を見張り続けるプログラムが要る。問題は、そのプログラムが動くパソコンが落ちたりスリープすると監視が止まることだ。条件注文はこの監視を証券会社のサーバーに渡す。
タイプは三つ。SINGLE は条件を一つだけ監視する。OCO は二つの条件を同時に監視し、どちらかが成立すると残りを自動で取り消す。損切り線と利確線を一緒に置く典型的な使い方で、二つとも売りであり、第一の監視価格は現在値より高く、第二は現在値より低い必要がある。OTO は第一の条件が約定してから第二の条件の監視を始める。第一が買い、第二が売りという構造なので、入りと出をまとめて登録できる。
制約も知っておきたい。OCO と OTO は指値のみ対応で、同一銘柄にグループ条件注文は一つしか置けない。すでに条件を満たした価格で登録すると拒否される。SINGLE には銘柄あたりの本数制限がない。
自作の監視プログラムと比べるとトレードオフは明確だ。条件注文はサーバーが監視するので自分のパソコンの状態に左右されず、反応も速い。代わりに条件は単純な価格水準に限られる。移動平均や新高値更新のように計算が必要な条件は、依然として自分の側で判定して発注することになる。実務的には、損切り・利確のような防衛線は条件注文に任せ、計算が要る入りの判断だけ自分のスクリプトが担う組み合わせが扱いやすい。
curl -s -X POST 'https://openapi.tossinvest.com/api/v1/conditional-orders' \
-H "Authorization: Bearer $TOKEN" \
-H 'X-Tossinvest-Account: 1' \
-H 'Content-Type: application/json' \
-d '{
"symbol": "005930",
"type": "SINGLE",
"quantity": 100,
"orderType": "LIMIT",
"clientOrderId": "my-cond-20260725-001",
"expireDate": "2026-09-10",
"first": {
"orderSide": "SELL",
"triggerPrice": "295",
"orderPrice": "295"
}
}'呼び出し上限とエラーの扱い方
すべての API はクライアントと API グループ単位で毎秒のリクエスト数が制限される。相場は毎秒 10 回、注文は毎秒 6 回だが、寄り付き直後の 09:00 から 09:10 までは毎秒 3 回に下がる。口座一覧の照会は毎秒 1 回と最も厳しいので、口座番号のようにほとんど変わらない値は一度取ってキャッシュするのが正しい。
上限を超えると 429 が返る。レスポンスヘッダーの Retry-After の分だけ待って再試行し、繰り返すなら 1 秒、2 秒、4 秒と間隔を広げ、わずかなランダム遅延を混ぜる。正常応答にも残りリクエスト数がヘッダーで返るので、その値が減ってきたら先回りして速度を落とすほうが安全だ。
エラーは形式が一定なので code だけ見て分岐すればよい。トークンが期限切れなら expired-token、残高が足りなければ insufficient-buying-power、受付時間外なら order-hours-closed、値幅制限を外れれば price-out-of-range、同じ冪等キーで内容が違えば idempotency-key-conflict が返る。問い合わせが必要になったら応答の requestId を添えるとよい。
エージェントにスクリプトを任せるときは、このエラー処理を最初から要求するのがよい。ただ作ってと頼むと成功経路だけ書きがちで、その状態で定期実行に載せると静かに失敗する。
まとめると、この順序で始めればよい
第一に、トス証券 WTS の設定で Open API の鍵を発行し、許可 IP を登録する。第二に、ターミナルで curl を使ってトークンを取り、銘柄情報を一件照会してみる。ここまでが接続確認だ。
第三に、Claude Code か Codex を入れ、鍵を .env に置いて保有株照会のスクリプトを作らせ、アプリ画面と数字を突き合わせる。第四に、発注スクリプトを作るが、練習モードを既定にし実発注ゲートを先に入れる。第五に、ごく小さい数量で実発注を一度出し、訂正と取消まで確認する。第六に、損切り・利確のような防衛線を条件注文に移す。
最後に当たり前だが書いておく。自動売買はルールが間違っていれば、その間違ったルールを速く忠実に繰り返す。最初は必ず少額で、練習モードで十分に回してから実行し、結果の責任は全面的に本人にある。
ルール自体が実際に利益を出したのかを検証する方法、つまり過去データで売買ルールを試すバックテストは次回に扱う。
