Bot CEX 開発ログ

🛠️開発記録#609(2026/11/11)市場が見えないのか、そもそも見ていないのか――bitFlyerの観測と判定の実例からまとめる

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

今日は、bitFlyerの現物・CFD市場を対象に、データ取得環境の調査、PAPER戦略の継続観測、内部システムの監査を進めました。

ここ数日は、過去の約定履歴から価格差や価格変動を調べ、実際の市場でその傾向が再現されるかを検証しています。

今回も、その研究を継続しています。

ただし、今日の中心となったのは、新しい売買条件の発見や収益性の改善ではありません。

bitFlyerから実際にどのような情報を取得できるのか。そして、取得した情報のうち、自作システムは何を保存し、何を計算や売買判断に利用しているのか。

この2つを改めて調べることにしました。

その過程で、APIの取得範囲、データ保存の仕様、通信状態と内部判定の関係など、これまで十分に区別できていなかった部分が見つかりました。

今回は、実際の取得試験とPAPER観測、コード監査から確認できた事実を中心に、研究上の理解がどのように変わったのかを整理します。

1.価格差の研究と並行して観測範囲を調べ直した

以前の開発記録#605「CEXの内側を測り、外側の使い道を考える」では、bitFlyerの現物市場とCFD市場について、価格や出来高などの関係を調べました。

その後も分析を進め、現在は約37.85日分の約定履歴を使って、両市場の価格差や変動の性質を検証しています。

このデータから抽出した条件をもとに、現在は複数のPAPER戦略を並行して観測しています。

PAPERとは、実際に注文を出さず、公開された板の価格や数量を利用して仮想的な売買を記録する方式です。

現在は7条件を独立した仮想口座として扱い、それぞれの売買判断や損益を比較しています。

ただし、7条件は同じ市場を対象としているため、独立した7つの市場標本ではありません。また、それぞれの損益を合算して、一つの実行可能な戦略とみなすこともできません。

先に実施した観測は、約8時間31分で自動停止しました。

原因を調べると、板のWebSocket接続が単純に途切れたわけではなく、HTTPによる市場状態の取得失敗や、内部の利用可能性判定が停止条件へ波及していました。

そこで、HTTP取得の独立化、期限設定、再試行処理などを修正しました。

そのうえで、11月11日08時34分から、同じ売買条件による24時間のPAPER観測を開始しています。

本記事の執筆時点では、このRunは継続中です。

一方、今日はその結果を待つだけでなく、bitFlyerで取得できる市場情報そのものについても調べ直しました。

現在の戦略に問題が生じたため、慌てて新しい条件を探しているわけではありません。

今後の研究でどのような問いを立てられるのか、その判断材料となる情報の範囲を把握することが目的です。

2.OIと板厚の調査から観測可能な情報の境界が明確になった

最初に確認したのは、未決済建玉(Open Interest:OI)です。

私はこれまで、perp市場を調べる際に、OIを市場内に蓄積されたポジションの大きさを示す情報として扱ってきました。

板厚や約定フローと同様に、市場状態を把握するための重要な観測対象という位置づけです。

ただし、改めて整理すると、それぞれが示す情報は異なります。

情報主に観測する対象
OI約定済みで、まだ解消されていない建玉
板厚価格水準ごとに提示されている未約定注文
約定フロー実際に成立した売買の数量や方向
価格・価格差取引価格と、その変動

OIが増えたからといって、必ずしも買い圧力が強まったとは言えません。また、板厚が大きいことと、建玉が多いことも同義ではありません。

それぞれ異なる市場の状態を表す情報です。

bitFlyerでは市場全体のOIを取得できる公開APIを確認できなかった

bitFlyerの公式API仕様を確認すると、自分の口座の建玉を取得するPrivate APIは用意されています。

しかし、市場全体の未決済建玉を取得するPublic APIは、今回確認した範囲では見つかりませんでした。

また、保存済みの約定データから正確なOIを復元することもできません。

約定数量やBUY・SELLの方向が分かっても、それが新規建玉の成立なのか、既存建玉の決済なのかを識別できないためです。

一方、出来高や売買方向の偏りは、保存済みの約定データから算出できます。

実際に、終了済みの約8時間31分のRunについて、全158シグナルの判断時点を基準に、直前1分・5分・15分の約定フローを集計しました。

現物・CFDそれぞれについて、約定数量、BUY・SELL別数量、方向の偏り、直前の同じ長さの区間に対する出来高倍率などを求めています。

ただし、これらはあくまで約定活動を表す指標です。

建玉の増減や、新しい資金の流入を直接示すものではありません。

CFDと一般的なperpの違いも再確認した

今回、bitFlyer Crypto CFDの商品構造についても公式資料を確認しました。

Crypto CFDは証拠金を用いたロング・ショート取引が可能で、Funding制度もあります。

その一方、一般的な無期限先物とは異なり、bitFlyerが取引の相手方となる満期繰延型の店頭デリバティブです。

詳細な商品仕様については、bitFlyerの公式説明に譲ります。

重要なのは、これまで研究してきたperp市場の観測方法を、そのまま当てはめられるとは限らないことです。

ただし、これはbitFlyer CFDの研究が難しいという結論ではありません。

今回分かったのは、取得できる情報と、その意味が異なるということです。

この区別は、今日の研究の出発点になりました。

3.追加取得試験で既存の保存設定がAPIの上限ではないと分かった

次に調べたのは、板データの取得範囲です。

これまでのPAPER観測では、現物・CFDそれぞれについて、売り板・買い板の上位25段を約1秒間隔で保存していました。

このデータを使えば、最良気配付近の注文数量や、買い板と売り板の数量の偏りを分析できます。

実際、終了済みRunの保存データから、板厚や一定価格範囲内の注文数量の推移を集計しました。

ただし、保存している25段より外側の情報や、観測間隔の間に生じた変化までは分かりません。

そこで、既存の保存仕様とは別に、公開APIからどこまで取得できるのかを調べました。

HTTP板とWebSocketの取得範囲を実測した

短時間の取得試験では、HTTP板とWebSocketのsnapshot・差分更新を比較しました。

その結果、HTTP板では、現物・CFDともに上位25段を大きく超える価格水準の注文数量を取得できました。

WebSocketでも、今回の試験では売買各300段のsnapshotを観測しています。

ただし、これらはその時点で実際に取得できた数量です。

常に同じ段数が提供されることや、取得した板が市場内の全注文を網羅していることまで確認できたわけではありません。

それでも、重要なことが一つ分かりました。

既存Runで25段・約1秒間隔のデータを保存していたことは、bitFlyerのAPIそのものの上限ではなく、自分の観測プログラムの保存設計による制約でもあったのです。

30分間の独立取得試験も実施した

取得範囲を確認した後、5分間の試験を経て、30分間の独立取得を実施しました。

この試験では、現物・CFDの板、Ticker、約定など、計8チャンネルを購読しています。

取得したメッセージの保存に加え、CPU・メモリ・ディスク使用量も測定しました。

項目30分間の実測結果
WebSocket購読8チャンネル
HTTP板取得120回成功
WebSocket切断・再接続記録なし
平均CPU使用率1コア換算で約1.72%
最大RSS約100MiB
圧縮済み受信データ約3.96MiB

この結果から、少なくとも今回の30分間については、より広い情報を取得・保存する処理が大きな資源負担なしに動作することを確認できました。

ただし、長時間の安定性や、相場急変時の負荷、配信イベントの完全な網羅性まで証明されたわけではありません。

また、今回の保存データはアプリケーションが受信したメッセージを再直列化したもので、通信線上の全バイトをそのまま保存したものではありません。

ここでも、取得できたことと、完全に記録できたことは分けて考える必要があります。

今回の試験は新しい売買条件の実装ではありません。

今後の市場研究で利用できる観測手段を把握するための調査です。

4.HTTPの不調は市場データの停止と同じではなかった

続いて、稼働中の24時間Runについて内部状態を監査しました。

ここで見つかったのが、HTTP取得処理の問題です。

11月11日16時19分までの記録では、市場状態とFunding関連の4系統で、合計220件の20秒期限超過が発生していました。

最初は多数の通信エラーが散発しているようにも見えました。

しかし、発生時刻を詳しく調べると、状況は異なっていました。

220件の期限超過は8つの期間に集中していた

4系統は、現物・CFDの市場状態、Funding、Funding履歴です。

今回のログでは、55回すべてで4系統がほぼ同時に期限超過し、成功応答を挟まない連続失敗が8つの期間に集中していました。

つまり、220件がそれぞれ独立して発生したわけではありません。

4系統の共通する取得経路や実行環境に原因がある可能性が考えられます。

ただし、もともと要求の開始時刻と期限が揃っているため、失敗時刻の一致だけで根本原因を特定することはできません。

DNS、TLS、通信経路、ローカルの実行処理、取引所側の応答など、どこで問題が生じたのかは未確定です。

一方、今回のRunではWebSocketの接続は継続しており、HTTP不調の期間にも約定データの保存や板の更新が確認されています。

ここで、当初の認識を修正する必要がありました。

HTTPの市場状態確認に失敗したことは、板や約定の受信そのものが停止したことを意味しません。

内部の利用条件によって計算が制限されていた

現行システムでは、受信した情報をそのまま売買判断へ渡すわけではありません。

板の鮮度や状態、市場状態HTTPの応答などを確認し、定めた条件に適合する情報を利用しています。

そのため、WebSocketで市場データを受信できていても、HTTPの市場状態を確認できない期間には、シグナル計算やPAPER評価が制限されます。

16時19分までの集計では、内部の利用可能性条件を満たさないpaused区間は、累計約40分29秒でした。

ただし、この時間は市場の停止時間でも、通信全体の停止時間でもありません。

現在のプログラムが、定められた条件で情報を利用できなかった時間です。

以前は、内部の状態表示を見て、処理が正常に動いているかどうかを判断していました。

しかし、今回のように実際の処理経路を調べると、同じ「利用不可」という状態でも、止まる処理と継続する処理が異なります。

これは通信の安定性だけではなく、システム内部の設計に関わる問題でした。

5.PAPERの売買成立と評価できなかった期間を分けて考える

内部の利用条件を調べたことで、PAPER成績の解釈にも注意が必要だと分かりました。

11月11日16時19分までの途中監査では、69件の仮想入口と69件の決済が確認されています。

記録された入口について、板の利用不可を理由とした取消はありませんでした。

また、出口予定時刻がpaused区間と重なった事例も確認されていません。

ただし、これだけでシステムの利用制限が損益に影響しなかったとは言えません。

保有中の価格評価には欠測があった

69件の仮想取引のうち、64件では保有期間中に板を利用できない時間帯が存在していました。

例えば、ある約100分の取引では、保有期間中に合計約681秒、板による価格評価を実行できない時間がありました。

この間、コード上では含み損益や最大逆行損失(MAE)の評価が更新されません。

したがって、保有中の最大損失を示す指標についても、観測できた範囲に制限があります。

ただし、評価が欠測していたことと、記録された決済損益が誤っていることは同じではありません。

今回確認できたのは、保有途中の評価経路に欠測があることです。

また、HTTP不調によってシグナル計算が制限されていた期間については、本来どのようなシグナルが発生したかを、そのままでは確認できません。

つまり、発生済みのPAPER取引の成績と、制限がなかった場合に成立したかもしれない取引を区別する必要があります。

この問題は、以前の開発記録#600「DEX Arbの『判定不能』を分解する」で扱った内容にも接続します。

観測できなかったことと、機会が存在しなかったことは同じではありません。

今回は、この問題をbitFlyerの実際のPAPER観測と内部コードから確認することになりました。

なお、現在のRunは執筆時点ではまだ完了していません。

保有費用の未確定分や未決済ポジションも区別する必要があるため、途中の損益だけで最終的な収益性を判定することはしません。

6.内部監査で受信・保存・判定・評価の境界を問い直した

今回の調査では、Codexを使って内部処理の監査も行いました。

単にプログラムが動いているかどうかではなく、取得した市場データがどのような順序で処理され、どこで選別・保存され、どの判断に利用されているのかを確認しています。

その後、コードと保存記録を使った別の観点からの監査も実施しました。

ここで重要だったのは、主に3つの問題です。

保存前に情報を失う経路が存在する

現在の約定処理には、受信メッセージを解析・検証してから保存へ渡す部分があります。

このため、一つのバッチ内に不正なデータが含まれている場合、処理途中で例外が発生し、正常なデータまで保存されない可能性があります。

この経路はコードと模擬入力から確認されました。

ただし、今回の稼働中Runで実際にそのような保存前のバッチ欠落が発生した記録は見つかっていません。

ここは、コード上で発生し得る問題と、実際の市場観測で発生した問題を分けて扱います。

保存された情報だけでは判断の全過程を再現できない

現在のPAPER観測では、板を再構築した後、必要な範囲を縮約して保存しています。

一方、実際の売買判断には、板の状態だけでなく、約定の更新順序、HTTP市場状態、内部の処理時刻なども関係します。

そのため、保存された1秒間隔の板や約定履歴だけでは、過去の判断を完全に再生できるとは限りません。

市場の価格や流動性を分析することと、当時のプログラムの判断を忠実に再現することには、必要な情報の違いがあります。

また、原本の保存と判断をどこで分離するかについても、今後の設計課題として残っています。

状態の名称と実際の作用が一致しない場合がある

今回の監査では、内部の利用条件に関する一時的な不適格が71区間発生していた事例も調べました。

合計時間は約31.9秒でしたが、その区間に起因する入口取消や出口遅延は確認されませんでした。

この結果から、71回という件数だけを見て、売買処理が71回停止したと解釈するのは不適切だと分かりました。

内部の状態表示が何を表しているのか。

その状態で実際にどの処理が止まり、何が継続していたのか。

そこまで調べなければ、研究への影響は判断できません。

ここまで調べて、今回の問題が単純な通信エラーや保存容量の不足だけではないことが明確になりました。

市場の情報を取得できること。

取得した情報を保存できること。

保存した情報から市場状態を再構築できること。

そして、その情報を使って行った判断を後から検証できること。

これらはそれぞれ別の要件です。

今後は、すべてを一度に作り直すのではなく、研究上の判断に影響する部分から改善していきます。

7.説明変数を増やす前に現在の市場を観測する方法を整える

今日の調査では、OI、出来高、売買方向、板厚など、価格以外の情報についても確認しました。

また、他市場のOIを取得する方法も存在します。

しかし、現時点で外部市場の情報を追加する予定はありません。

理由は、現在の価格差戦略に対して、それらの情報が独立した予測力や収益上の優位性を持つと確認できていないためです。

外部市場を追加すれば、取得できる情報は増えるかもしれません。

一方で、市場間の連動性、情報の鮮度、時間差、契約仕様の違いなど、新しく検証すべき問題も増えます。

情報を増やすこと自体が、研究の進展を保証するわけではありません。

以前の開発記録#606「価格変化の中身を調べる――SolanaとCEXのエッジ探索」でも、観測方法や分析の起点をどう設定するかについて整理しました。

今回の調査は、その延長にあります。

ただし、現在の研究が手詰まりになったから、観測方法を見直しているわけではありません。

既存の価格差戦略は、そのまま検証を継続しています。

それと並行して、bitFlyerという市場で取得できる情報の範囲を確認し、今後どのような問いを立てられるかを考えています。

今日の調査から、少なくとも次のことが分かりました。

  • 市場全体のOIなど、今回の公開API調査では取得方法を確認できなかった情報がある。
  • 約定フローや板厚など、保存済みのデータから追加分析できる情報がある。
  • より広い板情報など、現在の保存設定では残していないものの、取得可能と確認できた情報がある。
  • データを受信できていても、内部の利用条件によって計算やPAPER評価に使われない場合がある。
  • 保存された結果が存在しても、その判断に至る処理を完全に再現できるとは限らない。

これらは、同じ「データが足りない」という言葉でまとめるべき問題ではありません。

そして、今回新たに確認した情報を、すぐにエントリー条件へ組み込む必要もありません。

今後は、まず現在の24時間Runを完了させ、保存と処理の整合性、評価できなかった期間、費用を含めた損益を確認します。

その結果を踏まえ、研究に必要な観測・記録の仕組みを段階的に改善していく予定です。

ただし、すべての技術的課題を解決することを目指すわけではありません。

何を明らかにしたいのか。そのために、何を観測し、どこまで再現できれば十分なのか。

この基準を持って、必要な範囲を整えていきたいと考えています。

今回、新しい収益エッジが確立したわけではありません。

しかし、bitFlyerから取得できる情報の制約と、自作システムが作り出している制約を、以前より具体的に区別できるようになりました。

市場が見えないのか。

それとも、自分が取得・保存・利用していないだけなのか。

この違いを確かめることは、次にどのような研究を進めるかを判断するうえでも重要です。

今は、現在の市場に集中して、その仕組みと観測可能な範囲をもう少し詳しく調べていきます。

それでは、また。

-Bot, CEX, 開発ログ