Bot CEX 開発ログ

🛠️開発記録#488(2026/3/18)multi_market_probe開発ログ ― 歪み回帰をどこまで短期構造として扱うかを、観測機で切り分け始めた話

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

前回は、歪み回帰の白黒判定だけを返す最小構成の J-Reversion を作り、「今この条件で構造があるのかないのか」を低コストで読める形まで削りました。
今回はその判定器を賢くするのではなく、同じ判定条件のまま時間幅だけを動かして比較できるようにすることを主眼にしています。
30秒基準を残したまま 60 / 90 / 120 秒の比較系を追加し、ダッシュボード上でも基準系と比較系の責務を分け直しました。これにより、歪み回帰をどこまで短期構造として扱うのが妥当かを、観測機ベースで切り分け始められる状態になりました。

前回の話
🛠️開発記録#487(2026/3/17)multi_market_probe開発ログ ― 観測機の機能を極限まで絞って、歪み回帰の白黒判定器を作った話

続きを見る

1. 今回のゴール:J-Reversionを時間幅比較できる形へ広げる

今回のゴールは、J-Reversion をより賢い判定器にすることではありませんでした。前回の時点で、J-Reversion は bf_fx × binance_perp を対象に、threshold_bps=10、horizon_main_sec=30 を軸にした最小構成の白黒判定器としていったん立っています。しかも YES/NO の閾値や relation / quality の下限もかなり明示的に置かれていて、yes_hit_rate_pct=55、min_samples_main=80、relation_min_abs_corr=0.15 という形で、「この土俵で立つなら YES、立たないなら NO」と返す設計です。だから今回やりたかったのは、その土俵をいきなり作り替えることではなく、まずは同じ歪み定義・同じ判定条件のまま、観測時間幅だけを比較できるようにすることでした。

この順番にした理由は単純です。今の段階で threshold まで同時に動かすと、「YES/NO が変わった理由」が一気に分からなくなるからです。J-Reversion の判定ロジック自体は _JReversionStructureTracker にまとまっていて、additional_pairs を読めば同じ構造判定器を別 horizon で複数立てられる形になっています。つまり、まずはロジックを増やすのではなく、既存の判定器を 30 秒基準のまま 60 / 90 / 120 秒へ横に並べることができる状態にある、ということでした。今回の実装は、その既存構造をそのまま使って、比較軸を一つ増やす方向に寄せています。

設定側でも、その意図はかなり明確です。j_reversion_eval の本体は 10bps / 30s / 60s を持ったまま残しつつ、additional_pairs として 60 秒、90 秒、120 秒の main horizon を追加しています。しかも threshold_bps は全部 10 のままで、変えているのは horizon_main_sec とそれに対応する horizon_slow_sec だけです。これはつまり、今回の比較が「別の歪み定義を試す」ためではなく、同じ 10bps 級の歪み回帰を、どこまで短期構造として扱えるのかを切り分けるためのものだと言えます。

ダッシュボード側も、その方針に合わせて整理しました。今回の J-Reversion セクションには、h30 固定の基準パネルとして [J-Reversion Minimal] Verdict by Direction (h30, NO=0/YES=2) を置き、その上で比較用に [J-Reversion Minimal] Verdict by Direction (Multi Main Horizons) を別に用意しています。しかも後者は h60 / h90 / h120 を並べる構成にしてあり、h30 は基準系へ切り出しました。つまり今回は、「30 秒の白黒判定」を残しつつ、「60 / 90 / 120 秒ではどう見えるか」を比較するための読み順を先に固定したわけです。さらに時系列確認用として、Selected Main Horizon と Multi Main Horizons の2種類の Timeline パネルも追加していて、単発の Verdict だけでなく、状態変化の継続性まで追える形に寄せています。

ここで重要なのは、今回のゴールが「J-Reversion を完成させること」ではなかった、という点です。むしろ今回やりたかったのは、J-Reversion をどこまで“短期の歪み回帰判定器”として扱ってよいのかを、観測機の側から切り分け始めることでした。30 秒でしか立たないのか、60 秒でも追随するのか、120 秒まで伸ばしてもなお同じ構造と呼べるのか。この問いに入るためには、まず時間幅だけを比較できる器が必要でした。今回の実装は、そのための最初の足場です。つまり、前回が「白黒判定器を作った回」だとすれば、今回は「その白黒判定器を、時間幅という一軸だけ動かして読める状態にした回」だったと思っています。

2. まず確認したこと:今のJ-Reversionは何を「歪み回帰」と呼んでいるのか

今回、時間幅を比較できるようにする前に、先にやったのは「そもそも今の J-Reversion は何を歪みと呼び、何を回帰と呼んでいるのか」を実装ベースで確認することでした。ここが曖昧なまま 60 / 90 / 120 秒へ広げても、あとで「何を比較していたのか」が分からなくなるからです。設定を見ると、J-Reversion はあくまで 構造判定器 として置かれていて、対象は base_market: bf_fxref_market: binance_perp に固定、しきい値は threshold_bps: 10、主判定窓は horizon_main_sec: 30 です。さらに relation 側には corr_window_sec: 60corr_min_points: 20relation_min_abs_corr: 0.15、判定側には min_samples_main: 80min_distortion_events_total: 10yes_hit_rate_pct: 55 が入っていて、最初からかなり限定的な土俵で動くようになっています。

まず「歪み」の定義ですが、今の J-Reversion が見ているのは microprice や板の局所力学そのものではありません。サービス側では、入力サンプルから premium_exec_best_bpspremium_exec_signed_bps を取り出し、abs(premium_exec_best_bps) >= self.threshold_bps を満たしたときだけアンカーを追加します。つまり歪み発生は、「bf_fx と binance_perp のあいだで、実行可能ベースの相対プレミアムが 10bps 以上に広がった状態」として定義しています。しかも signed 側の符号で long / short を分けていて、signed<0 を long、signed>0 を short として方向を持たせています。ここで見ているのは、2市場の相対プレミアム構造であって、単一市場内の板の歪みではありません。

次に「回帰」の定義ですが、ここもかなり限定的です。今の Forward 側は、アンカー時点と horizon 到達時点を一点比較しているのではなく、_append_min_abs_sample() で窓の中の最小 absolute 値を追い、_resolve_future()min_abs_seen < abs(anchor_premium) なら hit とみなす作りになっています。つまり、「30秒後にちょうど戻っていたか」ではなく、30秒以内のどこかで一度でも絶対値が縮小したかで回帰を見ています。direction 別の _resolve_future_directional() でも同じ考え方が使っていて、signed premium の絶対値がアンカー時より小さくなった回数を、long / short 別に hit として積み上げています。今回の J-Reversion が返しているのは、「ゼロへ完全に戻ったか」でも「最後まで維持したか」でもなく、「一定時間内に一度でも縮んだか」というかなり素直な回帰定義となっています。

そのうえで、J-Reversion の YES は「今すぐこの方向で発注すべき」という意味ではありません。Exporter を見ると、J-Reversion は state_code (NO=0,HOLD=1,YES=2)samples_30shit_rate_30s_pct などのメトリクスとして出されていますが、そこで保持しているのは執行判断ではなく、direction 別の構造ラベルです。サービス側の判定でも、quality が悪ければ NO、ready が足りなければ NO、relation が弱ければ NO、samples が足りなければ NO、distortion events が足りなければ NO と落としていき、そのうえで hit_rate >= yes_hit_rate_pct と directional edge を通ったときだけ YES を返します。つまり YES の正体は、「その方向の歪みアンカーが発生したとき、一定時間内に縮小しやすい構造が、最低限の relation / quality / samples を満たしたうえで確認できている」という意味です。

この整理を入れたことで、今回ようやく違和感の正体もはっきりしました。long と short が同時に YES になりうるのはおかしいのではなく、そもそも J-Reversion が「現在の発注方向」を返しているのではなく、「方向別の条件付き回帰構造」を返しているからです。だから今の J-Reversion を読むときは、「どちらに賭けるか」ではなく、「どの方向の歪みが、どの horizon で縮みやすいと判定されているか」を見る必要があります。今回の章でまず確認したかったのは、まさにこの点でした。J-Reversion は、名前だけ見ると歪みそのものを判定しているように見えますが、実装上は 実行可能ベースの相対プレミアムが一定以上広がったあとに、それが一定時間内で縮小しやすいかどうかを、方向別に見る構造判定器 です。この前提を固定して初めて、「では 30 秒と 60 / 90 / 120 秒で見えるものは本当に同じ種類の現象なのか」という次の問いに進めるようになりました。

3. 実装変更①:30秒基準を残したまま、60/90/120秒の比較系を追加した

今回の実装変更で最初にやったのは、J-Reversion の判定ロジックそのものを作り替えることではなく、同じ構造判定器を別の main horizon で並列に立てられるようにすることでした。もともとの設定では j_reversion_eval の本体が threshold_bps: 10horizon_short_sec: 10horizon_main_sec: 30horizon_slow_sec: 60 を持つ最小構成として置かれていました。今回もこの 30 秒基準は残したままで、追加分として 60 / 90 / 120 秒の組を additional_pairs に足しています。しかも全部 threshold_bps: 10 のままで、歪みの定義そのものは変えていません。変えているのは main horizon と slow horizon の長さだけです。だから今回の比較は、「別ロジックを試した」ではなく、同じ 10bps 級の歪み回帰判定を、時間幅だけ変えて並べたという性格のものです。

サービス側も、この意図にかなり素直に沿っています。multi_market_probe_service.py では additional_pairs を読んで、追加条件ごとに _JReversionStructureTracker を生成する形になっています。ここでは threshold_bpshorizon_short_sechorizon_main_sechorizon_slow_sec を raw 側から受け取りつつ、relation や samples の条件は既存設定をそのまま継承する構成です。要するに、J-Reversion 自体は一個の賢い判定器として肥大化させず、同じ判定器を複数条件で複製して走らせる方向を採っています。この形にしておくと、「判定ロジックが変わったから結果が変わった」のか、「main horizon を動かしたから変わった」のかを分離しやすくなります。今回のフェーズでは、ここがかなり重要でした。

Prometheus exporter 側でも、この変更に合わせてラベル設計を拡張しています。_MMARB_J_REVERSION_LABELS("base_market", "ref_market", "threshold_bps", "horizon_main_sec", "direction") という形になっていて、update_multi_market_j_reversion_state() でも threshold_bpshorizon_main_sec を label として持たせています。つまり J-Reversion の state_codereason_codeready_flagquality_flagsamples_30shit_rate_30s_pct は、単に bf_fx × binance_perp の direction 別だけではなく、どの threshold・どの main horizon の判定かまで区別した状態で保存されます。これがないと 30 秒と 60 秒の判定が同じ系列に上書きされてしまいますが、今回はその事故を避けたうえで、比較に必要な粒度でメトリクスが残るようになりました。

ダッシュボード側も、この exporter のラベル構造に合わせて比較系を追加しています。たとえば [J-Reversion Minimal] Verdict by Direction (Multi Main Horizons) は、obx_mmarb_j_reversion_state_code{...,horizon_main_sec=~"$jrev_main_horizons",direction="long|short"} を引いていて、同一 threshold のまま main horizon ごとの long / short 判定を並列表示する構成です。さらに [J-Reversion Minimal] Verdict Timeline (Multi Main Horizons) では、同じ state_code を時系列で重ねて表示し、h60 / h90 / h120 の状態推移を一枚で追えるようにしています。つまり今回は、単発の Stat パネルだけでなく、時間幅比較をそのまま時系列で観測できる器までまとめて作ったわけです。

この変更で大きかったのは、J-Reversion の white/black 判定を「一点の verdict」から「比較可能な系列」へ進められたことでした。前回までは、30 秒基準の J-Reversion が YES か NO かを見るところまではできていましたが、それだけでは「30 秒だから見えているのか」「60 秒以上まで伸ばしても同じ構造なのか」が分かりません。今回、同じ threshold で 60 / 90 / 120 秒を横に並べたことで、少なくとも今後は「どの時間幅までを歪み回帰と呼んでよいのか」を、コードもダッシュボードも同じ前提で比較できるようになりました。つまり今回の実装変更①は、新しい判定理屈を追加したというより、J-Reversion を“時間幅の研究ができる装置”へ一段進めた変更だったと思っています。

4. 実装変更②:h30を基準パネルに固定し、比較系との責務を分けた

60 / 90 / 120 秒の比較系を追加したあと、すぐに気になったのが h30 の扱い でした。もともと前回までの J-Reversion は、30 秒主判定を返す最小構成の白黒判定器として読んでいました。そこに今回、Multi Main Horizons の比較パネルをそのまま足すと、h30 が 「基準の単発判定」「比較対象のひとつ」 の両方に出てくることになります。実装上は間違っていなくても、読む側からすると「左の h30 と上の h30 は何が違うのか」が分かりにくい。つまり、時間幅比較を入れたことで、ロジックの問題というより 表示責務の重なり が見えるようになりました。

そこで今回やったのは、30 秒を比較群の一員として雑に並べるのではなく、基準系として単独で固定する ことでした。ダッシュボード変数を見ると、jrev_main_focus"30","60","90","120" を選べるまま残しつつ、比較側の jrev_main_horizons"60","90","120" に切り出しています。つまり、「Selected Main Horizon として一つを見る系」と、「複数 horizon を比較する系」で、そもそも使う変数の責務を分けたわけです。しかも比較系から h30 を外したことで、30 秒は基準、60 / 90 / 120 秒は拡張比較 という読み方が自然に固定されるようになりました。

パネル名も、その意図に合わせてかなり明示的に変えています。基準側は [J-Reversion Minimal] Verdict by Direction (h30, NO=0/YES=2) として、30 秒主判定であることをタイトルに入れました。一方、比較側は [J-Reversion Minimal] Verdict by Direction (Multi Main Horizons) のままにして、ここでは h60 / h90 / h120 だけを見る構成にしています。これで、「左はこの観測機の基準判定」「右はその基準に対する時間幅比較」という役割分担がはっきりしました。実際、前者のクエリは horizon_main_sec="30" へ固定され、後者は horizon_main_sec=~"$jrev_main_horizons" を引く形になっています。コード上でも、単発の基準系と複数系列の比較系が明確に分かれました。

この整理は、時系列パネル側でも同じです。[J-Reversion Minimal] Verdict Timeline (Selected Main Horizon)jrev_main_focus を引き、単一条件の long / short の state_code 推移を追うためのものです。対して [J-Reversion Minimal] Verdict Timeline (Multi Main Horizons)jrev_main_horizons を使って、h60 / h90 / h120 の long / short をまとめて重ねる構成です。つまり「今選んでいる一条件の挙動を見るパネル」と、「基準以外の複数 horizon がどう動くかを見るパネル」とで、ここでも役割をきれいに分けました。前回までの J 系統記事でも何度か書いてきましたが、観測機は情報量を増やすより先に、どの順番で読むかを固定する ことが重要です。今回の h30 切り出しは、まさにそのための変更でした。

この変更で良かったのは、ダッシュボードを見た瞬間に読む順番がかなり自然になったことです。まず左の h30 基準パネルで、「今の最小 J-Reversion は立っているのか」を確認する。そのうえで、reason や gate を見て、relation なのか sample なのか quality なのかを切る。そこまで分かったら、右や下の比較系で h60 / h90 / h120 がどう追随するかを見る。この流れにしておくと、「h30 だけ立っているのか」「60 以上でも立つのか」「そもそも全部 NO なのか」が、かなり低コストで読めるようになります。もし h30 まで比較群に残したままだと、毎回「どの h30 を基準として見るのか」を頭の中で補正しなければならず、せっかく作った比較系が読みにくくなっていたと思います。

要するに、今回の実装変更②は、ロジックを足した話ではありません。h30 を“比較対象のひとつ”ではなく、“この研究の基準座標”として固定したという整理です。J-Reversion を 30 秒基準の白黒判定器として残しつつ、そこから 60 / 90 / 120 秒へどこまで構造が延びるのかを見る。その役割をダッシュボード上でもはっきり分けたことで、ようやく「時間幅比較を研究するための観測機」として読める形に近づいたと思っています。

5. なぜ120秒を上限候補にしたのか:歪み回帰とLead-Lagの境界を考えた

今回、時間幅の比較系を追加していて、途中からいちばん気になり始めたのは「J-Reversion をどこまで伸ばしてよいのか」でした。30 秒基準を残したまま 60 / 90 / 120 秒まで広げること自体は、比較のためには自然です。ただ、その先も同じ調子で 180 秒、300 秒と伸ばしていくと、それは本当にまだ「歪み回帰」と呼んでよいのか、という疑問がどうしても出てきます。ここで違和感があったのは、単に長い時間幅が嫌だったからではありません。今の J-Reversion が見ているものが、あくまで 実行可能ベースの相対プレミアムが一定以上ズレたあと、それが一定時間内に縮小しやすいか という短期構造だからです。もしそのズレがかなり長い時間残るなら、それはもう短期の回帰というより、別の市場力学が混ざっている可能性の方が高いのではないか、と感じました。

この違和感は、実装の定義を確認するとよりはっきりします。今の J-Reversion では、歪み発生は abs(premium_exec_best_bps) >= threshold_bps、つまり 10bps 以上の実行可能プレミアム乖離です。回帰 hit も、_resolve_future_directional() の中で min_abs_seen < abs(anchor_signed_bps) を満たせばよく、「窓の中で一度でも縮小したか」を見ています。これはかなり短期の収束現象を意識した定義です。言い換えると、今の J-Reversion が追いたいのは「市場間の相対ズレが、比較的すぐ解消されるか」であって、「数分単位でゆっくり別市場へ伝播していくか」ではありません。だから horizon を無制限に伸ばすと、定義の中心にある“短期収束型”という性格そのものがぼやけてしまいます。

さらに、J-Reversion の relation 側が見ているのは corr_window_sec: 60 の対数リターン相関で、relation_min_abs_corr: 0.15 を超えているかどうかです。つまりこの系統は、まず「2市場に最低限の連動がある」ことを前提に、その上で相対プレミアムのズレが縮むかを見る構造になっています。ここで数分単位まで伸ばした現象を同じ箱に入れると、相関で見ている短期の連動性と、実際に起きているゆっくりした価格伝播やレジーム変化が混ざりやすくなります。そうなると、J-Reversion が返す YES は「短期の歪み回帰」なのか、「少し遅れて他市場がついてくる Lead-Lag」なのかが分かりにくくなる。今回 120 秒を上限候補にしたのは、この責務の混線を避けたかったからです。

もちろん、120 秒という数字そのものに絶対的な意味があるわけではありません。これはまだ研究上の仮置きです。ただ、30 / 60 / 90 / 120 秒くらいまでなら、まだ「短期の歪みがどこまで縮むか」を同じ文脈で比較しやすい。一方で、300 秒まで行くと、感覚的にもかなり長いですし、その間に別のプレイヤーのフローや市場全体の方向性が入りやすい。すると、それを見て「歪み回帰がある」と言ってしまうのは、かなり危うくなります。だから今回の時点では、J-Reversion は 120 秒までを本線にし、それを超える現象は“別構造の可能性が高い”とみなす くらいの方が、観測機の責務としては自然だと思いました。

その意味で、今回置いた 120 秒上限候補は、最適値の主張というより 研究を切るための境界線 に近いです。もし 30 / 60 / 90 / 120 秒まで見ても一貫して構造が立たないなら、「少なくとも短期収束型の歪み回帰としては弱い」とかなり言いやすくなります。逆に、120 秒を超えた先でしか構造が見えないなら、それは J-Reversion の成功ではなく、Lead-Lag か別の J 系統が担当すべき現象かもしれません。今回、時間幅比較を入れたことで見えてきたのは、単に「30 秒が短いか長いか」ではなく、歪み回帰という箱そのものを、どこまでの時間軸で使うべきか という問題でした。120 秒を上限候補にしたのは、その箱を広げすぎないための判断だったと思っています。

6. スクショで見る現在地:今見えていることと、まだ見えていないこと

今回のダッシュボード整理でいちばん良かったのは、YES が出たことではなく、今どこで落ちているのかを低コストで読めるようになったことでした。基準系として切り出した [J-Reversion Minimal] Verdict by Direction (h30, NO=0/YES=2) は、30秒主判定を固定で見るためのパネルです。一方で比較系は、h60 / h90 / h120 を並べて見る役割に分けています。つまり今のダッシュボードは、「まず h30 を見る」「次に比較群を見る」という読解順がはっきりしていて、前回までのように同じ h30 を複数の意味で読み分ける必要がなくなりました。これは派手な変更ではありませんが、観測機としてはかなり大きいです。

実際のスクショでも、その読み方はかなり素直に機能しています。h30 の基準パネルでは long / short ともに NO、比較側の h60 / h90 / h120 も同様に NO です。ここで重要なのは、「全部赤いからダメだった」という話ではなく、少なくとも現時点では、短い horizon だけ特別に立っているわけではないことが一目で分かる点です。もし h30 だけが立って比較群が追随しないなら、「かなり短期に閉じた構造かもしれない」という読みになりますし、逆に比較群だけ立つなら「それはもう短期回帰ではなく別構造ではないか」という疑いが強まります。今の状態はそのどちらでもなく、基準系も比較系も一貫して NO です。だからこそ、いまは「構造がない」のではなく、「まだその土俵で立っていない」と冷静に読めます。

さらに、Final Verdict OR + Reason を見ると、今回の NO がどこで落ちているのかまで切れます。J-Reversion の reason code は exporter 側で NO_NOT_READYNO_LOW_SAMPLENO_QUALITY_ISSUENO_NO_RELATIONNO_NO_DISTORTIONNO_NO_REVERSION_30SNO_NO_DIRECTIONAL_EDGE などに整理されていて、ただ NO を返すだけでなく、「何が足りないから NO なのか」をそのまま表示できるようになっています。今回のスクショでは NO_NO_RELATION が見えていて、つまり今の時点では quality や ready 以前に、そもそも relation 条件を通るだけの市場連動が立っていないと読めます。これはかなり大きいです。前回までのように「何となく構造が弱いのかもしれない」と曖昧に考えるのではなく、最低限どこで落ちているのかを観測機側が返してくれるからです。

この読みは設定とも一致しています。いまの J-Reversion は relation_min_abs_corr: 0.15corr_min_points: 20min_samples_main: 80yes_hit_rate_pct: 55 というかなり明示的な下限を持っていて、しかも 60 / 90 / 120 の追加比較系も同じ threshold=10bps のまま horizon だけを変えています。つまり今の NO は、「別ロジックではダメだった」というより、10bps級の歪みを起点にした短期回帰構造が、この relation 条件の下ではまだ立っていないという意味です。この整理が入ったことで、少なくとも「何を変えれば NO の意味が変わるか」がかなりはっきりしました。今後動かすべき軸は、時間幅なのか、閾値なのか、relation の土台なのか、という話にかなり素直に入れます。

一方で、まだ見えていないことも多いです。まず大きいのは、120秒までを J-Reversion の本線とみなす仮説が、実データでどこまで妥当か です。今回の追加比較系は 60 / 90 / 120 までで切っていて、300 秒までは本線に入れていません。これは設計上かなり意図的ですが、だからといって 120 秒が正しいと確定したわけではありません。今はまだ、「歪み回帰は短期収束型として扱いたい」「それを超えるなら Lead-Lag か別構造を疑いたい」という研究方針を置いた段階であって、その仮説がどのくらい市場の事実と噛み合うかは、これから Timeline や verdict の持続性で見ていく必要があります。

もう一つまだ見えていないのは、今の NO が本当に「構造なし」に近い NO なのか、それとも「relation の置き方がまだ雑なだけ」なのか という点です。いまの relation は 60 秒窓の対数リターン相関で切っていて、これは最小構成としてはかなり分かりやすいです。ただ、相関が弱いからといって、即座に歪み回帰構造が存在しないとまでは言えません。もっと短い relation 窓の方が良いのかもしれないし、そもそも相関以外の連動性指標の方が適しているかもしれない。つまり今見えているのは、「この relation 定義のもとでは NO が返っている」ということまでであって、「歪み回帰という現象そのものが無い」と断定する段階ではまだありません。

さらに、スクショだけではまだ持続性が見えません。今回追加した Timeline パネルの価値は、単発の Verdict だけではなく、いつ YES / NO が切り替わり、それがどの程度続いたか を確認できる点にあります。今は稼働時間がまだ短く、系列の変化も薄いので、「h30 は立つが h120 は追随しない」のか、「全部ほぼ同時に立つ / 落ちる」のかまではまだ判断できません。ここは今後しばらく放置して、Selected Main Horizon と Multi Main Horizons の両方で state_code の変化を見る必要があります。今回のスクショで見えているのは、あくまで“今この瞬間の断面”までです。時系列の持続性が見えて初めて、「短期回帰としてどこまで自然か」を少しずつ言えるようになると思っています。

要するに、今回のスクショから言えることはかなり整理されています。見えているのは、基準系と比較系を同じ前提で読める形になったこと、そして現時点ではどの horizon でもまだ構造ありとは言えないことです。 一方で、まだ見えていないのは、その NO がどこまで構造の弱さを表していて、どこからが relation 定義や horizon 設計の問題なのかという部分です。だから今やるべきことは、NO を見て結論を急ぐことではなく、この観測機をそのまま回しながら、h30 / h60 / h90 / h120 がどう動くかを事実ベースで積み上げていくことだと思っています。

7. 次に試すこと:J-Reversionは120秒までを本線にして進める

今回の整理で、少なくとも次の方針はかなり明確になりました。J-Reversion は、これ以上なんとなく horizon を伸ばしていくのではなく、30 / 60 / 90 / 120 秒までを本線として扱います。つまり今後の研究対象は、「10bps 級の実行可能プレミアム乖離が、このレンジの中で短期収束型の構造として立つのかどうか」です。今回の config.yaml でも、J-Reversion の比較系は additional_pairs に 60 / 90 / 120 秒までを置く構成へ整理してあり、少なくとも現時点では 300 秒のような長い窓を本線には入れていません。これは単なる暫定設定というより、今回考えた「歪み回帰と別力学の境界」を、そのまま研究上の運用ルールへ落とした形です。

そのうえで、次に試すこともかなり絞れます。まず優先したいのは、いま追加した h30 / h60 / h90 / h120 の比較系をしばらく回し、Timeline を含めて state_code の変化を観測することです。今回はダッシュボード上で基準系と比較系の責務を分け、Selected Main Horizon と Multi Main Horizons の両方の時系列パネルも追加しました。だから次のフェーズでは、単発の Verdict だけでなく、「いつ YES が立つのか」「どの horizon が先に立つのか」「その YES がどれくらい持続するのか」を見ることができます。まずはこの器をそのまま回して、短期構造として立つ horizon が本当に存在するのかを事実ベースで確認したいです。

その次に動かす軸も、今回の時点である程度決まりました。前回までと同じで、一度に複数の軸は動かしません。 まずは時間幅だけを見る。そのうえで、もし 30 / 60 / 90 / 120 のどれでも一貫して構造が立たないなら、次に触るべきは threshold です。いまの J-Reversion は threshold_bps: 10 に固定されていて、これは「最適値」ではなく「まず一つ土俵を置くための基準値」です。だから時間幅比較を一通り見たあとで初めて、10bps の帯が妥当なのか、15 / 20 / 30bps の方が構造が見えやすいのかを動かす段階に進むと思っています。ただしそのときも、時間幅まで同時に変えてしまうと何が効いたのか分からなくなるので、順番は崩さないつもりです。

一方で、今回かなりはっきりしたのは、120 秒を超えた世界を J-Reversion の本線としては追わない という方針です。もし 120 秒以内で一貫して構造が立たず、180 秒や 300 秒でしか何かが見えないなら、それは J-Reversion の成功ではなく、Lead-Lag か別の J 系統が担当すべき現象だと考えます。今回、歪み回帰を「短期収束型の構造」として扱いたいという前提をかなり意識して整理したので、ここを曖昧にすると、せっかく切った責務境界がまた崩れてしまいます。だから今後は、J-Reversion の研究を続けるとしても、「どこまで短期構造として成立するのか」を 120 秒以内で見切ることを優先します。J-Reversion の現在の定義では捕まえにくいことであれば、別構造として扱って探索を切るって感じですね。

要するに、次にやることは「J-Reversion をさらに賢くする」ことではありません。まずは今回作った比較系をそのまま動かし、h30 / h60 / h90 / h120 のどこで構造が立つのか、あるいはどこまで見ても立たないのかを観測すること。その結果、120 秒以内で白黒が付かなければ、J-Reversion を深追いするのではなく、Lead-Lag や別戦略へ素直にシフトすること。今回ようやく、「歪み回帰をどこまで短期構造として扱うのか」という問いを観測機の形に落とし込めたので、次のフェーズではこのルールに沿って、探索を切る判断まで含めて進めていこうと思っています。

今回やったことは、J-Reversion を賢くすることではなく、時間幅の研究ができる観測機として整えることでした。
30秒を基準として固定し、60 / 90 / 120 秒を比較系として切り出したことで、少なくとも「どこまでを短期の歪み回帰として扱うか」を同じ前提で読めるようになりました。
今後はまずこの比較系を回し、120秒以内で構造が立つのかを確認します。もし立たないなら、J-Reversion を無理に延命せず、Lead-Lag か別系統へ切り分ける。今回の整理で、その判断を観測機ベースで行うための土台ができたと思っています。

-Bot, CEX, 開発ログ