こんにちは。ぼっちbotterよだかです。
前回は、Binance Japan の BTC/JPY を対象にした新規リードラグ研究について、何を仮説として置き、どういう順番で検証していくかを整理しました。今回はその続きとして、まずは global BTC/USD × USD/JPY を fair value の基準線に置き、Binance Japan 側の価格がそこからどれだけズレるのかを観測するための Phase1 観測機を最小構成で立ち上げました。まだこの段階で Lead-Lag を証明したいわけではありません。むしろ、fair value だけでどこまで説明が尽きるのかを先に疑い、そのうえで次に何を見るべきかを判断できる土台を作ることが今回の目的です。

-
-
🛠️開発記録#502(2026/4/4)リードラグ研究メモ「Binance JapanのBTC/JPYにLead-Lagはあるのか ― 新規研究の仮説と検証順序」
続きを見る
今回の目的: Lead-Lagを証明する前に、最小観測機を通す
今回の開発で最初に置いた目的は、Lead-Lag 構造をいきなり証明することではありませんでした。
むしろ逆で、その前段として、最小構成の観測機をきちんと動かし、「何が見えていて、何がまだ見えていないのか」を切り分けられる状態を作ることを優先しました。
前回の記事では、Binance Japan の BTC/JPY を対象にした新規リードラグ研究について、研究対象、背景仮説、作業仮説、帰無仮説、検証順序までを先に言葉で整理しました。あの時点では、「何を疑い、何を順番に確かめるか」はだいぶ固まりましたが、当然ながらそれだけでは観測は進みません。実際に見える形へ落とし込んで初めて、仮説が土台を持ちます。そこで今回は、その最初の一歩として、Phase1 観測機を最小構成で立ち上げることにしました。
ここで大事にしたかったのは、最初から情報源や判定ロジックを増やしすぎないことです。
新しい研究テーマに入ると、「せっかくだからこれも見たい」「どうせならこの市場も加えたい」と対象を広げたくなります。ただ、そうやって最初から広げてしまうと、あとで何かが見えたとしても、それがどの要素によるものなのかを切り分けにくくなります。特に今回のテーマは Lead-Lag なので、“何か先に動いているように見えるもの”はいくらでも作れてしまう危険があります。だからこそ今回は、まずは最小の説明系だけを置き、それでどこまで説明できてしまうのかを先に疑うことを目的にしました。
今回の観測機でやりたいことを一言で言えば、
「Binance Japan の BTC/JPY は、グローバルな BTC/USD と USD/JPY だけでどこまで説明できるのか」を見ることです。
もしこの最小構成だけで短期価格形成の大部分が説明できてしまうなら、少なくとも現段階では、他市場や他情報源を増やしてまで Lead-Lag 構造を掘りにいく優先度は下がります。逆に、fair value を置いたうえでもなお説明しきれないズレが残るなら、その時点で初めて「では、その残差に対して何が先に効いているのか」を見に行く意味が出てきます。つまり今回の Phase1 は、Lead-Lag の本体に踏み込む前の、研究全体の関所のような位置づけです。
この方針は、仮説に執着しないためでもあります。
新しい研究を始めると、自分の中で「こういう構造がありそうだ」という期待がどうしても生まれます。ただ、その期待を抱えたまま観測対象を増やしていくと、見たいものを見てしまいやすくなります。今回避けたかったのはまさにそこです。だから今回は、「Lead-Lag があるはずだ」と前に進むのではなく、いま置ける最小の説明系で本当に説明が尽きないのかを先に確認することにしました。結果として、何かが見えれば前進ですし、逆に思ったより説明が尽きてしまうなら、それもまた価値のある結論です。
その意味で、今回の開発は「勝ち筋を見つける作業」そのものではありません。
もっと手前の、観測の地盤を作る作業です。
Binance Japan の BTC/JPY、グローバルな BTC/USD proxy、そして USD/JPY を用意し、それらから fair value を作り、Binance Japan 側の価格とのズレを premium / residual として見る。この導線をまず通しておく。今回やっているのは、そうした基礎工事に近いものです。派手さはありませんが、ここを飛ばして先へ進むと、後から見えてきたものを解釈するときに足場が不安定になります。
ですので、今回の目的はかなり限定的です。
Lead-Lag を証明することではなく、Lead-Lag を探しに行く価値があるかどうかを判断できる最小観測機を通すこと。
まずはそこを達成ラインに置いて、現実に見えるものとまだ読んではいけないものを切り分けられる状態を作る。それが、DAY1 の開発でやりたかったことでした。
何を fair value として置いたのか
今回の Phase1 では、fair value を次のように置きました。
fair value JPY = global BTC/USD mid × USD/JPY mid
ここで使っている global BTC/USD mid は Binance Global 側の BTC/USD proxy、USD/JPY mid は FX 系列です。
意味としては、「Binance Japan の BTC/JPY が、グローバルな BTC 価格と為替だけで機械的に決まるとしたら、いまどのあたりにいてもおかしくないか」を表す基準線です。
大事なのは、この fair value が「本来あるべき理論価格」や「BTC の本源的な価値」を意味しているわけではないことです。
今回はそこまで大きな話をしたいのではなく、あくまで 価格形成を分解して見るための基準線 として置いています。
今回この形を採った理由は、BTC/JPY の値動きには少なくとも二つの要因が混ざっていると考えたからです。
一つは BTC そのもののドル建て価格変動、もう一つは円ドル為替の変動です。この二つを最初から分けて見ておかないと、あとで Binance Japan 側のズレを見たときに、「BTC 側の変化なのか」「為替側の変化なのか」「それでも説明できない残差なのか」が分かりにくくなります。
たとえば、BTC/USD が横ばいでも USD/JPY が円安に動けば、BTC/JPY は上がります。
逆に、為替が動かなくても BTC/USD が上がれば、やはり BTC/JPY は上がります。見た目としてはどちらも「BTC/JPY が動いた」ですが、中身は別です。だから今回は、最初から
- BTC/USD 側の変動
- USD/JPY 側の変動
- それでも説明しきれない Binance Japan 側のズレ
の三つに分けて見られるようにしておきました。
そのうえで、Binance Japan 側の価格との差分を premium として定義しています。
premium_bps = (BJ mid - fair value JPY) / fair value JPY × 10000
この premium は、「Binance Japan の BTC/JPY が、グローバル BTC 価格と為替で作った基準線に対して、いまどれだけ上振れ・下振れしているか」を bps で見たものです。
さらに、これを rolling median と MAD で正規化したものを residual_z として見ています。
ここでのポイントは、premium や residual を「Lead-Lag の証拠」とはまだ扱わないことです。
この段階で見たいのは、あくまで fair value だけで説明が尽きるのか、それとも一定のズレが残るのか です。もし premium がほとんど残らないなら、この最小構成だけでかなり説明できていることになります。逆に、安定したズレが残るなら、次に「そのズレに対して何が先に効いているのか」を見にいく理由ができます。
つまり今回の fair value は、Binance Japan の BTC/JPY を評価するための答えではなく、説明可能な部分を先に切り出すための土台です。
ここを置いておくことで、次に他の市場や情報源を足したときも、「それは本当に追加の説明力なのか」「ただの為替やグローバル価格の言い換えではないのか」を見分けやすくなります。
まずは小さく通すために、実装をどう絞ったか
今回の実装では、最初から機能を広げすぎないことを重視しました。
新しい研究テーマでは、見たいものを増やそうと思えばいくらでも増やせます。ただ、最初の段階で対象や機能を盛り込みすぎると、何が原因で動いているのかが見えにくくなります。そこで今回は、「まず観測機を通す」「fair value と premium が見える状態を作る」という一点に絞って構成を決めました。
観測対象として置いたのは、次の三つだけです。
- Binance Japan の BTC/JPY
- Binance Global 側の BTC/USD proxy
- USD/JPY
この三本から fair value JPY = global BTC/USD mid × USD/JPY mid を作り、Binance Japan 側とのズレを premium / residual として見る、という形です。
つまり、最初から複数の海外市場やデリバティブ市場を並べて比較するのではなく、まずは最小の説明系だけを置くことを優先しました。
価格の取り方も、初手はできるだけ単純にしています。
板全量や複雑な約定分析には入らず、まずは top-of-book から mid を作る形にしました。これなら系列の意味が分かりやすく、実装も軽くできます。Phase1 で欲しいのは執行可能価格の厳密な評価ではなく、基準線とズレの観測なので、最初はこの形で十分だと判断しました。
FX 側も同じ考え方です。
最初は専用の高頻度 feed を前提にしていましたが、無料枠と運用のしやすさを考えて、最終的には API キー不要の公開レートを polling する構成 に寄せました。今回の目的では、USD/JPY を高精度に研究する必要はありません。必要なのは、BTC/JPY の変動を分解するための補助系列として、壊れずに一本入っていることです。ここで為替データの品質を追いすぎると、研究の主題がずれてしまいます。そのため、まずは粗くても動く構成を優先しました。
監視項目も最低限に絞っています。
見たいのは主に次のものです。
- BJ mid
- global BTC/USD mid
- USD/JPY mid
- fair value
- premium_bps
- residual_z
- freshness / source alive / error count
これ以上の指標を最初から増やすこともできますが、Phase1 ではまだ不要です。
今必要なのは、「各系列が取れているか」「fair value が計算できているか」「premium がどの程度残るか」を見られることです。そこが通って初めて、次に何を足すべきかを考えられます。
既存の観測機と干渉しないように、運用面も分離しました。
Grafana、Prometheus、exporter のポートは既存系と競合しない番号を使い、metrics prefix や保存先ディレクトリも分けています。これにより、今動かしている別系統の観測機を止めずに、新しい Phase1 を並行して回せる状態にしました。実験系を増やすときに既存環境を壊さないことは、地味ですがかなり重要だと思っています。
保存まわりも、最初から重くしない方針です。
raw を何でも保存するのではなく、ストレージ爆発を避けることを優先しました。今回の段階では「長期にわたって高精細な再生をする」より、「観測機を継続稼働できる」ことの方が大切です。そのため、保存頻度や監視項目は抑えめにし、まずは運用に乗る形を目指しました。
要するに、今回の実装方針は一貫しています。
精度や機能を最初から取りにいくのではなく、最小の説明系を壊さずに動かし、そこから次に進む理由があるかどうかを見られる状態を作ること。
その意味で今回の Phase1 観測機は、完成形ではなく、研究を前に進めるための足場として設計しました。
実装で実際に詰まったところ
今回いちばん時間を使ったのは、売買ロジックそのものではなく、「この観測機をどういう前提で動かすのか」を実装側にきちんと反映し直すことでした。
結果だけ見ると、Docker を外した、Grafana を直した、FX ソースを差し替えた、という話に見えるかもしれません。ただ、実際にはその一つひとつが「この研究で何を優先するのか」を決める作業でもありました。ここは単なるトラブル記録ではなく、意思決定の整理として残しておきたいと思います。
1. 最初の詰まりは、実装前提そのもののズレでした
最初に詰まったのは、監視スタックが Docker 前提で組まれていたことです。システム実装の屋台骨は私が構想を練っているのですが、その構想をAIに共有して実装に落とす過程で、Docker前提で組まれていたというのが原因です。AIが気を回してくれたことによる不整合と言っても良いかもしれません。make start や make prom-start を叩くと Docker daemon に接続しにいき、そこで止まりました。原因自体は単純で、実装側が docker compose 前提になっていたからです。こちらから Docker 利用を依頼したわけではなかったので、これは「起動方法の問題」というより、実装前提の置き方がずれていたと捉えた方が正確でした。
ここでの判断ははっきりしていて、Docker を起動して合わせるのではなく、実装側をローカル実行前提へ戻すことにしました。
理由は二つあります。一つは、今回の目的が Phase1 の観測機を最小構成で通すことだったこと。もう一つは、既存の観測機と並行稼働させる前提なので、運用手順はなるべく単純な方がよかったことです。結果として、make prom-start、make grafana-start、make probe-start がローカル実行で通る形へ修正してもらいました。ここで大事だったのは、「とりあえず Docker を立てて先に進む」ではなく、最初に決めた運用前提に実装を合わせると判断したことです。
2. 次に詰まったのは、分離したはずの監視環境が実は分離しきれていなかったことです
ローカル実行へ直したあと、Grafana のダッシュボードを開くと、既存の別ダッシュボード側のログインが切れる問題が出ました。
原因は localhost 上の Cookie 名衝突で、localhost:3000 と localhost:3001 が同じ grafana_session を上書きし合っていました。ポートを分ければ十分だと思いがちですが、実際にはそれだけでは不十分でした。
このときの判断は、「ポート分離だけで十分」と考えるのをやめ、セッション管理まで含めて別システムとして扱うことでした。
そのため、専用 Grafana 側の Cookie 名を変更してもらいました。地味な修正ですが、この問題を放置すると「別システムとして並べて動かす」という前提そのものが崩れます。今回の観測機は既存系と独立して動いてほしかったので、見た目のポート番号だけでなく、ブラウザ上のセッションも含めて分離する方向を選びました。ここは、運用上の小さな違和感を軽視せず、独立性を実際の挙動で担保する方向に切った場面でした。
3. 「起動しているのに No data」という状態では、配線を一つずつ疑うしかありませんでした
その後、プロセス自体は起動しているのに、Grafana のパネル群がすべて No data になる問題が出ました。
この段階では prometheus、grafana、probe の各プロセスは生きていたので、一見すると「動いているように見える」のですが、実際には監視の配線が通っていませんでした。
まず原因の一つは、Grafana の datasource がまだ Docker 向け URL のままだったことです。
Grafana は http://prometheus_bjll:9090 を見に行っていたのに、実際の Prometheus はローカルの 127.0.0.1:9092 で動いていました。これでは Grafana から Prometheus に届きません。ここでの判断は、当然ながら datasource をローカル用に切り替えることでしたが、重要なのはその前に「No data を UI 側の問題と決めつけず、まず接続経路を疑う」という順番を守れたことです。
もう一つの原因は、Grafana の dashboard provisioning 先が Docker 用のパスを見ていたこと、そして make start の起動順で Prometheus が probe より先に立ち上がっていたことでした。
前者は /var/lib/grafana/dashboards を見ていて、ローカル環境では当然そこにダッシュボードがありません。後者は、probe がまだ立ち上がっていない初回 scrape のタイミングで Prometheus が Service Unavailable を返していました。これも、単に「表示がおかしい」ではなく、ローカル運用へ直したのに、一部の前提がまだ Docker 時代のまま残っていたことが問題でした。そこで、dashboard path をローカル用へ修正し、起動順と ready 待ちも合わせて直してもらいました。ここでは、場当たり的に一箇所ずつ直すより、「何が Docker 前提のまま残っているか」をまとめて洗い直す判断をしたのが大きかったです。
4. FX データ取得は、単なるデータソース選びではなく、研究の優先順位を確認する場面でした
実装面でいちばん判断が必要だったのは FX 側です。
最初は TraderMade や Twelve Data のような API キー前提のソースを使う形にしていました。しかし、この時点で改めて考えたかったのは、「今回の Phase1 で本当に必要なのは何か」ということでした。もしここで高頻度・高品質な FX データにこだわり始めると、研究の主題がずれてしまいます。今回欲しいのは FX そのものの精密な研究ではなく、BTC/JPY を分解するための補助系列として USD/JPY を一本入れることでした。
そのため、最終的には API キー不要の公開レート API を優先する方針へ切り替えました。
最初は Twelve Data を第一候補にする案も試しましたが、最終的には Frankfurter を優先し、REST polling で USD/JPY を取得する構成へ寄せています。更新頻度は粗くなりますが、その代わり無料・無認証で通せます。ここでの判断は、「最良の FX ソースを選ぶ」ではなく、Phase1 の目的に対して十分な最小解を選ぶことでした。将来的に必要なら差し替えればよいので、この段階ではまず観測機を継続稼働できることを優先しました。
5. この章で残しておきたいのは、「詰まった」ことより「どこで線を引いたか」です
今回の実装で詰まった箇所は、表面的にはいくつもあります。
Docker 前提、Cookie 衝突、datasource の向き先、dashboard path、起動順、FX ソースの切り替え。ですが、私にとって重要だったのは、個々のバグそのものよりも、そのたびに 何を修正し、何を後回しにしたか です。
- Docker は合わせるのではなく外す
- 監視環境はポートだけでなくセッションまで分離する
- No data は UI ではなく配線から疑う
- FX は高品質化より先に無料・無認証で一本通す
- いま必要ない精度は取りにいかない
今回の判断をまとめると、こうなります。
Phase1 に必要なものだけを残し、それ以外は切る。
言い換えれば、実装の詰まりを通じて、研究の優先順位をもう一度確認していたとも言えます。観測機は「動けばよい」わけではありません。何のために動かすのかが崩れるなら、たとえ動いても意味が薄くなります。今回の DAY1 は、その意味で、コードを書く日であると同時に、研究の境界線を実装に反映し直す日でもありました。
いま見えているものと、まだ読んではいけないもの
ここまでで、少なくとも **「観測機としての導線は通った」**とは言えます。
Binance Japan の BTC/JPY、グローバル BTC/USD proxy、USD/JPY の三本が入り、fair value、premium、residual_z まで一通り可視化できる状態になりました。ダッシュボードとして見たい最低限のものが並んだので、Phase1 の土台はひとまずできたと考えてよさそうです。

まず、いま見えていることを整理します。
一つ目は、Binance Japan 側とグローバル BTC/USD 側の価格系列は、少なくとも観測対象として成立しているということです。両方とも継続して更新されており、mid 系列として扱える状態にあります。fair value も計算されており、Binance Japan 側の価格との差分として premium が出ています。つまり、「価格系列が取れていない」「計算が通っていない」という段階ではもうありません。
二つ目は、premium がゼロ近辺に張り付いているわけではないということです。
スクリーンショットを見る限り、premium_bps はおおむね 14〜16bps 台で推移しており、時間の経過とともに少しずつ形を変えています。少なくとも、fair value を置いた瞬間に Binance Japan 側の価格が完全に説明され尽くした、という見え方ではありません。この時点で、「最小構成を置いてもまだズレは残る」という事実は一応確認できます。
ただし、ここで慎重でいたいのは、そのズレをすぐに「意味のある residual」だと読まないことです。
今回の fair value は、global BTC/USD × USD/JPY から作った機械的な基準線です。そして USD/JPY 側は、今の段階では Frankfurter の coarse な polling を前提にしています。実際、freshness を見ると USD/JPY は 10〜30秒程度の粗い更新になっており、crypto 側の系列とは明らかに時間粒度が違います。つまり、いま見えている premium には、Binance Japan 固有のズレだけでなく、FX 側の更新の粗さによる段差や遅れも混ざっている可能性があります。
この前提を踏まえると、現時点で「まだ読んではいけないもの」もかなりはっきりしています。
まず、residual_z の絶対値はまだ研究結論として扱えません。スクリーンショットでは一度大きく負方向へ跳ねていますが、この段階では「強い歪みが観測された」とは読まず、まずは rolling MAD が小さい局面で値が過大に出ていないか、FX 更新のタイミングと重なっていないかを疑うべきです。z-score は便利ですが、前提となる系列がまだ粗いときには見かけのインパクトが強く出すぎます。

同じ理由で、candidate_state や strong_candidate_state の点灯そのものも、まだそのまま意味づけしない方がよいと考えています。
いまの段階では、これらは「将来的にこういう監視をしたい」という導線確認に近いものです。点灯したこと自体をもって「Lead-Lag の候補が見えた」と解釈するのは早いです。特に FX 側が coarse である以上、very short な residual 判定はかなり保守的に読む必要があります。
では、いま何を読んでよいかというと、そこはもっと地味な部分です。
たとえば、
- 各系列が安定して更新されているか
- USD/JPY の freshness がどれくらい粗いか
- premium がどの程度の帯で推移しているか
- candidate 点灯が特定の更新タイミングに偏っていないか
といった、観測機の癖そのものです。
この Phase1 では、勝ち筋を読みにいくより先に、「このシステムはどういう歪み方をするのか」「どこから先をまだ信用してはいけないのか」を把握する方が大切です。
今のスクリーンショットから受ける印象を素直に書くなら、
fair value を置いても premium はそれなりに残っているが、その中身はまだ“Binance Japan 固有の残差”と断定できる段階ではない、というところです。
これは後ろ向きな話ではありません。むしろ、最初の一日でここまで見えているなら十分です。観測機としては通っており、しかも「何がまだ粗いのか」もかなり見えています。Phase1 としては、いまはそれで十分だと思います。
要するに、現時点での読み方はこうです。
価格の導線は通った。ズレも見えている。だが、そのズレをすぐに構造として読んではいけない。まずは観測機の前提と限界を把握する。
この順番を崩さないことが、次の観測をきれいに進めるうえで大事だと感じています。
次に確認すること
ここまでで、Phase1 観測機を最小構成で立ち上げ、価格系列・fair value・premium・residual の導線を通すところまではできました。
次にやることは、機能追加ではなく、いま見えているものを少し長めに観測して、この観測機がどこまで使えるのかを確かめることです。
まず確認したいのは、premium_bps がどのような帯で推移するのかです。
現時点では、ゼロ近辺に張り付くというより、一定の幅を持って動いているように見えます。ただ、この幅が Binance Japan 側の相対的なズレを示しているのか、それとも FX 側の粗い更新や基準線の置き方によるものなのかは、まだ切り分け切れていません。したがって次は、まず数時間単位で観測を続けて、premium がどの程度の水準に滞留しやすいのか、どの時間帯で帯が変わるのかを見ていきます。
次に見たいのは、USD/JPY の freshness と premium の動きがどれくらい結びついているかです。
今回の FX 系列は API キー不要・無料枠優先で組んでいるため、更新は coarse です。これは設計上の意図に沿った選択ですが、そのぶん premium や residual の見え方に段差が入る可能性があります。ですので、premium の変化をそのまま Binance Japan 固有のズレと読むのではなく、まずは「FX 更新直後にだけ大きく動いていないか」「freshness が荒れている局面で candidate が点灯していないか」を確認したいです。ここが見えると、今の Phase1 をどこまで信用してよいかの感覚がかなり変わってきます。
三つ目に確認したいのは、residual_z や candidate 判定が、どの場面で出ているのかです。
現時点では、これらの値をそのまま研究結論として読むつもりはありません。ただ、観測機としての癖を見る材料にはなります。たとえば、candidate が FX 更新タイミングに偏っているのか、それとも BJ と global の関係だけでもある程度出てくるのか。あるいは、rolling MAD が小さくなりすぎて z-score が過大化していないか。このあたりを見ておくことで、「いまの residual 判定はどこまでが導線確認で、どこから先が次の修正対象か」を判断しやすくなります。
そのうえで、Phase1 全体としていちばん大事なのは、fair value だけで説明が尽きるかどうかを見極めることです。
ここは今回の研究の関所でもあります。もし観測を続けた結果、premium がほぼ一定の固定差としてしか見えず、時間構造もあまりなく、しかもその大半が FX 側の coarse さで説明できるようであれば、この段階で他市場を増やす優先度は下がります。逆に、fair value を置いたあとでもなお、時間帯や局面によって説明しきれないズレが残るなら、その時点で初めて「では、その残差に対して他の市場が先行しているのか」を見にいく意味が出てきます。
ですので、次の一手は新しい市場を足すことではありません。
まずはこの観測機をしばらく回し、
- premium の分布
- premium の滞留時間
- FX freshness の分布
- candidate / strong candidate の発生タイミング
- fair value でどこまで説明が尽きるか
を確認することです。
その結果を見て、次にやることは二つに分かれます。
一つは、いまの構成のままで residual が残るなら、他市場や他情報源を足して説明力を見にいくこと。もう一つは、FX 側の粗さが解釈を強く邪魔しているなら、先に為替系列の品質を少し上げることです。
今回の DAY1 は、観測機を通すところまでがゴールでした。
次の段階では、その観測機を使って「この研究を本当に前に進める余地があるのか」を見ていきます。派手な進展ではありませんが、ここを丁寧に見ることで、次に何を足すべきか、あるいは足さないべきかを落ち着いて判断できるようになるはずです。