取引所

取引所のAPI仕様変更にどう備える?ボットが突然壊れないための設計と点検習慣


※本記事にはアフィリエイト広告(プロモーション)が含まれています。

昨日まで問題なく動いていたボットが、ある日突然エラーを吐いて発注できなくなる。原因を調べてみると、コードのバグではなく取引所側のAPI仕様が変わっていた、というケースは珍しくありません。この記事では、取引所がダウンした時の障害対応とは別の切り口として、「取引所そのものは正常に動いているのに、仕様変更でボットが壊れる」というリスクにどう備えるかを整理します。

API仕様変更とAPI障害は別物

まず区別しておきたいのは、この記事が扱うのは障害・ダウンタイムの話ではないという点です。取引所のAPIは正常に応答しているのに、レスポンスの中身や挙動が変わってしまうことで、ボット側の処理が想定と噛み合わなくなる。これがAPI仕様変更の問題です。

具体的には、次のような変更が起こり得ます。

  • レスポンスに含まれるフィールド名の変更・追加・削除
  • 価格や数量の刻み幅(tick size)、最小注文単位の変更
  • 認証方式やヘッダー仕様の変更
  • レートリミットの方式・上限値の変更
  • 特定のエンドポイントや注文タイプの廃止(ディスコンティニュー)
  • シンボル表記(ペア名)の変更

※取引所のAPI仕様は運営会社の判断で随時変更されることがあります。本記事で挙げている項目はあくまで一般的な分類であり、具体的な仕様は必ず各取引所の公式ドキュメントで最新情報を確認してください。

なぜ気づきにくいのか

API仕様変更がやっかいなのは、「エラーにすらならずに静かに壊れる」パターンがあることです。

  • 例外を投げずに、想定と違う値やnullを返すフィールドがある
  • 注文は通っているように見えて、実際には別の解釈で約定している
  • レートリミットの上限が引き下げられ、しばらくは動くが特定の時間帯だけ失敗が増える

一方で、明確なエラーとして現れるパターンもあります。ccxtを使っている場合、これらの多くは ExchangeErrorInvalidOrder のような例外として表面化しやすく、ccxtのエラーが解決しない?実運用で踏んだ落とし穴で紹介した個別のエラー対処と組み合わせて考えるとよいでしょう。ただし「例外は出ないが挙動だけ変わっている」ケースは、通常のエラーハンドリングでは検知できません。

設計原則1: レスポンスを信用しすぎない

多くのボットは、APIレスポンスのフィールドに response['price'] のように直接アクセスします。この書き方だと、フィールド名が変わった瞬間に KeyError で落ちるか、最悪の場合は黙って None を使って処理が進んでしまいます。

対策として、レスポンスを受け取る境界に簡単な検証層を挟む方法があります。

REQUIRED_TICKER_FIELDS = ('symbol', 'last', 'bid', 'ask', 'timestamp')


def validate_ticker(ticker: dict) -> dict:
    missing = [f for f in REQUIRED_TICKER_FIELDS if ticker.get(f) is None]
    if missing:
        raise ValueError(f'ticker response missing fields: {missing}')
    return ticker


ticker = validate_ticker(exchange.fetch_ticker(symbol))

ポイントは、「フィールドが欠けていたら握りつぶさずに例外を出す」ことです。黙って処理を続けるより、早い段階で気づける方がはるかに安全です。ログの残し方についてはボットのログ設計もあわせて参考にしてください。

設計原則2: 定期的な「疎通チェック」をジョブ化する

仕様変更は、ボットを実際に動かして初めて気づくのではなく、軽量な確認ジョブを定期的に走らせておくことで早期発見できます。たとえば以下のようなチェックを、本番の取引ロジックとは別に用意しておく方法です。

  • fetch_markets() で銘柄一覧と最小注文単位・刻み幅を取得し、前回取得時との差分を比較する
  • fetch_ticker() のレスポンスに想定フィールドが揃っているか検証する
  • 実際に注文は出さず、fetch_balance() など読み取り系のAPIだけを一通り呼んで例外が出ないか確認する

このようなチェックはGitHub Actionsでのデプロイの仕組みを応用して、スケジュール実行するジョブとして組み込むことができます。失敗したらDiscordへの通知で人間に知らせるようにしておけば、実際の取引ロジックが動く前に異常を検知できる可能性が高まります。

# .github/workflows/exchange-health-check.yml (例)
on:
  schedule:
    - cron: '0 */6 * * *'
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: python scripts/check_exchange_schema.py

設計原則3: ライブラリのバージョンを固定し、更新は計画的に

ccxtのような共通ライブラリ経由で取引所APIを叩いている場合、取引所側の仕様変更はccxt側のアップデートで吸収されることも多くあります。しかし裏を返せば、ccxtを何気なくアップデートしただけで、内部の挙動が変わってしまうこともあり得ます。

  • requirements.txt などでバージョンを明示的に固定する
  • アップデートする際は、事前にChangelogやリリースノートで変更内容を確認する
  • 可能であれば本番環境にそのまま適用せず、テストコードでの検証やペーパー環境で一度動作確認してから反映する

「勝手に自動更新される」状態を避け、いつ・何が変わったかを追える状態にしておくことが、原因調査の時間を大きく左右します。

設計原則4: 複数取引所対応なら影響範囲を切り分ける

複数の取引所に対応したボットを運用している場合、1つの取引所の仕様変更が全体に波及しないよう、取引所固有の処理を分離しておくことも重要です。複数取引所対応ボットの設計で紹介した「差異を吸収する層」を用意しておけば、ある取引所のレスポンス形式が変わっても、修正箇所をそのアダプター部分に限定でき、戦略ロジック本体への影響を防ぎやすくなります。

運用習慣: 公式情報を追う仕組みを作る

設計面の対策と並行して、情報を能動的に取りに行く習慣も欠かせません。

  • 利用している取引所の開発者向けドキュメント・変更履歴ページをブックマークし、定期的に目を通す
  • 取引所が提供しているステータスページやお知らせ(メンテナンス情報・APIバージョン移行の告知など)を確認する
  • ccxtを使っている場合は、ccxtリポジトリのリリースノートも合わせて確認する

これらは地味な作業ですが、「エラーが出てから調べる」のではなく「変更が予告された時点で対応を検討する」方が、影響を小さく抑えられます。

まとめ

  • API仕様変更は障害とは別の問題で、エラーにならずに静かに壊れることがある
  • レスポンスの検証層を挟み、想定外のフィールド欠落は握りつぶさず例外にする
  • 本番ロジックとは別に、軽量な疎通チェックを定期ジョブとして走らせ異常を早期検知する
  • ライブラリのバージョンは固定し、更新は計画的に、可能ならテスト環境を経てから反映する
  • 複数取引所対応なら、取引所固有の処理を分離して影響範囲を限定する
  • 公式ドキュメント・お知らせ・ライブラリのリリースノートを能動的に追う習慣を持つ

取引所のAPI仕様変更は、こちらの都合とは関係なく起こります。完全に防ぐことはできなくても、「気づくまでの時間」と「影響範囲」を小さくする設計と習慣を持っておくことが、長くボットを運用し続けるための地味ながら重要な備えになります。