Bot CEX 開発ログ

🛠️開発記録#477(2026/3/9)「multi_market_probe開発ログ ― 閾値監視から分布観測へ、M系統を作り直した話」

こんにちは、ぼっちbotterよだかです。

今回は、開発を進めている市場間観測bot multi_market_probe のダッシュボード改修について書きます。

前回は、Forward層とJudgment層を分離する理由を整理しました。市場の事実を観測するレイヤーと、その事実を戦略として読むレイヤーを混ぜないこと。これは設計思想としてかなり重要で、今も土台になっています。

ただ、実際に観測器を動かしてみると、設計思想を分けただけでは足りないことも分かってきました。
指標が並んでいるだけでは、まだ「読める装置」にはならないのです。品質監視が過剰なら、本当に見たいものが埋もれてしまう。premium を閾値だけで見ていると、それが異常値なのか背景状態なのかも分からない。相関も、ただ数値を置くだけでは全体傾向と局所の違いが見えにくい。観測器として必要なのは、単に情報量を増やすことではなく、市場の事実を、順番と粒度をそろえて読めるようにすることなのだと思いました。

そこで今回は、Q / C / M 系統を中心にダッシュボードを作り直しました。
品質監視は「接続が維持されているか」「過度な遅延がないか」「更新が継続しているか」の3点に絞り、binance-perp の取得系は HTTP polling から WebSocket に切り替えて安定化させました。さらに M 系統では、premium を従来の閾値表示ではなく、width や quantile を含む分布として見えるようにしています。これによって、今その市場で何が“例外”で、何が“通常状態”なのかを、ようやく事実ベースで見られる形に近づけました。

この記事では、そうした改修内容を開発ログとして整理します。
章によってはコードやメトリクス設計にかなり踏み込みますが、全部を最初から技術記事として固めるつもりはありません。実際に手を動かしながら何を削り、何を残し、どこで「やっと見えるようになってきた」と感じたのか。そうした感覚の部分も含めて、読み物として追える形で書いていきます。
前半は全体の意図や設計上の狙いをなるべく読みやすく、後半は必要に応じてコードや具体的なパネル構成にも踏み込みながら、今回の改修で何が前進したのかをまとめていきます。

1. 今回触った範囲:Q / C / M を先に固めた

今回の改修では、ダッシュボード全体を一度に作り込むのではなく、Q / C / M の三つのレイヤーに絞って整理するところから進めました。

multi_market_probe のダッシュボードは、
Q(Quality) → C(Correlation) → M(Market State) → F(Forward) → J(Judgment)
という五層構造で設計しています。これは単なる見た目の分類ではなく、

データが正常か

市場同士に関係があるか

価格差という状態が存在するか

その結果はどう分布するか

戦略として読めるか

という情報の流れに対応しています。

理想的には、この五層すべてが揃ってはじめて、観測器として完成したと言えます。
しかし実際に手を動かしてみると、いきなりすべての層を同時に作り込むのはあまり良い進め方ではないと感じました。

理由はシンプルで、下の層が整理されていない状態で上の層を作ると、指標の意味が曖昧になるからです。

たとえば、

  • データ品質が不安定な状態で Forward 分布を見ても意味がない
  • 市場間の関係性が分からない状態で Lead-Lag を議論しても空振りになりやすい
  • premium の分布を理解していない状態で Reversion スコアを作ると、単なるノイズになる

といった問題が起きやすくなります。

そのため今回は、まず 観測の土台になる三つのレイヤーに集中することにしました。

  • Q(Quality)
    データが正常に取得されているかを確認する層
  • C(Correlation)
    市場同士の基本的な関係性を確認する層
  • M(Market State)
    市場間の価格差や状態を観測する層

この三つが整理されていれば、

データは信頼できるのか

市場同士に関係はあるのか

価格差という状態は存在するのか

という最低限の前提を確認できます。

言い換えると、ここまでは 戦略以前の観測フェーズです。

そのため今回の記事では、

  • Q 系統の整理(品質監視のスリム化)
  • binance-perp のデータ取得を WebSocket に移行
  • C 系統の相関パネルの再構成
  • M 系統の premium 観測を「閾値」から「分布」へ変更

といった部分を中心にまとめていきます。

Forward(F)や Judgment(J)といった上位レイヤーについては、まだ完全に理解できていない部分もあるため、今回は無理に作り込まず、次回の開発フェーズで整理する予定です。

観測器を作るときにありがちな失敗は、いきなり「使える戦略」を作ろうとしてしまうことだと思います。
しかし実際には、その前に

市場で何が起きているのか
その状態がどれくらい続くのか

を、できるだけ歪めずに観測できる状態を作る必要があります。

今回の改修は、multi_market_probe を 戦略ボットではなく、まず「読める観測装置」に近づけるための整理作業でした。

次の章では、その中でも最初のレイヤーである Q(Quality)系統の整理について見ていきます。

2. Q系統の整理:品質監視を3点に絞った

ダッシュボードの改修を進める中で、最初に手を入れたのが Q(Quality)系統です。
ここは市場分析の指標というより、観測器そのものの健全性を確認するためのレイヤーです。

アルゴリズム研究では、どうしてもシグナルや統計指標に目が行きがちです。しかし実際には、その前提として「データが正常に取得できているか」を確認する必要があります。もしデータ取得のどこかが壊れていれば、どれだけ立派な統計を計算しても、その結果は信頼できないからです。

ただし、今回ダッシュボードを見直していて気づいたのは、品質監視の情報が増えすぎると、逆に状況が分かりにくくなるという問題でした。

もともとの設計では、

  • drop rate
  • out-of-order rate
  • stale flag
  • recv lag
  • latency
  • 更新頻度
  • feed state

といった多くの品質指標を同時に並べていました。これは開発初期の検証段階では有用だったのですが、実際に観測器を運用してみると、常にすべてを追い続ける必要があるわけではありません。

むしろ重要なのは、観測が成立しているかどうかを短時間で判断できることです。

そこで今回の改修では、Q系統の監視を次の三つに整理しました。

  • 接続が維持されているか
  • 遅延が過度に増えていないか
  • データ更新が継続しているか

この三つが正常であれば、少なくとも

  • 価格は流れている
  • 時系列は破綻していない
  • 市場比較が成立する

という最低条件は満たされます。

逆に言えば、この三点のどれかが崩れている場合、その時点で上位レイヤーの指標を見る意味はほとんどありません。
たとえば価格更新が止まっている状態で premium を計算しても、それは市場の状態ではなく、単にデータ取得の問題を反映しているだけになります。

もう一つ今回意識したのは、Qパネルの役割を「分析」ではなく「状態確認」に限定することです。

品質指標は多くの場合、長時間眺めて分析するものではありません。
むしろダッシュボードを開いた瞬間に、

「観測は正常に動いているか」

を確認できれば十分です。

そのため今回の改修では、パネルの配置も含めて、

  • 状態を一目で確認できる要約
  • 必要に応じて詳細を掘れる情報

という構造に整理しました。

この変更によって、Q系統は「多くの情報を並べる場所」ではなく、観測器が今も正常に動いているかを確認するための入口として機能するようになりました。

ダッシュボードを使う順序としても、まずこのレイヤーを確認し、問題がなければ次の層に進む、という形になります。

次の章では、その次のレイヤーである C(Correlation)系統について見ていきます。ここでは、市場間トレードの前提となる「市場同士の関係」がどのように観測されているのかを整理します。

3. binance-perp を HTTP polling から WS へ切り替えた

Q系統の整理と並行して、もう一つ手を入れたのが binance-perp のデータ取得方式です。

これまで multi_market_probe では、一部の市場データを HTTP polling で取得していました。
一定間隔で API を叩き、その時点の価格を取得するというシンプルな方法です。実装も簡単で、初期のプロトタイプを動かす段階では十分機能していました。

ただ、観測器として長時間動かしてみると、いくつか問題が見えてきます。

まず、更新タイミングが市場の変化と同期しないという点です。
polling は一定周期でデータを取得するため、その間に市場が何度動いたのかは分かりません。たとえば 1 秒ごとに取得している場合でも、その 1 秒の間に価格が何回更新されたのかは観測できないことになります。

もう一つは、遅延の評価が難しくなるという点です。
HTTP polling では、

API 呼び出し

レスポンス受信

価格更新

という順序になるため、取得したデータが「どの時点の価格なのか」がやや曖昧になります。
観測器として市場間比較を行う場合、このタイミングのズレは無視できない問題になります。

そこで今回は、binance-perp の取得方式を HTTP polling から WebSocket(WS)へ切り替えることにしました。

Binance では、bookTicker ストリームを利用することで、best bid / ask の更新をリアルタイムで受信できます。
設定としては次のような形になります。

source_type: binance_book_ticker
transport: websocket

この変更によって、価格更新は

市場更新

WebSocket 経由で push

probe 側で受信

という形になります。
つまり、こちらから取りに行くのではなく、市場側から更新を受け取る構造になります。

観測器の観点から見ると、この違いはかなり大きいです。

まず、価格更新が発生したタイミングに近い形でデータを取得できるため、市場間の時間差をより正確に観測できるようになります。
また、更新イベントそのものが流れてくるため、更新間隔や遅延の監視も行いやすくなります。

もちろん、WS に切り替えればすべてが解決するわけではありません。
接続管理や再接続処理など、実装面ではむしろ複雑になります。ただ、今回の目的はトレードボットではなく観測器なので、多少実装が重くなっても、市場の状態をより正確に観測できることを優先しました。

現時点では、この構成で binance-perp のデータ取得は安定して動いています。
Q系統のパネルでも、接続状態や更新間隔を確認しながら運用していますが、少なくとも現段階では大きな問題は見えていません。

この変更によって、multi_market_probe の市場データ取得は、よりリアルタイム性の高い形に近づきました。

4. Qパネルの並び順を“読む順番”に合わせて組み直した

Q系統のもう一つの変更は、パネルの並び順の整理です。

これは機能追加というより、ダッシュボードの読み方を整える作業でした。
実際に multi_market_probe を動かしながら Grafana を見ていると、指標そのものよりも「どこから見始めればよいのか」が分かりにくいという問題に気づきました。

もともとの配置では、品質指標がそのまま並んでいるだけでした。
個々のメトリクスは正しく表示されているのですが、

どのパネルを最初に見るのか
次にどの情報を確認すればよいのか

という判断の流れがダッシュボードの構造から読み取りにくかったのです。

観測器としてダッシュボードを使う場合、重要なのは情報量よりも「読み順」です。
画面を開いたときに、

観測は正常に動いているのか
どこかの市場が止まっていないか
遅延が異常に増えていないか

といった基本的な状態を、数秒で確認できる必要があります。

そこで今回の改修では、Q系統のパネルを次の順番に並べ替えました。

① 現状の要約(Summary:[Q] Quality Summary (Max Feed State))
まず最初に、現在の状態を一目で確認できるパネルを置きます。
ここでは各市場の feed state や接続状態など、全体の健康状態をざっくり把握します。

② 実態の確認(Operational metrics:[Q] Feed State Code)
次に、遅延や更新頻度といった実際の動作状況を確認するパネルを配置します。
ここで、価格更新が止まっていないか、更新間隔が極端に広がっていないかなどをチェックします。

③ 詳細情報(Diagnostics)
最後に、必要に応じて掘り下げるための詳細メトリクスを置きます。
通常の運用ではここを常に見続ける必要はありませんが、異常が発生したときには原因を追う手がかりになります。
(現状、この系統のパネルは実装済みですが、現時点では不要なので表示させていません)

この構造にすると、ダッシュボードを開いたときの視線の流れが自然になります。

現状を確認する

実際の動作を確認する

必要なら詳細を見る

という順序で情報を追えるようになるからです。

ダッシュボードを作っていると、つい「必要な情報をすべて表示する」方向に進みがちです。
しかし実際に使う場面を考えると、重要なのは情報量よりも 判断のしやすさです。

今回の並び替えによって、Q系統は「品質指標の一覧」ではなく、観測器が正常に動いているかを短時間で確認するための入口として機能するようになりました。

次の章では、この観測データをもとに 市場間の関係を確認する C(Correlation)系統について整理していきます。

5. C系統の整理:60秒窓の相関を全体と詳細で分けて見せる

Q系統で観測器の状態を確認したあと、次に見るのが C(Correlation)系統です。
ここでは、市場間トレードの前提になる 市場同士の関係性を観測します。

multi_market_probe では現在、主戦場である bitFlyer FX(bf_fx) を基準に、複数市場との関係を観測しています。
その中でも今回のダッシュボード改修では、binance-perp との関係を中心に整理しました。

C系統で扱っているのは主に リターンの相関です。
単純化すると、次のような関係を見ています。

corr( return_bf_fx , return_binance_perp )

ここで重要なのは、「価格差」ではなく 変化の相関を見ているという点です。

価格差(premium)は M系統で扱いますが、C系統ではまず

  • 市場同士がどれくらい連動しているのか
  • そもそも比較対象として意味があるのか

といった 前提条件を確認します。

もし二つの市場のリターンがほとんど相関していない場合、
その市場ペアで

  • リード/ラグ
  • 歪み回帰

といった戦略を議論すること自体が難しくなります。

そのため C系統は、市場間トレードの土台を確認するレイヤーになります。


全体傾向を見るパネル

今回の改修では、まず全体傾向を確認するためのパネルとして
[C] Return Corr Trend (bf_fx vs binance_perp) を中心に配置しました。

このパネルは、bitFlyer FX と binance-perp の リターン相関の推移を時系列で表示しています。
現在の設定では 60秒窓で相関を計算しており、短期的な市場連動の変化を見ることができます。

このパネルの役割はシンプルで、

  • 市場同士がある程度連動しているのか
  • 相関が極端に低くなっていないか

といった 全体傾向を把握することです。

たとえば相関が長時間にわたってゼロ付近に張り付く場合、
その市場ペアは単純な価格追随関係にない可能性があります。

逆に、ある程度の相関が安定して観測されている場合は、
市場間に何らかの関係が存在する前提で次のレイヤーを見ることができます。


詳細を確認するパネル

ただし、相関の値は単一の数値だけでは読み取りにくい場合があります。

そこで [C] Return Corr Trend (bf_fx vs binance_perp) を全体パネルとして置いたうえで、
その詳細を確認するためのパネルも併せて配置しています。

具体的には、

  • 相関計算に使用されている サンプル数
  • 相関計算が成立しているかを示す ready 状態
  • 相関の短期的な揺れ

といった補助情報です。

これらのパネルは、相関そのものを分析するというよりも、

  • 相関計算が正常に行われているか
  • サンプル不足で値が不安定になっていないか

といった 観測条件の確認として使います。


なぜ「全体 → 詳細」の構造にしたのか

今回の改修で意識したのは、
一つのパネルで全部を説明しようとしないことでした。

相関のような指標は、単純な数値だけでは判断が難しい場合があります。
そのため、

まず 全体傾向を見るパネルを置き、
必要に応じて 補助パネルで詳細を確認する

という二段構造にしています。

これによってダッシュボードの読み順は

[C] Return Corr Trend (bf_fx vs binance_perp)

必要なら詳細パネルを確認

という形になります。


C系統の役割は、あくまで 市場間の基本的な関係性を確認することです。
ここで見ているのは戦略シグナルではなく、

  • 市場同士に関係があるのか
  • その関係は安定しているのか

という 構造の前提条件です。

この前提が確認できて初めて、
次のレイヤーである M(Market State)系統
市場間の価格差そのものを観測する意味が出てきます。

次の章では、今回の改修で最も大きく変えた部分である
**M系統の再設計(premiumを分布として観測する仕組み)**について整理していきます。

6. M系統を作り直した:premiumを閾値ではなく分布で見る

今回のダッシュボード改修で、最も大きく手を入れたのが M(Market State)系統です。
ここでは、市場間の価格差、つまり premium を観測しています。

これまでの構成では、premium を主に 閾値ベースで見ていました。
たとえば、

  • premium ≥ 8bps
  • premium ≥ 10bps
  • premium ≥ 12bps

といった条件を満たしたときにイベントとして記録する形です。

この方法は、歪みイベントを検出する目的では分かりやすいのですが、実際に観測器を動かしてみると、ひとつ問題が見えてきました。

それは、premium がイベントではなく背景状態として存在している可能性です。

たとえば特定の市場ペアでは、

  • premium の平均が 20bps 前後
  • premium ≥ 10bps の発生率がほぼ常時

といった状態が観測されました。

この場合、

「premium が 10bps を超えた」

という条件は、もはや特別なイベントではありません。
単に その市場の通常状態を記述しているだけになります。

もしその状態で閾値イベントを見続けると、

イベント発生
→ 実は通常状態

という構造になり、指標としての意味が薄くなってしまいます。

そこで今回の改修では、premium の観測方法を

閾値ベース → 分布ベース

へ切り替えることにしました。

重要なのは、

  • premium が存在するか
    ではなく
  • premium がどのような分布を持っているか

を見ることです。


premium を分布として観測する

M系統では現在、premium を次の三つのパネルで観測しています。

  • [M] Premium Width/Tail Trend (bf_fx vs binance_perp)
  • [M] Premium Width Median (|exec_best|, 5m)
  • [M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)

それぞれ役割が異なります。


全体の幅を見る

[M] Premium Width/Tail Trend (bf_fx vs binance_perp)

このパネルでは、premium の **幅と裾(tail)**の変化を時系列で表示しています。

ここで見ているのは、

  • premium の平均的な幅
  • 極端な値がどれくらい発生しているか

といった 分布の形です。

premium が安定した幅を持っているのか、
それとも突発的なイベントとして発生しているのかを確認できます。

また、以下の2つのパネルで、現時点の「Premiumの乖離の平均値」と「Premiumの乖離のP95」も詳細に見えるようにしています。


中央値を見る

[M] Premium Width Median (|exec_best|, 5m)

次に見るのが、この中央値パネルです。

ここでは、**実際に執行可能な価格差(executable)**をベースに、
premium の中央値を表示しています。

中央値を使う理由はシンプルで、
平均値は外れ値に引きずられやすいからです。

中央値を見ることで、

現在の市場で
どれくらいの premium が「普通の状態」なのか

を把握できます。


分位点を見る

[M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)

最後に、premium の分布をもう少し細かく見るためのパネルです。

ここでは、

  • P50(中央値)
  • P75
  • P90
  • P95
  • P99

といった 分位点を同時に表示しています。

これによって、

  • premium の通常レンジ
  • tail がどれくらい厚いか
  • 極端な価格差がどの程度発生しているか

を一目で確認できます。

たとえば、

P50 と P95 がほとんど離れていない場合、
premium はかなり安定した分布を持っていると考えられます。

逆に P99 が大きく跳ねる場合、
まれに大きな歪みが発生している可能性があります。


premiumを「状態量」として扱う

このように分布として観測することで、premium の意味づけが変わります。

以前の構成では、

「premium ≥ X」

という条件が中心でした。

しかし分布を見始めると、
重要なのはその値そのものではなく、

  • 平均からどれくらい外れているのか
  • 分布のどの位置にあるのか

という 相対的な位置になります。

つまり premium は、

イベント

ではなく

市場状態(state)

として扱う方が自然な場合がある、ということです。

今回の M系統の改修は、その状態を 事実ベースで観測できる形にすることを目的にしています。

次の章では、この分布をもう少し具体的に理解するために、
各 premium パネルの役割をもう少し細かく整理していきます。

7. Premium Width / Median / Quantiles をどう分けて置いたか

前章では、M系統で premium を「閾値」ではなく「分布」として観測するようにした理由を書きました。
ここでは、その分布を具体的にどのようなパネルで見ているのか(各パネルの解釈の話など)を、もう少し整理しておきます。

現在のダッシュボードでは、premium を観測するために次の三つのパネルを配置しています。

  • [M] Premium Width/Tail Trend (bf_fx vs binance_perp)
  • [M] Premium Width Median (|exec_best|, 5m)
  • [M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)

どれも premium の分布を扱っていますが、それぞれ役割が違います。
一言で言えば、

  • 全体の動きを見るパネル
  • 基準水準を見るパネル
  • 分布の形を見るパネル

という分担になっています。


全体の動きを見る

[M] Premium Width/Tail Trend (bf_fx vs binance_perp)

このパネルは、premium の幅と tail の変化を 時系列で確認するためのパネルです。

ここでは、

  • premium の平均的な幅
  • tail(分布の裾)の広がり

といった指標を時間軸で表示しています。

役割としては、

「いま premium の状態がどう変化しているのか」

をざっくり把握することです。

たとえば、

  • premium の幅が急に広がっている
  • tail が厚くなっている
  • 逆に分布が収束している

といった変化は、このパネルを見るとすぐに分かります。

つまりこのパネルは、premium の分布を 時間方向に観測するためのパネルです。


基準水準を見る

[M] Premium Width Median (|exec_best|, 5m)

次に見るのが、この中央値パネルです。

ここでは、premium の分布の中でも **中央値(median)**を表示しています。

しかも、このパネルでは

実際に執行可能な価格差

をベースにしています。

具体的には、

  • bid / ask を使った executable な価格差
  • その絶対値の中央値

を計算しています。

パネル名にもあるように、表示しているのは

|exec_best|

つまり 実行可能な premium の大きさです。

このパネルの役割は、

「今の市場では、どれくらいの premium が普通なのか」

という 基準水準を確認することです。

分布を見るうえで中央値を使う理由は、平均値よりも 外れ値の影響を受けにくいからです。

premium の分布では、まれに大きな価格差が発生することがあります。
平均値だけを見ていると、そうしたイベントに引きずられてしまいます。

中央値を見ることで、

通常状態の premium

を比較的安定した形で観測できます。


分布の形を見る

[M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)

最後のパネルは、premium の分布そのものをもう少し細かく見るためのものです。

このパネルでは、次の分位点を同時に表示しています。

  • P50
  • P75
  • P90
  • P95
  • P99

つまり、premium の分布を

中央値

やや大きい値

かなり大きい値

極端な値

という形で段階的に観測しています。

このパネルを見ると、たとえば次のようなことが分かります。

  • P50 と P95 が近い
    → premium は比較的安定した分布
  • P95 と P99 が大きく離れている
    → まれに大きな歪みが発生している
  • 分位点全体が上にシフトしている
    → 市場全体の premium 水準が変化している

つまり、このパネルは

premium の分布の「形」

を観測するためのものです。


三つのパネルの役割

ここまでの内容をまとめると、三つのパネルは次の役割分担になります。

[M] Premium Width/Tail Trend (bf_fx vs binance_perp)
→ premium の動きを時系列で観測する

[M] Premium Width Median (|exec_best|, 5m)
→ premium の通常水準を確認する

[M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)
→ premium の分布の形を確認する

この三つを組み合わせることで、

  • premium の現在の水準
  • premium の分布
  • premium の時間変化

を、それぞれ別の視点から観測できるようになります。

M系統の役割は、ここまでです。
ここではまだ 戦略判断は行いません

やっているのは、

「市場間の価格差がどのような状態で存在しているのか」

という 市場状態の観測だけです。

次の章では、この premium を計算する際に使っている **価格の基準(mid と executable)**について整理します。

8. 執行ベースとmidベースをどう使い分けているか

M系統で premium を観測する際、もう一つ意識しているのが 価格の基準です。
具体的には、次の二種類の価格を使い分けています。

  • mid価格ベースのpremium
  • executable価格ベースのpremium

どちらも同じ「価格差」を見ているのですが、意味合いは少し違います。


mid価格:市場状態をざっくり把握するための基準

まず mid価格です。

mid は

mid = (best_bid + best_ask) / 2

で計算される、いわゆる板の中央価格です。

この価格は実際に約定する価格ではありませんが、市場の状態をざっくり把握するには便利です。
スプレッドの影響をある程度ならした形で価格を比較できるため、

  • 市場間の価格水準
  • 大まかな premium の方向
  • 市場のトレンド

といったものを観測する用途には向いています。

そのため、ダッシュボードでは

[M] Premium Mid bps (bf_fx - binance_perp)

のようなパネルで、midベースの premium を表示しています。

このパネルの役割は、

「今、市場間の価格差がどちらの方向に開いているのか」

といった 粗いスキャンを行うことです。


executable価格:実際に執行可能な価格差

一方で、トレードを考える場合には 実際に約定できる価格差を見る必要があります。

そのため multi_market_probe では、
executable な価格差も同時に計算しています。

具体的には、

  • bf_fx の best bid / ask
  • binance_perp の best bid / ask

を組み合わせて、

buy market A
sell market B

という形で 実際に成立しうる価格差を計算します。

この値が、ダッシュボードの

[M] Premium Width Median (|exec_best|, 5m)
[M] Premium Width Quantiles (P50/P75/P90/P95/P99, 5m)

といったパネルで使われている exec ベースの premiumです。

ここで見ているのは、理論上の価格差ではなく、

スプレッドを含めた、実際に成立する価格差

になります。


なぜ二つの基準を併用するのか

この二つの基準を分けている理由はシンプルです。

mid価格は
市場状態を理解するのに向いている

一方で executable価格は
トレード可能性を評価するのに向いている

からです。

もし executable だけを見ていると、

  • スプレッド
  • 一時的な板の歪み

といった要素に強く影響されてしまい、市場全体の状態が見えにくくなります。

逆に mid だけを見ていると、

「理論上は大きな価格差があるのに、実際にはスプレッドで消えてしまう」

というケースを見逃してしまいます。

そのため multi_market_probe では、

  • midベース → 市場状態の観測
  • execベース → 実行可能性の評価

という形で役割を分けています。


M系統で見ているもの

ここまでの内容をまとめると、M系統では次の二つの視点を同時に扱っています。

  • 市場間の価格差が どのような分布を持っているのか
  • その価格差が 実際に執行可能な形で存在するのか

ただし、この段階でもまだ戦略判断は行いません。

M系統で行っているのは、

「市場間の価格差がどのような状態で存在しているのか」

という 事実の観測だけです。

この状態がどのような結果につながるのかを確認するのが、
次のレイヤーである Forward(F)系統になります。

次の章では、今回の改修を通して見えてきた 市場の事実について、いくつか整理しておきます。

9. 今見えていること:premiumの“事実”は見えるようになった

ここまで見てきたように、今回の改修では Q / C / M 系統を整理し、
市場状態を 分布として観測できる形に整えました。

まだ Forward(F)や Judgment(J)まで踏み込んだわけではありませんが、
それでも実際にダッシュボードを動かしてみると、いくつか気づくことが出てきます。

ただしここで強調しておきたいのは、
まだ解釈はしないということです。

multi_market_probe は、最初から戦略を作るためのボットではありません。
まずは市場の状態を観測し、その分布を理解することが目的です。

その前提で、現時点で見えている「事実」をいくつか整理しておきます。


premium はイベントではなく背景状態かもしれない

M系統のパネルを見ると、
bitFlyer FX と binance-perp の間には、ある程度の premium が 常に存在していることが分かります。

これは直感的には少し意外な結果でした。

市場間トレードを考えるとき、つい

「premium が広がった瞬間」

をイベントとして捉えがちです。

しかし実際の分布を見ると、

  • premium がある程度の水準で常時存在している
  • むしろそこからの変動が小さい

という可能性が見えてきます。

もしこれが本当に市場の通常状態だとすると、

「premium が X bps を超えたらエントリー」

という単純なルールは成立しにくくなります。

なぜなら、その条件自体が 異常ではなく通常状態だからです。


相関はあるが、非常に強いわけではない

C系統のパネル
[C] Return Corr Trend (bf_fx vs binance_perp)
を見ると、bitFlyer FX と binance-perp のリターンには 一定の相関があります。

ただし、その相関は非常に強いわけではありません。

完全に同じ動きをしているわけでもなく、
かといって無関係というほど弱くもない。

つまり、

  • 市場はある程度連動している
  • しかし完全なコピーではない

という状態です。

これは市場間トレードの観点では、むしろ自然な状態とも言えます。
もし二つの市場が完全に同じ動きをしているなら、価格差はほとんど発生しません。

逆に、ある程度のズレが存在するからこそ、
premium という状態が生まれます。


観測器としては「正常に見える」

今回の改修で確認できたもう一つの点は、
観測器としての multi_market_probe が 安定して動いているということです。

Q系統では

  • feed state
  • 更新間隔
  • latency

といった指標を確認していますが、現時点では大きな異常は見えていません。

また、binance-perp の取得を WebSocket に移行したことで、
データ更新の安定性もかなり改善しました。

これは地味ですが、観測器としては重要な進展です。

データ取得が不安定な状態では、
premium や相関の議論そのものが成立しません。

その意味では、今回の改修で

  • データ取得
  • 品質監視
  • 市場状態の可視化

という 観測の土台は、かなり整ってきました。


まだ結論は出さない

ここまで書いてきた内容から、
「ではどの戦略が成立するのか」と考えたくなるかもしれません。

ただし、現時点ではまだそこまで進む段階ではありません。

なぜなら、

  • premium の分布をまだ十分に理解していない
  • future outcome の統計もまだ十分ではない
  • horizon(観測時間)も仮設定のまま

だからです。

この段階で戦略を作ってしまうと、

偶然の分布

偶然の結果

偶然の戦略

という形になりやすくなります。

multi_market_probe の役割は、
まず 市場の状態を事実として観測することです。

premium がどのような分布を持っているのか。
その状態がどれくらい続くのか。
条件が成立した後に何が起きるのか。

そうしたデータが揃って初めて、
「この構造は戦略として使えるかもしれない」と言えるようになります。

今回の改修でできるようになったのは、
その事実を観測できる状態に近づいたというところです。

最後に、この状況を踏まえて
次の開発フェーズで何を詰めるのかを整理しておきます。

10. F系統とJ系統は次回へ

今回の改修では、Q / C / M 系統の整理を中心に進めました。
観測器としての土台である

  • データ品質の確認(Q)
  • 市場間の関係性(C)
  • 市場状態としての premium(M)

を、できるだけ読みやすい形で可視化するところまで来ています。

ただし、ここまでのレイヤーはあくまで 観測の前段階です。
ここで見ているのは

市場がどういう状態にあるのか
という 現在の事実だけです。

次のフェーズでは、その状態が

その後どう変化するのか
という 時間方向の情報を扱う必要があります。

そこで次に取り組む予定なのが、
F(Forward)系統J(Judgment)系統の整理です。


F系統:結果の分布を見る

F系統では、Forward層で記録している

  • persistence(premium の継続時間)
  • future outcome(一定時間後の変化)

といった指標を可視化します。

ここで見たいのは、

ある条件が成立したとき
その後どうなるのか

という 条件付きの結果分布です。

たとえば、

premium ≥ 20bps
という状態が発生したときに

  • 30秒後に縮小する確率
  • 平均でどれくらい縮むのか
  • 逆に拡大するケースはどれくらいあるのか

といった統計が見えてきます。

この段階になって初めて、

回帰傾向が存在するのか
それとも premium が持続するのか

といった 市場構造の仮説を検証できるようになります。


J系統:戦略の視点で整理する

その上にあるのが J(Judgment)系統です。

ここでは Forward層のデータをもとに、

  • Reversion(歪み回帰)
  • Lead-Lag(リード/ラグ)
  • Hedge(ヘッジ)

といった戦略ごとの視点で指標を整理します。

Screenshot

ただし、このレイヤーは Forward層とは性質が違います。

Forward層は
市場で観測された事実

ですが、

Judgment層は
その事実をどう読むかという解釈

です。

たとえば

  • Reversion strength
  • Lead-Lag strength
  • Hedge feasibility

といったスコアは、すべて Forward層のデータをもとにした 解釈モデルです。

そのため、この層の設計はかなり慎重に行う必要があります。
もし Forward層の分布を十分に理解しないままスコアを作ると、

Forwardの値

Judgmentスコア

それを根拠に戦略

という 循環構造になってしまう可能性があります。


観測 → 分布 → 解釈

multi_market_probe の開発は、いま次の段階にいます。

市場を観測する

分布を理解する

その結果を解釈する

今回の改修で、
観測と分布の部分はかなり整理されてきました。

その次に進むのが、

Forward の結果分布を可視化し
そこから戦略ごとの解釈を組み立てる

というフェーズです。


今回の記事は、multi_market_probe を
観測器として読める形に整えた段階までの開発ログでした。

戦略を作るのは、そのあとです。

まず市場の状態を観測する。
その分布を理解する。
そして、その結果として構造が見えてくるなら、そのとき初めて戦略として採用する。

次回は、Forward層とJudgment層のメトリクスを整理しながら、
条件付き結果の分布と戦略解釈の関係について書く予定です。

-Bot, CEX, 開発ログ