導入チュートリアルPython 3.11 · websockets 12
Python WebSocket 相場購読と自動再接続の実装
Python の websockets ライブラリでリアルタイム相場購読、定期ハートビート送信、指数バックオフ再接続、自動再購読を実装する完全ガイド。
更新日時:
保守運営:AllTick 公式エンジニアリングチーム
対象読者:リアルタイム相場ストリームを受信する Python エンジニア
要約 · 30秒開発サマリー
本番運用に耐える WebSocket 相場クライアントには4つの要素が不可欠です:(1) 接続直後の購読メッセージ送信、(2) 一定間隔のハートビート送信、(3) 切断時のジッター付き指数バックオフ再接続、(4) 再接続成功後の自動再購読です。以下では AllTick 株式 WebSocket API を例に実装します。
01
プロトコルの要点
| 項目 | AllTick における仕様 |
|---|---|
| 株式 WebSocket URL | wss://quote.alltick.co/quote-stock-b-ws-api?token=あなたのToken |
| 為替・貴金属・コモディティ URL | wss://quote.alltick.co/quote-b-ws-api?token=あなたのToken |
| 最新約定の購読コマンド | cmd_id 22004、data.symbol_list に銘柄配列を指定 |
| ハートビート | cmd_id 22000、公式サンプルでは10秒ごとに送信 |
02
完全な実行可能コード
ターミナルコマンドbash
pip install websocketsstream_quotes.pypython
import asyncio, json, os, random, uuidimport websocketsWS_URL = "wss://quote.alltick.co/quote-stock-b-ws-api?token={token}"CMD_SUBSCRIBE_TRADE = 22004CMD_HEARTBEAT = 22000HEARTBEAT_SECONDS = 10CODES = ["700.HK", "AAPL.US"]def message(cmd_id: int, data: dict) -> str: return json.dumps({"cmd_id": cmd_id, "seq_id": 1, "trace": str(uuid.uuid4()), "data": data})async def heartbeat(ws): while True: await asyncio.sleep(HEARTBEAT_SECONDS) await ws.send(message(CMD_HEARTBEAT, {}))async def run_once(url: str): async with websockets.connect(url, ping_interval=None) as ws: await ws.send(message(CMD_SUBSCRIBE_TRADE, {"symbol_list": [{"code": c} for c in CODES]})) beat = asyncio.create_task(heartbeat(ws)) try: async for raw in ws: handle(json.loads(raw)) finally: beat.cancel()def handle(msg: dict): if msg.get("cmd_id") == CMD_HEARTBEAT + 1: return print(msg)async def main(): token = os.getenv("ALLTICK_API_TOKEN", "YOUR_API_TOKEN") url = WS_URL.format(token=token) delay = 1 while True: try: await run_once(url) delay = 1 except (websockets.WebSocketException, OSError) as exc: wait = min(delay, 60) + random.uniform(0, 1) print(f"切断検出: {exc!r}、{wait:.1f} 秒後に再接続します") await asyncio.sleep(wait) delay *= 2if __name__ == "__main__": asyncio.run(main())03
コード設計のポイント
- 購読処理を run_once の内部に配置しているため、再接続のたびに自動的に再購読が行われ、「接続済みだがデータが来ない」状態を防ぎます。
- 再接続待機時間は1秒から倍増(最大60秒)し、ランダムなジッターを加えることで一斉再接続の集中を回避します。
- ハートビートタスクは接続終了時に finally ブロックで確実にキャンセルされます。
- ping_interval=None でライブラリの自動 ping を無効化し、アプリケーション層のハートビート(cmd_id 22000)に統一しています。
- handle 関数内でハートビート応答をフィルタリングし、相場データのみを処理します。
04
本番稼働前のチェック項目
1print を構造化ログに置き換え、切断理由と再接続所要時間を記録する。
2連続再接続失敗回数にしきい値を設け、アラートを通知する。
3再接続完了後、切断期間中のローソク足を REST API で補完する。
41接続あたりの購読銘柄数を契約プランの上限内に収める。
仕様出典と検証記録 · 2026-10-13
以下の一次資料で関連するエンドポイント、フィールド、取引所規則を確認しました。
Python コードは Python 3.14.0 の ast.parse で構文解析を通過しました。依存関係、実行互換性、ネットワーク応答の検証は含みません。
今回の確認では実際の Token による AllTick 要求や本番エンドツーエンド試験は実行していません。再現時にプラン、ライブラリ版、取引時間、ret/trace、結果を記録してください。
一次資料
導入前に再現する項目
- 10 秒ごとに cmd_id 22000 を送り 22001 を確認します。文書上の閾値は 30 秒です。古い心拍タスク停止後に再接続します。
- 復旧後に再購読して応答を確認し、上限付きジッター再試行で並列再接続による接続枠超過を防ぎます。