mcpField
D
dflow-kalshi-market-scanner

dflow-kalshi-market-scanner

github.com/dflowprotocolその他042 回インストール3 週間前に更新
リポジトリ

dflow-kalshi-market-scanner について

dflow-kalshi-market-scannerは、DFlow Metadata APIを使ってKalshi市場を検索・順位付けするスキャンを定義したスキルです。価格、出来高、スプレッド、モメンタム、終了時刻を扱い、スナップショットとストリーミングの両方に対応します。

主な機能

  1. 01名前付きの絞り込み・順位付けレシピ
  2. 02価格・裁定機会のスキャン
  3. 03出来高・スプレッド・モメンタムのスキャン
  4. 04RESTスナップショットとWebSocketストリーム
  5. 05市場・イベント・シリーズの検索

活用シーン

  1. 01価格やスプレッド条件に合う市場の検索
  2. 02出来高による市場の順位付け
  3. 03価格変動のリアルタイム監視
  4. 04イベント内の結果の比較

MCP 対応

APIパラメーター、ページネーション、レスポンス形式の確認に、https://pond.dflow.net/mcp のDFlow docs MCPを使います。スキャン自体はRESTまたはWebSocketでDFlow Metadata APIに問い合わせます。

インストール

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

$npx skills add https://github.com/dflowprotocol/dflow-skills --skill dflow-kalshi-market-scanner

インストール後、Claude Code で/dflow-kalshi-market-scannerを入力して読み込まれたか確認します。

詳細

DFlow Kalshi Market Scanner

条件に一致するKalshi市場を見つけます。このスキルは、DFlow Metadata APIに対する名前付きのスキャン(フィルターとランキングのレシピ)で構成されています。

前提条件

  • DFlow docs MCP(https://pond.dflow.net/mcp)— リポジトリのREADMEに従ってインストールしてください。このスキルはレシピであり、MCPはリファレンスです。正確なクエリパラメーター、ページネーション、レスポンスの形式など、フィールドレベルの情報は search_d_flow/query_docs_filesystem_d_flow で調べてください。推測しないでください。

対象

ここで紹介するすべてのスキャンはMetadata API(https://pond.dflow.net/resources/metadata-api)に対して実行します。これは、特定時点のクエリにはREST、継続的なストリームにはWebSocketを使用します。コマンドラインからの手早い curl、Node/Pythonスクリプト、cronジョブ、バックエンドサービス、ブラウザーUIのリクエストをプロキシするNext.jsルートなど、どこからでも両方を呼び出せます。

ユーザーが「ターミナルから実行して」と言った場合、dflow CLIは使わないでください。ディスカバリー用のサブコマンドはありません。代わりに、Metadata APIにアクセスする短いHTTP/WSスクリプトを作成してください。

スキャナーの基本構成

すべてのスキャンは、同じ4つのステップで構成されます。このパターンを基本にしてください。スキャンごとに作り直す必要はありません。

  1. 対象全体を列挙する — GET /api/v1/markets(フラット形式)または GET /api/v1/events?withNestedMarkets=true(グループ形式)を使用します。status=active でフィルターします。完了するまでページを取得してください({ markets, cursor } 形式に関するページネーションの注意点を参照)。ユーザーが「今すぐ」DFlowで取引可能な市場を求めている場合に限り、isInitialized=true を指定してください(「注意点」を参照)。

  2. 市場ごとのシグナルを取得する。 最良気配値のスキャンでは、シグナルはすでに市場オブジェクトに含まれています。yesBid/yesAsk/noBid/noAsk(小数点以下4桁の確率文字列)、volume24hFp/volumeFp/openInterestFp(ドル相当額の文字列)、closeTime(Unix時刻)があり、オーダーブックの呼び出しは不要です。モメンタムの分析には、ローソク足または prices/trades WebSocketチャンネルを使用します。注文板の厚みには /api/v1/orderbook/by-mint/{mint} を使用します。直近の約定には /api/v1/trades または trades チャンネルを使用します。

  3. 指標を計算する。

  4. フィルターしてランキングする。 上位N件を返します(デフォルトは10件です。さらに多く必要かユーザーに確認してください)。

ポーリングとストリーミング

意図に合ったモードを選択します。

  • ポーリング(REST) — ユーザーがスナップショットを求めている場合(「今すぐ上位10件を表示して」「Xに一致する市場をすべて一覧表示して」)に適しています。最新状態を保ちたい場合は、一定間隔で再実行します。
  • ストリーミング(WebSocket) — ユーザーがイベント発生時にアクションを起こしたい場合(「YES+NOが1ドルを下回ったら通知して」「1分以内に5%以上動いた市場を知らせて」「Xが約定したら取引して」)に適しています。wss://<host>/api/v1/ws で関連チャンネル(prices、trades、orderbook)を購読し、更新ごとに指標を計算します。ストリーミングの仕組み全般(再接続、バックオフ、サブスクリプションのライフサイクル)については、dflow-kalshi-market-data に引き継いでください。

正確なエンドポイントパラメーター、チャンネルのペイロード、ページネーションについては、docs MCPを参照してください。

提案するスキャン

各スキャンは、ユーザーの質問と指標の組み合わせです。指標を基本構成に当てはめてください。

固定の数値しきい値より、順位に基づくフィルターを優先してください。 Kalshiの取引高は、アクティブな市場間で5桁以上の幅があります。固定のドル下限をハードコードすると、低すぎて素通りするか、高すぎてすべてを除外するかのどちらかになり、プラットフォームの成長に伴って状況も変わります。スキャンで「取引が活発」「安い」「大きく動いた」などを判定する必要がある場合は、ここに固定値を埋め込まず、スキャン結果(現在の対象全体におけるパーセンタイル)からしきい値を算出してください。

固定値を使うのは、意味上定まる場合に限ってください。たとえば、裁定取引における YES + NO < $1.00(調整可能なしきい値ではなく、裁定なしを成り立たせる不変条件)や、status=active(しきい値ではなく、フィールドの値)です。ユーザーが具体的な数値を指定した場合は、その数値を使ってください。ユーザーの表現が具体的なしきい値を示唆しているものの、その値がわからない場合(「かなりの取引高」「大きく動いた市場」など)は、推測せずにユーザーに確認してください。

1. アービトラージ — YES + NO < $1

「両方の側を合計1ドル未満で購入できる市場を探してください。」

  • 指標:parseFloat(yesAsk) + parseFloat(noAsk) < 1.00。裁定取引がないことを示す意味上のしきい値です。この値は固定してください。
  • 順位付け:差額(1 - sum)が大きい順です。
  • yesAsk または noAsk のいずれかが null の行は除外してください(その側に未約定の売り注文がなく、実際のアービトラージではありません)。
2. ロングショットの YES

「実際に取引されている、安価な YES。」

  • parseFloat(volume24hFp) の降順で順位付けし、アクティブな市場の上位四分位を「実際に取引されている」市場群として選びます(スキャン結果から75パーセンタイルのしきい値を算出し、ドル金額をハードコードしないでください)。
  • その市場群の中で parseFloat(yesAsk) の昇順に並べ、最も安いものから上位N件を返します。ユーザーが上限(「20¢未満」「3¢未満」など)を指定した場合はそれに従います。指定がなければ順位付けのみとし、セント単位の上限を勝手に設定しないでください。「安価」は固定の値ではありません。何をロングショットとみなすかは、ユーザーがどこまで許容するかによって異なります。
  • 「期待ペイオフが最良」の場合は、別の順位付けとして parseFloat(volume24hFp) / parseFloat(yesAsk) を使います。活発であることと安価であることを同時に考慮します。意図が曖昧な場合は、どちらを希望するかユーザーに尋ねてください。
  • 出来高のない安価な市場は、ロングショットではなくゾンビ銘柄です。まず出来高で順位付けし、その後に価格を確認してください。この順序でノイズを除外します。
3. 近いうちに満期を迎える、ほぼ確実な YES

「97¢を超える YES のうち、まもなく終了するもの――セータを稼ぐ。」

  • フィルター:parseFloat(yesAsk) がユーザー指定のしきい値を超えるものです。「ほぼ確実」は表現であって数値ではありません。ユーザーが97¢と言った場合は0.97、99¢と言った場合は0.99を使います。数値を指定せず「ほぼ確実」とだけ言った場合は、どの水準を希望するか(95¢か99¢かなど)尋ねてください。デフォルトのしきい値を勝手に設定しないでください。
  • 順位付け:closeTime の昇順で、終了が最も近いものを先にします。
  • 上位N件を返します。ユーザーが期間(「48時間以内」「今週中」など)を指定した場合は、それを上書き条件として適用してください。デフォルトの期間を勝手に設定しないでください。
4. モメンタム

「直近1時間で何が動きましたか?」、または*「何かが動いたら知らせてください」*

  • ポーリング:各市場について、最小間隔で /api/v1/market/{ticker}/candlesticks(または /market/by-mint/{mint}/candlesticks)を呼び出し、最新の終値とN分前の終値を比較します。市場ごとに処理するためコストが高くなります。まず出来高上位に絞り込み(スキャン#6の順位を再利用し、出来高上位の市場からN件を選択)、その市場でモメンタムを計算してください。
  • ストリーミング:prices チャネル(all: true またはティッカーのリスト)を購読し、メモリ内でローリング変化率を計算します。「Xが起きたらアラート」のパターンでははるかに低コストです。「市場がN%を超えて動いたら取引する」機能を組み込む場合もこの方法を使い、一致した市場を dflow-kalshi-trading に渡します。
  • ユーザー指定の期間における絶対変化率(両方向)または符号付き変化率(方向あり)で順位付けします。ユーザーが指定しない場合は60分をデフォルトにしますが、変化率のしきい値にデフォルトは設けません。上位N件を返します。ユーザーが「N%を超えて動いた」と言った場合、Nはユーザーが指定します。
5. ビッド・アスク・スプレッドが最も大きい市場

「非効率な市場――マーケットメイクするか、避けてください。」

  • 指標:parseFloat(yesAsk) - parseFloat(yesBid)(NO側も同様です)。
  • 順位付け:スプレッドの降順です。
  • データ元:市場オブジェクト。追加の呼び出しは不要です。
6. 出来高が最も多い市場

「どこが盛り上がっていますか?」

  • 指標:parseFloat(volume24hFp)(24時間のドル換算額)、またはカットオフ以降の /api/v1/trades の合計(日中)。ライブフィードでは trades チャネルを購読し、ローリング期間で集計します。
  • 順位付け:出来高の降順です。
7. 終了が最も近い市場

「セータのカウントダウン。」

  • 指標:closeTime - now。
  • 順位付け:昇順です。
  • スキャン3(「ほぼ確実かつ終了間近」)またはスキャン6(「出来高が多く、終了間近」)と組み合わせると、特に便利です。
8. イベント単位・シリーズ単位のスキャン

「このイベントの全アウトカムで最も安いYESは?」「相互排他的な結果の合計が1を超えているか?」

  • 1つのイベント内(例:「FRBが金利をX bps引き上げる」で、結果ごとにバケットがある場合):GET /api/v1/event/{eventTicker}?withNestedMarkets=true を取得し、ネストされたマーケット全体を対象に集計します(min(yesAsk)、Σ yesAsk など)。イベントは、単一勝者のスキャンに適した自然な範囲です。
  • シリーズ全体:GET /api/v1/series/{seriesTicker} とそのイベントを取得し、集計します。
  • シリーズやイベントに mutuallyExclusive フラグはありません。 結果全体のYESを合計する意味があるのは、結果が1つの将来の可能性を網羅する分割になっている場合(必ずいずれか1つが起こり、同時に複数は起こりえない場合)だけです。これはイベント/シリーズのタイトルと契約条件から判断するものであり、フィールドを参照してわかるものではありません。判断に迷う場合は、数値を提示し、その前提をユーザーに明示してください。

個別検索(N=1)

ユーザーが対象のマーケットをすでに決めている場合は、概要取得を省略します。

  • ティッカー指定:GET /api/v1/market/{ticker}(複数形ではなく単数形の market)。
  • アウトカムのミント指定:GET /api/v1/market/by-mint/{mint}(ハイフンではなくスラッシュ)。
  • イベントティッカー指定:GET /api/v1/event/{eventTicker}?withNestedMarkets=true(単数形の event)。
  • 自由入力テキスト:GET /api/v1/search(自然言語からイベント/マーケットを検索)。

複数形(/markets、/events)はリストエンドポイントで、ページネーションには ?cursor=&limit= を指定します。単数形はIDによる個別検索です。取り違えると404になります。

ユーザーに尋ねること(尋ねてはいけないこと)

クエリの形式 — 曖昧でなければ推測し、曖昧なら確認します。

  1. どのスキャンか(または、スキャンに対応付けられる平易な言葉での意図)。
  2. ユーザーが指定する閾値 — 指定どおりに使います。 「> 5%」「2¢未満」「今週」などと言われた場合は、その数値を使います。指定がない場合は、各スキャンで定められた順位ベースのデフォルト(出来高の上位四分位など)を使います。独自の固定数値の閾値を提案してはいけません。 ユーザーの表現がスキャンで定義されていない閾値を示唆する場合(「大きく動いている」「相当な出来高」など)は、数値を推測せず、ユーザーに尋ねてください。
  3. ポーリングかストリーミングか — 「今すぐ見せて」のような意図ならREST、「通知して/発生したら反応して」のような意図ならWebSocketを使います。
  4. 上位N件(デフォルトは10件)。

インフラ — 必ず質問し、推測してはいけません。

  1. DFlow APIキー — スクリプトの検索/HTTP部分にのみ必要です。CLIのシェル呼び出しは独自に認証します(下記の「2つの認証経路」の注意点を参照)。簡潔で中立的な質問をしてください:「スキャナー/検索側で使うDFlow APIキーはありますか?」 キーの保存場所を決めつけてはいけません。「環境変数にありますか?」「DFLOW_API_KEY は設定されていますか?」といった聞き方は、ユーザーが求めていない環境変数のデフォルトへ誘導してしまいます。選択肢を提示し、環境変数やdevへ暗黙にフォールバックしてはいけません。DFlowキーはどこでも同じものを使います。同じ x-api-key でTrade APIとMetadata API、RESTとWebSocketのすべてが利用できます。キーがある場合は、本番ホスト(RESTは https://prediction-markets-api.dflow.net、WSは wss://prediction-markets-api.dflow.net/api/v1/ws)を使い、すべてのリクエスト(RESTとWSのアップグレード)に x-api-key を付けます。キーがない場合は、レート制限のあるdevホスト(https://dev-prediction-markets-api.dflow.net、wss://dev-prediction-markets-api.dflow.net/api/v1/ws)を使い、本番キーの取得先として https://pond.dflow.net/get-started/api-key を案内してください。スクリプトを生成する場合は、起動時に解決済みのホストとキーの有無をログに出力してください(Using prod Metadata API/Using dev Metadata API — rate-limited)。これにより、ユーザーはコードを読み込まなくても、どの接続先を使っているか確認できます。

尋ねてはいけないこと:

  • RPC、ウォレット、署名 — このスキルは読み取り専用の公開メタデータを扱います。トランザクションはありません。
  • 決済ミント/スリッページ/手数料 — これらは取引側の事項です。ユーザーが提示したマーケットでの注文に話題を移した場合は、dflow-kalshi-trading に引き継いでください。

注意点(ドキュメントMCPでは自発的に提示されない情報)

  • 最良気配はマーケットオブジェクトにあります。 yesBid / yesAsk / noBid / noAsk はすでに含まれています。最良価格を取得するためだけに、オーダーブックエンドポイントを繰り返し呼び出す必要はありません。
  • 価格と出来高はマーケット全体に適用され、取引はレールごとに行われます。 初期化済みの各マーケットには、market.accounts の下に USDC レールと CASH レールがあり、それぞれ独自の marketLedger / yesMint / noMint を持ちます。スキャンの yesBid / yesAsk / volume24hFp は共有の Kalshi オーダーブックから取得され、どのレールで取引するかは示しません。dflow-kalshi-trading に渡す際はマーケットティッカーを渡し、取引ステップでレールを選択させてください(デフォルト:USDC)。スキャン出力でレールを暗黙に事前選択しないでください。選択する場合は明示してください。
  • オーダーブックが返すのはビッドのラダーのみです(yes_bids、no_bids)。最良の YES アスク は 1 - max(no_bids keys) で算出します(価格 p の NO ビッドは、価格 1-p の YES オファーです)。ラダーの厚みをユーザーが知りたい場合にのみ関係します。
  • 価格スケールは 2 種類あります。 マーケット/オーダーブックの価格は、小数点以下 4 桁の確率文字列("0.4200")です。取引価格(REST と trades チャネル)は 0~10000 の整数で、yes_price_dollars / no_price_dollars の文字列フィールドも併せて含まれます。計算前に正規化してください。
  • market.title は、多くの場合マーケット固有ではなくイベントレベルのタイトルです。 複数結果のイベント(候補者ごと、利上げ幅の区分ごと、試合の勝者ごとなど、結果ごとにマーケットがあるイベント)では、そのイベント配下のすべてのマーケットで同じ title が共有されます。結果固有の表記は yesSubTitle(および noSubTitle)にあります。スキャン出力に title だけを表示すると、隣接する行が同じに見え、ユーザーがどの結果なのかを判別できません。title — yesSubTitle と表示してください(単純な二者択一マーケットで発生するように、yesSubTitle が null /空の場合は title のみを表示します)。マーケットを取引プロンプトに渡す場合も同様です。複数結果イベントで title だけを表示する「X に YES を購入」という確認は曖昧です。
  • 出来高フィールド — 文字列、ドル換算値、volume24h はありません。 マーケットオブジェクトには volume(整数、累積の生単位)、volumeFp(文字列、累積ドル換算値)、volume24hFp(文字列、24 時間のドル換算値)があります。volume24h フィールドはありません。比較前に *Fp フィールドを必ず parseFloat で数値に変換してください。openInterest / openInterestFp も同じ形式です。
  • isInitialized フィルター。 短期間のマーケット(15 分間の暗号資産マーケットなど)は、Kalshi では取引可能でも DFlow ではまだトークン化されていないことがよくあります。このフィルターがないとスキャンに含まれますが、isInitialized=true を指定すると、現時点で DFlow で取引可能なマーケットだけに絞られます。通常は true を指定します。
  • ビッド/アスクが null の場合。 流動性の低いマーケットでは、最良気配フィールドが null になります。これらを読み取るスキャンでは、null をゼロとして扱わず、必ずスキップしてください。
  • メンテナンス時間帯 — Kalshi は**木曜日の午前 3:00~5:00(ET)**にオフラインになります。この時間帯には、最良気配や出来高のフィールドが古くなったり、欠落したりすることがあります。WS の更新が途絶えることもあります。この時間帯にスキャン結果が空になったり、不自然に間違って見えたりする場合は、それが原因です。
  • ページネーションの形式。 /markets(および /events)は { markets: [...], cursor: <number> } を返します。最初の呼び出しでは cursor を省略するか、cursor=0 を渡します。どちらも同じです。返された cursor は次のページのオフセット(これまでの行数)です。次の呼び出しでは ?cursor=N として渡してください。markets.length < limit になったら終了します(標準の方法)。next === cursor のチェックを追加しても問題ありませんが、通常は不要です。limit の上限は 255 です。limit=256 以上では HTTP 400 "number too large to fit in target type" が返されます(バックエンドでは u8 です)。ドキュメントでは控えめなデフォルトとして 200 を使用していますが、実際の上限は 255 です。ページネーションを行わない大規模なスキャンでは、一致した項目が通知なく欠落します。
  • WebSocket の all: true は大量のデータを流します。 負荷の高いチャネル(特に prices)で all: true を指定して購読すると、すべてのマーケットの更新がすべてストリーミングされます。スキャン対象が決まった集合の場合はティッカーリストを優先し、本当に全マーケットが対象のスキャンに限り all: true を使用してください。
  • 「スキャンしてから購入」は、対話式スクリプト 1 つで実行し、成果物を 2 つに分けません。 ユーザーがコマンドラインからマーケットを見つけ、その結果に基づいて操作したい場合は、スキャンして順位付きリストを表示し、ユーザーに 1 つ選択させ(または各行で y/N の確認を求め)、その後 dflow trade を呼び出す単一のスクリプトを出力してください。非対話式のスキャンスクリプトを作成して、ユーザーに「1 つ選んで、自分で dflow trade を実行してください」と伝えるのは避けてください。ユーザーに作業を中断させ、識別子をコピーさせることになります。Node の readline プロンプトや Python の input() で問題ありません。行ごとのプロンプトなしで全自動化する場合も、スクリプトは 1 つにまとめ、「確認なし」で実行する動作を最初に明示してください。
  • dflow trade に渡す形式。 スキャン結果はマーケットオブジェクトであり、そのまま CLI に渡せる呼び出し形式ではありません。CLI の --market フラグには market.accounts[<settlementMint>].marketLedger の marketLedger を指定します。market.ticker、yesMint / noMint、トップレベルのミントではありません。ユーザーが CASH を指定しない限り、USDC レールをデフォルトにしてください(上記の「価格と出来高はマーケット全体に適用され、取引はレールごとに行われます」を参照)。YES と NO の購入には同じ marketLedger を使用します。サイドの選択には --market を変えるのではなく、--side yes|no を使用します。CLI 引数の詳しい形式(決済ミントから marketLedger を検索する方法、最小単位への変換、優先手数料フラグ、「整数単位で N 枚のコントラクトを購入する」イディオム)については、dflow-kalshi-trading を参照してください。ここで改めて説明する必要はありません。
  • 複数のサーフェスを使うスクリプト:認証経路は 1 つではなく 2 つです。 このスキルと dflow-kalshi-trading を組み合わせる自然な方法は、Metadata API でマーケットを探索し、その後 dflow trade を呼び出して実行するスクリプトです。各処理は個別に認証します。
    • 探索(Metadata API HTTP) — 通常の fetch / curl を使用します。スクリプトの環境変数または設定に DFlow API キーが必要です(#5 を参照)。キーがない場合は開発用ホストになり、レート制限が適用されます。
    • 実行(dflow trade の呼び出し) — CLI が dflow setup で保存した情報(キー、ウォレット、RPC)を使用します。スクリプトから CLI 呼び出しに渡す情報はありません。 ユーザーが「CLI はすでに設定済みです」と言った場合、それでカバーされているのは実行側であり、発見側ではありません。API キーについては、「スキャナー/発見機能のために、DFlow API キーをお持ちですか?」 と尋ねてください。「CLI だけでは不十分なので、別のキーが必要です」 と伝えるのではありません。この 2 つは独立しています。DFlow キーは 1 つで、設定箇所は 2 つです。

当てはまらない場合

上記でカバーされていない内容(すべてのパラメーターリスト、ページネーショントークン、レスポンススキーマ、WS の再接続仕様、まれに使うフィルター(スポーツ、タグ、カテゴリー、シリーズ検索)、ローソク足の間隔)については、ドキュメント MCP(search_d_flow、query_docs_filesystem_d_flow)に問い合わせてください。推測しないでください。

関連スキル

ユーザーが発見から実行に移る場合は、次のスキルに引き継いでください。

  • dflow-kalshi-trading — ここで見つけた市場で実際に購入/売却/償還します。
  • dflow-kalshi-portfolio — ユーザー自身のポジションと損益を表示します。
  • dflow-kalshi-market-data — 「名前付きスキャン」の形式以外で、一般的なリアルタイムのオーダーブック/取引/価格ストリーミングを扱います(再接続パターン、完全なペイロードスキーマ、試合中のライブデータ)。
  • dflow-proof-kyc — ウォレットを検証し、提示した市場を実際に購入できるようにします。

コメント