株価APIの空振りを減らす—取引カレンダーで取得対象日を先に決める

,

毎朝の株価データ取得で、今日の応答が空なら昨日、昨日も空なら一昨日へ遡る。この方法は小さく始めやすい反面、休日や配信前の日付にも問い合わせます。APIの上限に余裕があっても、「予想できた空振り」と「調査が必要な空応答」が混ざると運用は分かりにくくなります。

今回は、取得できた価格データから対象日を探す従来方式を見直し、取引カレンダーで候補日を先に決めた実装記録です。既存記事で扱ったバッチの完了期限ではなく、APIへ渡す日付の決定に焦点を当てます。ソフトウェアとデータ運用の説明であり、投資助言ではありません。

休日判定、時刻判定、対象日固定、応答検証の四段階でAPI取得日を決める

最近の取り組みで確認できたこと

2026年9月25日の作業記録では、日次処理のAPI使用状況を調べ、週約14回の問い合わせが当日や休日への空振りだったと整理されています。これは変更前の調査値です。変更後の一週間を観測して同数の削減を実証した数字ではありません。

その後、対象日解決を取引カレンダー参照へ変更し、17時前は当日を候補から外す処理を実装しました。関連するデータ取り込み変更とともにテスト・静的検査を通過し、開発ブランチへのマージまで完了した記録があります。一方、同日の記録ではリモートへのpushは未実施でした。この記事の作成時に、本番の定期実行へ反映されたかを再試験したわけではありません。

重要なのは「営業日を当てるために価格APIを呼ぶ」役割をなくした点です。取得日を決める処理と、その日の価格が本当に届いたかを確認する処理を分離できます。ただし、営業日だと分かっただけで配信完了を保証できるわけではありません。

仕組みを分解する

第一に、取引カレンダーを取得して、扱う市場に合う営業日を選びます。2026年9月26日に確認したJ-Quants公式HTMLでは、`GET /v2/markets/calendar` は日付と休日区分を返します。休日だけでなく、通常営業日、半日立会日、祝日取引のある非営業日が区別されています。

ここで「0以外なら株式の営業日」とはしません。休日区分3は祝日取引のある非営業日で、デリバティブの取引と現物株の取引を混同する原因になります。現物株の例では区分1と2を対象にしますが、区分2を含む日の配信時刻まで通常日と同じとは決めつけません。

第二に、実行時刻をAsia/Tokyoへ揃え、当日を候補へ含めるか判断します。今回の17時はローカル実装の境界です。公式の更新予定表では株価四本値は16時30分ごろですが、時刻は保証されず前後すると明記されています。「17時を過ぎたから必ず揃う」という契約ではありません。

第三に、条件を満たす直近の営業日を一つ選び、処理全体で固定します。途中で時計が境界を跨いでも、価格取得と後段集計の対象日を別々に再計算しない設計にします。

第四に、応答の状態を確認します。正常な価格データ、正常応答だが空、認証や権限のエラー、通信失敗を分けます。カレンダーは候補日の根拠、価格応答は実データの根拠です。この二つを片方だけで代用しないことが中心になります。

小さく再現する手順

最初はAPIを呼ばず、架空のカレンダーで日付選択だけを試します。以下は説明用の疑似コードで、運用中のコードを転載したものではありません。

“`text
now = 実行開始時刻をJSTへ変換
limit = nowの日付
if nowの時刻 < 17:00:
limit = limitの前日
eligible = カレンダーのうち
日付 <= limit かつ 休日区分が1または2
if eligibleが空:
対象日不明として停止
target = eligibleの最大日付
価格をtargetで取得し、応答状態を記録
“`

架空の日Aを営業日、翌日Bを休日とします。Aの境界前ならAより前の営業日、境界後ならA、BならAを選ぶのがこの例の期待値です。年末年始や連休も、曜日の計算ではなく入力した区分から選びます。実在日の休日を自作せず、試験用だと分かるデータにしてください。

次に、日付選択を変えずに応答だけ差し替えます。正常な価格、空配列、権限エラー、通信タイムアウトを用意し、空配列のときに勝手に古い日付を成功扱いしないか確かめます。前営業日へ代替する要件がある場合も、要求した日と採用した日を別々に残します。

実APIへ接続する段階では、カレンダーを対象期間で取得し、同じ条件のまま必要なページを読み切ります。公式仕様は応答に`pagination_key`があれば続きを取得する方式です。以前の取得が一回で終わっても、今後も常に一回で全件が返るとは限りません。認証情報は記事や実行ログへ出さず、既存の安全な設定経路を使います。

確認指標

確認するのは、総リクエスト数だけではありません。まず「対象日決定のための試行回数」を、カレンダー更新や本来の価格取得と分けます。次に「選んだ対象日と保存データの日付の一致」を調べます。最後に「候補日が正しいのに空だった回数」を別集計し、配信遅延や取得条件の調査へつなげます。

これらは今後の運用確認に使う推奨指標です。今回の根拠記録に、変更後の一週間分の計測結果はありません。「空振りゼロを達成」とはせず、同じ期間・同じ処理範囲で変更前後を測る必要があります。カレンダーの更新要求も含めた総負荷を見ないと、減った問い合わせだけを数える偏った評価になります。

また、週の総回数を一分あたりの上限で割って「使用率」とするのは不適切です。総量の余裕と瞬間的な集中は別の問題です。上限への接近を見る場合は、同じ時間窓のリクエスト数で比べ、再試行とページングも含めます。

失敗しやすい点と安全策

一つ目は、古いカレンダーに日付がないことを休日扱いする失敗です。取得済み期間を保存し、必要な範囲が欠けたら更新するか停止します。公式カレンダーにはレコード別の更新時刻や訂正識別子がないため、ローカルの取得日時と内容を残す設計が役立ちます。

二つ目は、営業日と配信済みを同一視する失敗です。公式には更新完了を通知するAPIもないと案内されています。候補日が妥当でも応答が空なら、即座に休日へ分類し直さず、待機・再確認・通知の条件を別に設けます。再試行回数と終了期限には上限が必要です。

三つ目は、エラーを空データへ変換する失敗です。権限不足や認証失敗まで「対象なし」にまとめると、日付を変えても直らない問い合わせを繰り返します。HTTP状態と業務上の取得結果を分け、原因に応じて停止します。

四つ目は、最新データの存在だけで過去データの完全性まで保証する失敗です。対象日の選定が正しくても、ページ欠落や後日の訂正は別途扱う必要があります。カレンダー導入は取得日の改善であり、データ品質全体の証明ではありません。

再現チェックリスト

  • [ ] 対象市場と休日区分の対応を明文化した。
  • [ ] 実行開始時刻をJSTで固定した。
  • [ ] 境界時刻の前後と連休を試験した。
  • [ ] カレンダーの取得済み範囲を確認した。
  • [ ] 要求日と保存データの日付を突合した。
  • [ ] 空応答と認証・通信エラーを区別した。
  • [ ] ページング終了まで取得できることを確認した。
  • [ ] 変更後の効果を未計測なら未計測と表示した。

次に改善するなら

次の課題は、カレンダー更新の頻度、配信遅延時の待機条件、変更前後の空応答数を一つの運用記録へまとめることです。これらがすべて完成したという根拠は、今回の記録にはありません。

まず少数の営業日で日付選択と応答を追い、その後に連休を含む期間で再確認するのが現実的です。目的は最少のAPI回数を競うことではなく、どの日を、どの根拠で取得し、どの状態で止めたかを説明できる処理へ変えることです。

参考情報

実施根拠は2026年9月25日の日次統合記録と同日の開発作業記録です。非公開資料を記事作成の根拠に用いており、読者向けの公開リンクではありません。以下の公式HTML本文は2026年9月26日に確認しました。

  • [J-Quants:取引カレンダー](https://jpx-jquants.com/en/spec/mkt-cal)
  • [J-Quants:休日区分](https://jpx-jquants.com/en/spec/mkt-cal/holiday-division)
  • [J-Quants:データ更新時刻と完了確認の制約](https://jpx-jquants.com/en/spec/data-update)
  • [J-Quants:レスポンスのページング](https://jpx-jquants.com/en/spec/pagination)

トップへ戻る