mcpField
A
alpaca-broker-sse-events

alpaca-broker-sse-events

github.com/alpacahq開発157117 回インストール1 週間前に更新
リポジトリ

alpaca-broker-sse-events について

Alpaca Broker APIを扱う開発者向けのSSEイベント処理スキルです。口座、取引、ジャーナル、送金、アクティビティのイベントを対象に、カーソル再生や再接続、冪等処理による安定したコンシューマー構築を説明します。

主な機能

  1. 01Brokerのライフサイクルイベントを購読
  2. 02イベントカーソルによる履歴再生
  3. 03ハートビート監視と再接続処理
  4. 04ワーカーキューと指数バックオフ
  5. 05レコード単位の冪等処理

活用シーン

  1. 01口座や注文の状態をリアルタイム更新
  2. 02停止中に欠落したイベントを復旧
  3. 03重複配信による副作用の再実行を防止

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/alpacahq/alpaca-skills --skill alpaca-broker-sse-events

インストール後、Claude Code で/alpaca-broker-sse-eventsを入力して読み込まれたか確認します。

同梱ファイルreference.md

詳細

Alpaca Broker API — リアルタイムイベント(SSE)

Alpaca は Server-Sent Events を使って証券業務のライフサイクルイベントを配信します。これは、text/event-stream をストリーミングする長時間接続の HTTP GET です。これはマーケットデータ用 WebSocket(alpaca-broker-market-data)とは異なります。トランスポート、認証、信頼性モデルがそれぞれ異なります。

ベース URL と認証(クライアントクレデンシャルの Bearer トークン。従来の Basic も引き続き使用可能)については、まず alpaca-broker-integration をお読みください。

リファレンス

  • ガイド:https://docs.alpaca.markets/docs/sse-events
  • 最新情報:alpaca-docs MCP → search "SSE Events"、次に fetch us/sse-events

1. なぜ SSE なのか(そして、見た目よりシンプルな理由)

SSE は通常の HTTP です。特別なクライアントは必要ありません。GET を開始し、接続を開いたままにして、ボディを行単位で読み取ります。各イベントは JSON オブジェクトを含む data: 行です。再生可能なため、過去の時点からイベントを取得してシームレスに最新の状態まで追いつくことができ、ライフサイクルの状態を把握するには、単純なポーリングよりはるかに優れています。

2. イベントストリーム

ストリームパス内容
アカウントステータスGET /v1/events/accounts/statusアカウント属性の変更:status/crypto_status(SUBMITTED→ACTIVE、ACTION_REQUIRED、REJECTED)、および kyc_results、account_blocked、trading_blocked、cash_interest、options
ジャーナルステータスGET /v2/events/journals/statusJNLC/JNLS のライフサイクル(queued→executed、correct…)
入出金/送金ステータスGET /v2/events/funding/status統合ストリーム:Transfer、BankRelationship、WireBank、FundingWallet エンティティ(entity_type で切り替え)
取引更新GET /v2/events/tradesevent フィールド内の注文イベント:new、fill、partial_fill、canceled、rejected、held、trade_bust、trade_correct…(注文の status よりも詳細)
アクティビティGET /v2beta1/events/activitiesすべての金融アクティビティを 1 つのストリームで配信:約定、コーポレートアクション、手数料、ジャーナル、送金。activity_type(TRD = 取引の約定)+ activity_subtype + details オブジェクト。ULID の event_id、UUID の ref_id
取引以外のアクティビティ(従来版)GET /v1/events/nta配当、利息、手数料、株式分割、ACAT、現金の支払い。entry_type は JNLC/FEE/INT/DIVNRA/CSD など。status ∈ executed/correct/canceled

パスとバージョンは統一されていません。個別に確認してください。 これは、Alpaca のドキュメントで十分に説明されていない、ストリーム間の不整合の典型例です。

  • Activity SSE は、 2026-02-11 以降に記録されたアクティビティについて、/v1/events/nta および GET /v1/accounts/activities を完全に置き換えます。それより前の履歴には、引き続き REST エンドポイントが必要です。新しいパートナーは従来のエンドポイントを使用しないでください。/v2/events/trades は置き換えません。約定、訂正、取消(バスト)は両方に表示されますが、約定以外のライフサイクルイベント(accepted、canceled、expired、replaced)はアクティビティではないため、こちらには表示されません。
  • /v1/events/trades は廃止されています(完全に非推奨となり、利用できません)。/v1/events/journals/status は従来版です。/v2 に移行してください。
  • /v1 のイベントには整数の event_id と ULID の event_ulid の両方が含まれます。/v2//v2beta1 では ULID の event_id が含まれます。§4 で渡すカーソルを説明します。

フィールドの形式はストリームごとに異なり、共通のエンベロープはありません。それぞれのスキーマを確認してください。

3. 接続

GET /v2/events/journals/status?since_id=<last-ulid-you-saw> HTTP/1.1
Host: broker-api.alpaca.markets
Authorization: Bearer <access-token>
Accept: text/event-stream

Authorization: Basic <base64(key:secret)> も使用できます。開いたストリームがトークンの期限切れ後も維持されるかどうかは、どこにも記載されていません。そのため、接続中の 401 は通常の切断として扱い、カーソルを使って再接続してください。

レスポンスストリームを読み取り、到着した data: {…} フレームを解析します。ほとんどの言語では、既製の EventSource/SSE クライアントを使用できます。ただし、最初のリクエストに Authorization ヘッダーを設定できることを確認してください(ブラウザーの EventSource API では、よく知られているとおり設定できません。代わりにサーバーサイドの SSE ライブラリを使用してください)。

4. 再生カーソル — データ損失を防ぐ機能

すべてのストリームで、特定の時点から再生できます。

パラメーター意味
since / untilRFC3339 または YYYY-MM-DD 形式のタイムスタンプ(日付のみの形式は一部の /v1 ストリームで使用)。オフセット内の + は %2B として URL エンコードしてください。
since_id / until_idv2 / v2beta1 ストリーム — ULID 値です。 /v1/events/* では、これらは レガシー整数 カーソルであり、一部のブローカーパートナーのみ利用でき、2027-02-15 に廃止されます。これらを前提に構築しないでください。
since_ulid / until_ulidv1 ストリーム(accounts/status、nta、およびレガシーの /v1 journals ストリーム)— ULID カーソルで、すべてのパートナーが利用できます。v1 ではこちらを使用してください。v2 には存在しません。

ルール:until を設定する場合は since が必須です。until_id を設定する場合は since_id が必須です(since_ulid / until_ulid も同様です)。since、since_id、since_ulid を混在させることはできません。/v2beta1/events/activities では依存関係が逆になり、since を指定する場合は until が必須です。また、ライブのテーリングで開始時点を指定せずに使用できるのは since_id のみです。since カーソルを指定しない場合、履歴は返されません — 以降のライブプッシュのみ受信します。until の境界に達すると、ストリームは 200 で終了します。

信頼性を確保するうえで、これが最も重要な教訓です。 最後に正常に処理したイベントの ID を永続化してください。再接続するたびに、それを since カーソルとして渡してください — v2/v2beta1 では since_id、v1 では since_ulid — そうすれば Alpaca が切断中に見逃したイベントを再生します。カーソルを指定せずに再接続するコンシューマーは、停止中に発生したすべてのイベントを気づかないまま取りこぼします。

5. 順序に関する注意点

同じミリ秒内では、ULID にランダムな要素が含まれるため、2 つのイベントのソート順はどちらになるか分かりません。Alpaca 独自のガイダンスでは、調整の際は最後のイベントより数分前の since からストリームを再開し、冪等な処理で重複分を吸収することを推奨しています。Alpaca はアカウントごとの順序を保証しますが、アカウント間では何も保証しません。そのため、グローバルな順序はおおよそ保たれるものとして扱い、重複排除を行ってください。また、アカウントごとの保証を活用してください(§7 を参照)。

6. 信頼性パターン(経験から得た知見)

SSE 接続は切断されます。ネットワーク、ロードバランサー、デプロイ、Alpaca 側のリセットなど、原因はさまざまです。本番環境で利用するコンシューマーには、次の対策が必要です。

  1. コメント行を解析し、決して破棄しないでください。 : で始まる行はすべて SSE コメントです。Alpaca では、ここに次の 3 つの意味を持たせています。:heartbeat(接続中。対応不要)、: you are reading too slowly, dropped N messages(気づかないうちにデータが失われています。ギャップとして扱い、カーソルから再再生してください)、: internal server error(サーバーが接続を閉じようとしています。再接続してください。v2/v2beta1 ストリームのみ)。: で始まる行をフィルタリングするコンシューマーは、気づかないままデータを失います。
  2. 無通信を検知してください。 ハートビートも含め、すべてのフレームで lastMessageAt を更新します。観測したハートビート間隔の数倍の時間、ストリームから何も届かない場合は、接続を切断して再接続してください。切断されたソケットも「接続中」に見えることがよくあります。ハートビートの間隔は文書化されていないため、タイムアウトを固定値にせず、実測してください。
  3. 読み取りループでブロッキング I/O を行わないでください。 Alpaca が明示しているとおり、読み取ったデータはキューに入れ、ワーカーで処理してください。イベントごとに同期的にデータベースへ書き込むと、: dropped N messages コメントが届くことになります。
  4. 指数バックオフと上限を設けて再接続してください。 エラーまたは接続終了後、一定時間待ってから再接続し、待機時間を上限まで倍増させます(例:1 秒から開始し、上限を 60 秒にする)。接続に成功したら待機時間をリセットしてください。
  5. 再接続は一度に 1 回だけに制限してください。 フラグを使い、エラーが連続しても複数の再接続処理が同時に起動して競合しないようにします。
  6. 必ずカーソルを指定して再接続してください =最後に処理したイベント(v2 では since_id、v1 では since_ulid。§4 を参照)。
  7. 冪等性を持たせて処理してください(§7 を参照)。再再生時に重複することは想定内であり、例外ではありません。
  8. 副作用の失敗でストリームを停止させないでください。 イベントごとの処理を try/catch で囲み、エラーを記録して続行します。1 件の不正なイベントや下流サービスの停止によって、残りのイベントを処理できなくなってはいけません。

注:OpenAPI では SSE を完全にモデル化できないため、生成された API クライアントでは、これらのエンドポイントで処理が停止することがよくあります(終わらないレスポンスを待ち続けるためです)。コード生成されたクライアントではなく、実際にストリーミングに対応した HTTP/SSE クライアントを使用してください。

7. 冪等な処理パイプライン

各イベントで実行する堅牢な処理方法は、次のとおりです。§6 のとおり、読み取りループではなくワーカーで実行してください。

parse → persist a raw event snapshot (keyed on the dedup id, skip-if-exists)
      → match the local record by Alpaca ID (account_id / journal_id / order_id / transfer_id)
      → update local state guarded by current status, serialized per record
      → fire side effects (notifications, downstream transfers)
      → advance the stored cursor to this event_id
  • 2 つの ID を混同しないでください。 event_id は再再生カーソルであり、重複排除キーはビジネス ID です。Activity SSE では ref_id(取引の場合は実行 ID、それ以外の場合はトランザクション ID)が該当します。再再生ではイベントが少なくとも 1 回配信され、訂正や取り消しは previous_id を介して関連付けられるため、文書で指定されている重複排除キーは ref_id です。バックフィルされたアクティビティは、元の at を保持したまま、event_id のシーケンスの末尾に遅れて届きます。従来のステータスストリームでは、event_id が両方の役割を担います。
  • レコードごとに変更を直列化し、1 つの送金/注文に対する複数のイベントが競合しないようにしてください。ワーカーを account_id でパーティション分割するのが、最もシンプルなデフォルトの方法です。これは、アカウントごとの順序保証(§5)によって可能になります。代替手段として、SELECT … FOR UPDATE による行ロックや、楽観的ロック用のバージョン列があります。
  • 現在のステータスに基づいて遷移を制御してください。 たとえば、すでに終端状態にある送金には処理を行わないようにし、遅れて届いた、または重複した「実行済み」イベントによって再度支払いが発生しないようにします。
  • 処理が成功してからカーソルを進めてください。 イベントの処理中にクラッシュした場合、そのイベントを飛ばすのではなく再再生できるようにします。これは少なくとも 1 回の配信ですが、冪等性によって安全に扱えます。

8. ストリームごとの注意事項

  • アカウントのステータス: status_to == ACTIVE に基づいて、オンボーディング UI と「取引を有効にする」の動作を制御します。
  • 取引の更新: new/accepted/pending_new は約定前のステータスです。fill/partial_fill/canceled/rejected を受信したら、ローカルの注文ステータスを更新します。約定時には、キャッシュされたポートフォリオや保有資産を無効化します。
  • ジャーナル: executed は最終状態ではなく、correct は新しいジャーナル ID を生成することに注意してください(alpaca-broker-journals を参照)。冪等性と ID をキーにしたスナップショットで、どちらにも対応できます。
  • 入出金/送金: 4 種類のエンティティを扱う統合ストリームです。entity_type に応じて切り替えます。送金ステータスは大文字(QUEUED、APPROVAL_PENDING、APPROVED、SENT_TO_CLEARING、COMPLETE、REJECTED、CANCELED、EXPIRED、RETURNED)です。また、入出金イベントのリストは REST の TransferStatus 列挙型と異なります。REST 側には PENDING が追加され、EXPIRED がありません。そのため、両方の和集合を受け入れてください。入出金ウォレットの送金ごとのステータスは、引き続きポーリングが必要になる場合があります(alpaca-broker-funding-transfers)。
  • アクティビティ/NTA: 配当、手数料、利息、コーポレートアクション、約定を、ref_id をキーとするアクティビティスナップショットとして永続化します。これらは残高やポートフォリオの照合に使われます。アクティビティの previous_id には、修正されたアクティビティの ref_id が格納されます。

9. SSE は必要ですが、それだけでは不十分です

コンシューマーが完璧でも、イベントを取りこぼすことがあります(保持期間を超える長時間の停止、バグ、未処理のタイプなど)。**SSE と定期的な照合・修復処理を必ず組み合わせてください。**Alpaca から正本となる状態(アクティビティ、ジャーナル、送金)を再取得し、アップサートします。SSE は低遅延を実現し、照合は正確性を担保します。alpaca-broker-reconciliation-idempotency を参照してください。

関連スキル: 正確性を担保する仕組み → alpaca-broker-reconciliation-idempotency;重複排除/冪等性の仕組み → alpaca-broker-reconciliation-idempotency;バックオフの詳細 → alpaca-broker-rate-limits-resilience;マーケットデータのストリーミング(SSE ではなく WS) → alpaca-broker-market-data。

コメント