こんにちは。ぼっちbotterよだかです。
今回やりたかったのは、Binance Japan BTC/JPY の残差が「なんとなく取れそうに見える」段階から一歩進んで、それが執行ベースでも意味を持ちうるのかを粗く観測できる土台を作ることでした。3/5/8bpsの閾値、滞留時間、BJ側コストとの比較、戻り方をまとめて見られるようにしつつ、先に観測品質の問題も潰しています。まだこの時点で白黒を出すつもりはなく、今回はあくまで判定器の土俵を整えた段階です。加えて、指標を都合よく読み替えないように、READMEやGrafana上の注記も見直しました。今回はそのあたりの実装と、現時点で何を見ていて、まだ何を判断しないのかを整理しておきます。
-
-
🛠️開発記録#504(2026/4/6)新規リードラグ研究メモ(DAY2)「FX情報源を差し替え、fair valueの見え方を一段まともにした話」
続きを見る
1. 今回のゴールは「残差を執行ベースで粗く見れるようにする」こと

今回の作業でまずはっきりさせておきたかったのは、Binance Japan BTC/JPY に見えている残差を、単に「なんとなくプレミアムがある」と眺める段階から一歩進めることでした。ダッシュボードを見る限り、Premium(bps) は過去24時間の中でおおむね4〜8bpsあたりを推移しており、ときどき8bpsを超える場面もありました。ただし、8bps超えはそこまで頻繁ではなく、そこだけを細かく追い始めると、まだ母数の薄い事象に研究の軸を引っ張られてしまうので、今の段階でそれをやるのは得策ではないと判断しました。
そこで今回は、「この残差が執行ベースでも意味を持ちうるのか」を荒く判定するための観測面を整えることを目標に置きました。具体的には、3/5/8bpsという閾値を切り口にして、どの水準でプレミアムが発生したのか、その状態がどれくらい滞留したのか、Binance Japan 側のコストと比べて入口時点で跨いでいたのか、その後どの程度戻ったのかを、一つの土俵で見られるようにしたかったということです。要するに、残差が「大きく見える」ことと、「実際に取れる可能性がある」ことを、少なくとも観測上は分けて見られる状態を作りたかったのです。
ここで重要なのは、今回はまだ勝ち筋を確定するフェーズではないということ。いきなり精密なEV推定や閾値最適化に入るのではなく、まずは執行ベース粗判定のための最低限の判定器を作り、そのうえで母数をため、後から調整できる状態に持っていく。その意味で今回のゴールは、結論を出すことではなく、結論を出すための観測の枠組みを整えることでした。今の自分に必要なのは、残差を見て期待することではなく、残差をどう読めばよいのかを機械的に確認できる環境を作ることだったと思います。
2. まずは観測品質の穴を塞いだ

執行ベースの粗判定を足す前に、先にやっておくべきだと判断したのが観測品質まわりの修正でした。どれだけ見たい指標を増やしても、そもそも観測機が途中で落ちたり、メトリクスの見え方に無駄な誤解が入ったりしている状態では、その上に積んだ判定も信用しにくくなるからです。今回はまさにその手前の穴がいくつか見えていたので、まずはそこを塞ぐところから始めました。
ひとつは、FXまわりの取得エラーで probe 全体が止まってしまう問題です。実際に 6 時台から 9 時台にかけてダッシュボードを見ている中で、FX Freshness まわりに不自然な挙動があり、当初は Twelve Data 側の仕様や日次リセットの影響も疑いました。しかし事実ベースで追っていくと、「24時間ごとに再接続が必要」というような話ではなく、RemoteDisconnected によって probe プロセス自体が停止していたことが主因でした。つまり、見えていた NoData は API の仕様というより、こちら側の耐障害性の不足によるものでした。
この点については、例外捕捉の対象に RemoteDisconnected を追加し、URL取得の途中で相手側が切断してきても probe 全体が落ちないように修正しました。これで、同種の切断が起きても source_error_total に積みつつループ継続できるようになりました。言い換えると、観測機として最低限必要な「多少の通信不調では全停止しない」状態を先に作ったことになります。今回の主目的は執行ベース粗判定の実装でしたが、その前段としてこの修正は優先度が高かったと思っています。
もうひとつは、FX Error Total パネルがずっと NoData になっていた点です。これも最初は見た目の問題に見えましたが、実際には「エラーが発生したときだけ系列が生成される」実装になっていたため、0件のときに何も表示されないという構造上の問題でした。これでは、平常時に「正常に0なのか」「そもそも取れていないのか」が見分けにくくなります。そこで、エラー0件時でも系列が出るようにして、NoData ではなく 0 として見えるようにしました。地味な修正ですが、観測品質の面ではかなり大事な変更だったと思います。
また、Twelve Data の日次リクエスト制限についても、観測しながら一度混線しかけたので、この機会に切り分けておきました。9時のタイミングで UI 上のリクエスト回数がリセットされた一方、ダッシュボードは NoData になっていたため、最初は仕様的な再接続要否も疑いました。ただし、こちらも後から見直すと、原因はリセットではなくその前に probe が落ちていたことでした。結果として、Twelve Data の仕様に余計な意味を読み込まずに済んだのは良かったですし、こうした切り分けを先に済ませたことで、以後は「何が API 側の制約で、何が自前の観測機の問題なのか」をやや素直に見られるようになったと思います。
執行ベース粗判定そのものより先に、まず観測品質の土台を整えたということです。判定器を足すこと自体は派手ですが、その前に「落ちない」「0は0として見える」「API制約と自前の不具合を混同しない」という最低限の足場を作っておかないと、その後の観測結果まで歪んで見えてしまいます。今回は、その意味でかなり地味ですが重要な作業から先に片付けた日でした。
3. 3/5/8bps・滞留・コスト比較・戻りを最小構成で実装した

観測品質の穴を先に塞いだうえで、今回の本題である執行ベース粗判定を最小構成で実装しました。ここで意識したのは、最初から細かく作り込みすぎないことです。いま必要なのは「実際に取れそうかどうかを荒く見るための土俵」であって、完成された執行判定器ではありません。したがって、要素は増やしすぎず、あとから意味を確認しやすい形で、3/5/8bps・滞留・コスト比較・戻りという4つに絞って追加しました。
まず閾値については、abs(premium_bps) を使って 3bps / 5bps / 8bps の3段階で見るようにしました。今回の目的は、残差がプラス方向かマイナス方向かを精密に切り分けることではなく、そもそも執行ベースで意味を持ちうるサイズなのかを粗く観測することです。そのため、方向はひとまず捨てて絶対値で見ています。また、イベントの定義も「閾値を上回っている間ずっと数える」のではなく、「上抜けた瞬間を1イベント」としました。滞留時間を別で測る以上、イベントの発生と継続を同じカウンタに混ぜると、あとで読みづらくなるからです。
次に滞留時間については、「連続で閾値以上だった秒数」をそのまま計測するようにしました。短い欠損をどう扱うかといった話はあとで詰める余地がありますが、現段階ではそこにロジックを足すよりも、まずは機械的に連続継続だけを拾う方が素直です。今回の粗判定では、複雑な補完や平滑化よりも、まず単純な定義で見て、その結果を受けて必要なら後で調整する方針を取りました。
コスト比較については、Binance Japan 側のスプレッドに加えて、片道手数料 × 2 の roundtrip fee を足し合わせた値を total cost として扱っています。ここで重要なのは、この判定は Binance Japan 単市場前提であり、先行市場側での執行は前提にしていないことです。要するに、「BJ 側で観測されている premium の大きさが、少なくとも BJ のスプレッドと手数料を入口時点で跨いでいるか」を見ているにすぎません。現段階ではスリッページまでは反映していませんが、それは意図的です。実際の執行を伴わない時点で適当な推定値を混ぜると、観測が濁ると考えたからです。今はまず、スプレッドと手数料という明示できるコストだけを入れておく方がよいと判断しました。
戻りについては、暫定的に「abs(premium_bps) が 3bps 以下に戻るまで」を戻りと定義し、それを 60 秒以内に満たしたかどうかを見ています。この 3bps / 60 秒という値には、現時点では厳密なキャリブレーション根拠があるわけではありません。ただし、それは問題ではなく、今回の段階ではむしろ仮設定であることを明示したまま観測を始める方が重要だと思っています。ここで大事なのは、いきなり最適な reversion 定義を当てにいくことではなく、「どういう分布で戻るのか」を見られる状態に持っていくことです。
これらを追加したことで、ダッシュボード上では、abs premium と total cost の関係、各閾値での event / dwell / entry cost pass、そして戻り率と平均戻り時間が見えるようになりました。まだこれだけで白黒を出せるわけではありませんが、少なくとも「プレミアムがあるように見える」を、閾値・継続・コスト・戻りという別々の軸に分解して眺められるようになったのは大きいです。今回の実装でやったのは、勝ち筋を完成させたことではなく、勝ち筋らしきものが本当にそうなのかを確認するための粗い観測面を一段整えたことでした。
4. まだ白黒は出さない。いまは判定の母数をためる段階
執行ベース粗判定を実装したとはいえ、この時点で「取れる」「取れない」の白黒を出すつもりはありません。むしろ、今回はそこを早まらないこと自体が重要でした。新しく追加した指標は、どれもまだ観測を始めたばかりで、現時点の数値だけを見ても統計的に意味のある判断にはつながりません。実際、確認時点では各閾値の event_total はまだ 1 件ずつに留まっており、reversion も 0/1 レベルの挙動しか見えていませんでした。これでは、閾値設定が適切かどうかも、戻り方の定義が妥当かどうかも、まだ何も言えないのとほぼ同じです。
また、コスト比較についても、現時点で total cost が premium を上回っているからといって、それだけで「この線はダメだ」と切る段階ではありません。今回の実装では Binance Japan 側のスプレッドに roundtrip fee を加えた値を total cost としているため、入口時点で premium がそれを跨いでいないケースが多ければ、当然 cost pass は立ちにくくなります。ただし、それは今の設定と現状の観測値に対して自然な結果であって、即座に研究テーマ全体の否定を意味するわけではありません。ここで大事なのは、現実に合わせて指標が素直に反応しているかどうかであり、都合の良い結果が出ることではありません。
今回の段階で必要なのは、まず母数をためることです。最低でも24時間、できれば48〜72時間ほど回して、各閾値である程度イベントが積み上がるのを待つ必要があります。感覚的には、各レベルで event_total が 30 件前後は欲しいところです。それくらいないと、「3bps はノイズ寄りなのか」「8bps は件数が少ない代わりに質が違うのか」「戻りの定義は 60 秒で妥当なのか」といった話も、ほとんど雰囲気でしか語れません。今の自分に必要なのは、精密な解釈ではなく、まず観測対象に対して十分な母集団を確保することだと考えています。
ここで強調しておきたいのは、今回は判定器の導入がゴールではなく、判定器をまともに使えるだけの観測段階に入った、ということです。研究を進めていると、新しいパネルが見えるようになった時点で何かを言いたくなりますし、数字が動き始めるとそこに意味を読み込みたくもなります。しかし、いま必要なのはそうした解釈の加速ではなく、「まだ何も結論づけない」という姿勢を保つことです。今回の進捗は、勝ち筋の証明ではなく、勝ち筋の有無をあとで確認するための母数回収フェーズに入った、という理解がいちばん正確だと思っています。
5. 指標の誤読を防ぐ注記を入れて、観測の意味を固定した
今回の作業の中で、実装そのものと同じくらい重要だったのが、指標の意味を誤読しないための注記を入れたことでした。執行ベース粗判定の観測面が見えるようになると、どうしても人間はそこに都合の良い意味を読み込みたくなります。特に、自分で実装した指標は「これが立っているなら取れそうだ」と解釈したくなりやすいですし、研究を進めたい気持ちがあるほど、その傾向は強くなります。だからこそ今回は、数値を足すだけで終わらせず、それが何を意味していて、何を意味していないのかを先に固定しておくことを重視しました。
いちばん大きかったのは、cost pass 系の指標に対する注記です。今回の実装では、entry 時点で abs(premium) が total cost を上回っていた回数を数える指標を置いています。ただし、これはあくまで入口時点のコスト跨ぎを見ているだけであって、その後に本当に利益が出たかどうかを表しているわけではありません。にもかかわらず、名前だけを見ると「コストを跨いだイベント数」から「取れた回数」や「勝ち筋の数」のような読み方に滑っていく危険があります。実際、自分でもその方向に脳内変換してしまいそうな感触があったので、README と Grafana の両方に「entry-time only」であり「profitability ではない」ことを明記しました。
また、パネル側の表示も少し調整し、cost pass という曖昧な見え方から、entry cost pass という意味が狭く伝わる形に寄せました。これによって、「入口で BJ コストを跨いでいたか」と、「その後どれだけ滞留したか」と、「最終的にどう戻ったか」を、少なくとも見た目の上では別物として読みやすくなったと思います。今回の粗判定は、3/5/8bps の閾値、滞留、コスト比較、戻りを役割分担して観測するのが目的なので、それぞれの役割を名前の段階で曖昧にしないことは意外と大事でした。
こうした注記は、一見すると実装本体よりも脇役に見えるかもしれません。しかし、自分にとってはむしろかなり本質的な部分です。研究が進むほど、人は結果を見てから定義を読み替えたくなりますし、観測の意味づけもあとから都合よく調整したくなります。今回のように、README やダッシュボード上で先に意味を固定しておくことは、そうした自己合理化を防ぐためのガードでもあります。言い換えると、今回やったのは単なる説明文の追加ではなく、観測結果をあとから自分の都合で解釈し直さないための固定具を打ち込む作業でした。
今回はまだ白黒を出す段階ではありませんし、閾値や戻りの定義も仮設定です。ただ、それでも「この数字は何を意味するのか」を曖昧にしたまま観測を進めるよりはずっとましです。実装した指標の意味を狭く、正確に、誤読しにくくしておくことは、結局のところ研究全体の精度を守ることにつながります。今回の進捗は、判定器を作ったことだけでなく、その判定器を都合よく読まないための注記まで入れられたことに価値があったと感じています。
6. 次に見るものと、まだ触らないもの
ここまでで、残差を執行ベースで粗く見るための土俵はひとまず整いました。では次に何を見るのかというと、いきなり閾値や戻り条件をいじることではなく、まずはこの判定器をそのまま回して母数をためることです。現時点では、各閾値のイベント数もまだ少なく、戻り率や平均戻り時間もほとんど初期値に近い状態です。この段階で 3bps が良いのか 5bps が良いのか、あるいは reversion の 60 秒が長いのか短いのかを議論しても、まだ観測対象よりも自分の解釈の方が先に走ってしまいます。したがって、次にやるべきことは、最低でも24時間、できれば48〜72時間ほど継続観測し、各レベルでイベントの母数をためることだと考えています。
そのうえで見たいのは、各閾値ごとの event_total の増え方、滞留時間の分布、entry cost pass の比率、そして戻り率と平均戻り時間です。特に重要なのは、「プレミアムが発生すること」と「執行コストを跨ぐこと」と「戻ること」が、どの閾値帯でどう組み合わさっているかを見ることだと思っています。たとえば 3bps は件数が多くてもほぼ BJ コストを跨がないかもしれませんし、8bps は件数こそ少なくても滞留や戻りの質が違うかもしれません。今後は、そうした差を雑に期待で読むのではなく、実際の分布として見ていく段階に入ります。
一方で、まだ触らないものも明確です。まず、閾値そのものの最適化はまだやりません。3/5/8bps は現時点ではあくまで観測の切り口であり、最適解として置いた値ではありません。母数が十分にたまる前にここをいじり始めると、観測したいものではなく自分が見たいものに寄せていくことになります。戻りの定義についても同様で、3bps / 60 秒という値は仮置きです。ただし、仮置きだからといってすぐ触るのではなく、まずはこの仮定でどんな分布が見えるかを確認してから調整する方針です。
また、今回の粗判定にはスリッページをまだ入れていませんが、この点も今はあえて触らないことにします。理由は単純で、執行を伴っていない時点でスリッページを適当に推定して入れても、観測が濁るだけだからです。推定値を使うこと自体は否定しませんが、それをやるなら「これは推定値であり、実測ではない」と明示したうえで別段階として扱うべきです。少なくとも今は、BJ スプレッドと手数料という事実として置けるコストだけで見た方が、研究の輪郭は保ちやすいと考えています。
さらに、方向性の分離もまだ後です。今回は abs(premium_bps) を使って絶対値で粗く見ていますが、これは方向を捨てた方が現段階の目的に合っているからです。もし今後、執行ベースでも意味がありそうな構造が見えてきたら、そのとき初めてプラスとマイナスを分けたり、より細かな判定条件を足したりすれば十分です。今の段階でそこまで広げてしまうと、判定器の観測面を整えるという本来の目的から外れてしまいます。
要するに、次にやることは「観測してためること」であり、まだやらないことは「最適化して意味を盛ること」です。今回の実装でようやく、残差を執行ベースで粗く観測するための枠組みができました。だから次は、それを動かして母数を集め、その上で初めて閾値や戻り条件の調整に入るのが自然な順番だと思っています。今は判定器を完成させる段階ではなく、判定器を信用できるだけの観測結果を集める段階です。その順番を崩さないことが、今回の研究ではいちばん大事だと感じています。