botのテストラン中は手が空くので、その間に次のbotをゴリゴリ作るようにしているのだが、フツーに脳のリソースが足りなくなってくる。これ、新しいことへの理解が不足しているからだな。もっと根本的な部分で戦略や実装の理解をしないとダメ。特に開発初期は頭をフル回転させているので腹も空く。
— よだか(夜鷹/yodaka) (@yodakablog) August 18, 2025
MMbot:概要
- 目的:① 自動停止(Alert →
/am-webhook
→disable_live
)② p99/RPS の常時可視化 ③ EV>0 の実証(最小Liveへ) - 現状判定:土台は概ねOK、制御エンドポイントと実オーダ着火が未了。全体達成度≒70%。
✅ 完了・成立していること
- 接続・認証
- REST:
api.binance.co.jp
に切替済(Global→Japan) - -2014(API-key)解消、WS深度受信OK
- REST:
- コード/環境
Config.mode
追加済(読み込み確認OK)Runner._enable_live()
追加済PYTHONPATH
を/app
参照に是正、mm_bot path=/app/mm_bot
を確認- 強制リビルド/再作成(ProcessLock 問題は再作成で解消)
- メトリクス基盤
/metrics
応答OK、既存KPI(例:mm_ev_order_total
)は露出済
⚠️ 進行中・未解決
- /control が 405(POST未受理)
└ ルート未登録 or メソッド未対応。enable/disable のトグルが不可。 - new_orders_enabled=OFF のまま → 実オーダ未実行
└ 段別メトリクスが BOOT/init のみ、p99(30s)
/RPS(30s)
が空。 - メトリクス重複の警告(
Duplicated timeseries: mm_status_new_orders_enabled
)
└ 定義の重複(Exporter/Runner両方)or Uvicorn reload。 - Alert → 停止のE2E未確認
└/am-webhook
→disable_live
の実ログ・カウンタ未確認。 - 設定の技術的負債
- APIキーがファイル直書き(対応済み)→ 環境変数/Secrets へ移行
- compose サービス名/コンテナ名の混在(
mmbot
vsmm-bot-mainnet
)
🧠 根本原因の要約(主要3点)
- /control 405:HTTP Exporter 側で POST未実装 or ルート未登録。
- KPI/レイテンシ未採取:実オーダが流れていないため、段別ヒストグラムが増えない。
- メトリクス重複:宣言箇所の一意化不足(定義は1箇所、他は参照のみ)。
📌 直近ログの重要シグナル
Duplicated timeseries in CollectorRegistry: {'mm_status_new_orders_enabled'}
System health issues detected: ['Orderbook unhealthy for BTCJPY']
(一時的。まずは通電と制御の確立が先)
🎯 次にやること(最短ルート & 受入基準つき)
STEP1:/control 修復(POST/GET両対応+runner attach)
- 受入:
POST /control {"action":"enable_live"}
→ HTTP 200 / ログにenable_live reason=...
/metrics
にmm_control_actions_total{action="enable_live"}
が +1
STEP2:最小オーダ “1本だけ通す”(LIMIT_MAKER・遠値・極小ロット)
- 受入:
mm_ev_order_total >= 1
- 段別
mm_lat_request_to_ack_seconds_bucket
に BOOT以外のサンプル mm_total_p99_ms:30s
/mm_total_obs_rps:30s
が 非空
STEP3:KPI“3行”の配線を確定(order/fill/reject の各1行)
- 受入:
mm_ev_order_total
/mm_ev_fill_total
/mm_ev_reject_total
が/metrics
で観測・増分
STEP4:Alert → /am-webhook
→ disable_live
のE2E
- 受入:
- 疑似POSTでログ
disable_live reason=alertmanager_critical
mm_control_actions_total{action="disable_live"}
+1mm_status_new_orders_enabled 0
- 疑似POSTでログ
STEP5:重複メトリクス撲滅
- 受入:再起動ログに
Duplicated timeseries
が 出ない
STEP6(安全面の後追い):Secrets移行/compose命名統一/reload無効化
📈 達成度ブレークダウン(“稼ぐ”をゴールに)
項目 | 重み | 現状達成 | 加点 |
---|---|---|---|
アルファ/EV実証(Paper→最小Live) | 40% | 25% | 10 |
実行/レイテンシ(p99/RPS・段別計測) | 25% | 60% | 15 |
リスク/自動停止(Alert→disable_live) | 15% | 50% | 7.5 |
可観測性(/metrics・KPI露出) | 10% | 80% | 8 |
運用/オペ(ビルド・再作成・経路整備) | 10% | 70% | 7 |
合計 | 100% | ≈70 |
Hyperliquid 清算スナイプBot:開発進捗サマリー
概要・現在地
- 目標(REPLAY基準):
KEEP ≥ 60%
/p95 ≤ 350ms
→ 合格後にfill_drop ≤ 10%
を“常時計測”へ。 - 現状:
p95 ≈ 300ms
(ALIGN=300で安定 ✅)/KEEP = 48%
(16→48% ↗)/fade=0(確認回路安定) - 主ボトルネック:**ltK(K未到達)**が支配(
insufficient_kinds ≈ 886
)
KPIスナップショット
- レイテンシ:
p95=300ms
(OK) - 合議率:
KEEP=48%
(目標まで+12pt) - ドロップ:計測系は配線済み(
exec_drop
/fill_drop
)※合格後に60分連続≤10%を見る - REPLAY/可視化:exactly-one成立、shortfall(oi_z/bbo/l2/burst)見える化済み
完了済み(効いた実装)
- 計測統合:Registry統一、時刻正規化、ALIGN制御、REPLAY flush
- 確認回路:confirm系メトリクス一式、pulse/refreshの“missing側限定”→ fade=0
- ltK可視化:
insufficient_reason_total
+ 理由別 shortfall ヒスト(oi_z/bbo/l2/burst) - ドロップ計測:
shadow/live
の attempt/fill 4カウンタ →exec_drop
/fill_drop
- レイテンシ分解:
req_ack_ms
(素RTT)/ack_to_fill_ms
(ttf) - 品質/安全:first-fail-wins(exactly-one保証)/Wilson区間A/B判定/SLO Burn(5m×1h)/invariants
- EV/運用:EVロガー(手数料込み)/EVゲート(Canary/LIVE)/Canary段階表
- 運用パック:120sプレフライト/発射シーケンス/Day-0実行/退行プレイブック/REDSTOP
- A/B証跡:CSV +
d_keep_per_step
/pass_signif
(弾性・有意性)
進行中・未達
- KEEP 48% → 60%:ltK削減の“1クリック”を継続(質を落とさずK到達率↑)
- drop ≤ 10%(60分連続):ダッシュボード常設 & 原因分解(門前/途中)での是正
- 日次EV>0 ×5営業日:Canary極小ノッチで検証運用
リスク & 監視ポイント
- ALIGN張り付きの影:
req_ack_ms p95/p99
・ack_to_fill_ms p95
で裏退行検知 - exactly-one崩れ:invariants(kept+faded=processed)±1〜2を常時確認
- サンプル不足:A/B判定は
DENOM ≥ MIN_DENOM
(不足時はDEFER) - ラベル爆発:
count by (symbol,reg)(shadow_exec_attempt_total)
を監視
今日やること(90分パッケージ)
- 120sプレフライト → OKなら先へ
- 攻め順自動決定(Top ltK理由 × shortfall p50)
- 段階A:1クリック=1ノブ
OI_Z: 1.4→1.3
orBBO: 3.0→2.8
(片方だけ)→ 5分A/B
- 判定
PASS+SIGNIF
:採用→drop常設PASS+NS
:サンプル増(10分窓 orMIN_DENOM↑
)FAIL
:即ロールバック→段階B(L2 0.72→0.75
orBURST 7→6
片方)
- Canary極小ノッチでEV並走(SLO Burn有効化、異常時はREDSTOP)
Go/No-Go(合否ライン)
- REPLAY:
KEEP ≥ 60%
&p95 ≤ 350ms
連続2ラウンド - drop:
hl:fill_drop_5m ≤ 0.10
60分連続 - EVゲート:Canaryで
avg_over_time(ev_live_usd[1d]) > 0
×5営業日(MaxDD内)
ガンマスキャbot:🧭 現在地(結論)
- MVPは“実戦投入”可能な状態まで到達。
- 目的の「まず$1」に向けて、執行・安全ガード・WS化・アンワインドまで実装済み。
- あとは時間帯選定+軽いチューニングで勝率を上げるフェーズ。
✅ できていること(実装済み)
コア機能
- Bybit V5クライアント(httpx/async)
- 署名v5、
instruments/tickers/order.create/asset.coin_greeks/position.list
対応
- 署名v5、
- ATMストラドル自動選定
- 直近満期・ATM近傍、
status=Trading
フィルタ、minOrderQty/qtyStep
準拠
- 直近満期・ATM近傍、
- ランナー(デルタ・スキャルピング)
orderLinkId
必須対応(UUID)- 数量丸め:
lotSizeFilter.qtyStep
に厳密準拠、ゼロ落ちはminOrderQty
に引上げ - Δヘッジ:Perp BTCUSDT、Market IOC
- DRY_RUN・時間ウィンドウ(
TIME_WINDOW
)・CSVロガー
収益・安全関連
- PNLブック(在庫ベース):実現PnL更新、部分約定対応
- 利確/損切り:
PNL_TARGET_USDT
/STOP_LOSS_USDT
- ヒステリシス:
DELTA_FIRE
/DELTA_CLEAR
(往復ビンタ低減) - リトライ/バックオフ:429/5xxで指数バックオフ+ジッタ
- スプレッド・ガード:
SPREAD_GUARD_BPS
(広がり時ヘッジ見送り) - ステイル検出:
STALE_GREEKS_SEC
/STALE_TICKER_SEC
- クールダウン:
REFRACTORY_SEC
- ノーション上限:
MAX_LINEAR_NOTIONAL_USDT
- 可変スリープ:アイドル/ヘッジ後でsleep調整
WS & 実約定
- WSクライアント:
greeks
/execution.linear
/order.linear
- WS優先のΔ取得+RESTフォールバック(
WS_GREEKS_TIMEOUT_SEC
) - 約定集約器:
await_fill_or_done()
で部分約定VWAP、キャンセル即確定 - WS再接続ループ:切断→再購読まで自動
アンワインド/Θ
- 安全アンワインド:
/v5/position/list
で実ポジ確認→reduceOnly
でゼロ化 - Θログ:
theta_tick
出力 - Θ積分:
theta_accum
(日/時で積分) - Θ日次予算ON/OFF:
THETA_BUDGET_USDT_PER_HOUR
で悪い日を機械的に回避
開発補助
- プレフライト:REST疎通/銘柄/Greeks確認
- サマライザ:CSVから
hedges/realized/realized_net(pending)/delta p95/exit理由
- セッション記録:
session_start
で環境スナップショット
🕳 未着手/保留(軽く手を入れると良いところ)
- Option足のクローズ(reduceOnly+orderLinkId)※安全導線の仕上げ
- Fee/Slipの精緻化(API/実fillベースで累積、net PnLを標準出力)
- Funding寄与の分離(線形のFRを別カラム)
- 監視ダッシュボード(p95/p99・失敗回数・スプレッド・Θ積分を見える化)
- ユニットテスト(丸め・ヒステリシス・集約器の境界値)
🚀 直近の実行フロー($1一直線)
- プレフライト
preflight
で[OK] linear / [OK] option / [OK] greeks
を確認 - 本番小口(JST 22:15–23:00 推奨)
環境(例):
WS_ENABLED=true DRY_RUN=false TIME_WINDOW=22:15-23:00 DELTA_FIRE=0.012 DELTA_CLEAR=0.007 PNL_TARGET_USDT=1.0 STOP_LOSS_USDT=-3.0 SPREAD_GUARD_BPS=4.0 REFRACTORY_SEC=0.8 MAX_LINEAR_NOTIONAL_USDT=2000 MAX_HEDGES=10 THETA_UNIT=per_day THETA_BUDGET_USDT_PER_HOUR=0.8
- ログ確認(合格ライン)
- 退出が
take_profit_exit
(realized ≥ 1.0
) hedges
が 8–15回に収まるdelta p95
がFIRE/CLEAR
の帯に収まるunwind_linear
で在庫ゼロtheta_accum
が過大なら時間帯/予算を見直し
🧪 チューニング指針(失敗時の動かし方)
- ヘッジ回数が多すぎる →
DELTA_FIRE↑
orREFRACTORY_SEC↑
- スキップが多い(spread/ cooldown) → 時間帯再選定 or
SPREAD_GUARD_BPS↑/REFRACTORY↓
- θコストが重い → 稼働窓を短縮 /
THETA_BUDGET
でブロック / 満期をより短期へ - ノーション上限に当たる →
MAX_LINEAR_NOTIONAL_USDT↑
or サイズ/閾値調整
📌 今日のToDo(90分でできる)
- JST 22:15–23:00で1本運転(
MAX_HEDGES=10
) summarize_log.py
のrealized_net
を出す(fee/slip累積反映)- ログ末尾5–10行(
hedge_ok/hedge_pnl/exit/unwind_linear/theta_accum
)を確認
→ 数字を見てFIRE/CLEAR/REFRACTORY/SPREAD_GUARD
を1段調整
ショート系bot:進捗サマリー
- ゴール:10分スモーク合格 → 24h Testnet Canary → α判断
- 現在地(概算達成度):55–60%
- 計測・基盤:95%(mp集約復旧、/metrics安定、CB真実値、EV分解、4カウンタ、Decimal統一)
- 執行性能(短時間):70%(req→ack ≈ 11ms、stalenessガードOK。ただし24h連続SLOは未検証)
- 実約定&EV:20%(IOC fill=0 → EV未通電)
- 24h Canary:未実施
いま“できている”こと
- Multiprocess /metrics 完全復旧:
/tmp/bsb_mp/current
原子的切替、集約REGISTRY運用。 - 可観測性:
- 露出/詰まり系:
orders_sent_total / fills_total / reject_total / ioc_timeout_total
- レイテンシ:
short_req_ack_ms_* / short_cancel_ms_*
- 板鮮度:
ob_staleness_ms_*
、skip_due_to_stale
- 新規:
ob_fetch_total{src, outcome}
、価格異常short_bad_price_total{reason}
- 露出/詰まり系:
- 価格経路の健全化:
- TOB経路復旧(OrderbookProvider:WS→RESTフォールバック、age≤300ms)
- Decimal一気通貫+三段ガード(非正値/過大乖離/レンジ外の遮断)
sell_price = floor_to_tick(best_bid - 1*tick)
- 運用セーフティ:post-only混入排除、CANARY_RATIOの明示切替手順整理
いま“詰まっている”一点
- IOCの実fill=0 →
ioc_timeout_total
が支配的、EVメトリクス未通電
直近スナップ例:orders_sent=64 / fills=0 / reject=0 / ioc_timeout=57
、req→ack 平均≒11ms
⇒ 約定経路(実マッチ/報告)に未接続の可能性が高い
原因の切り分け(想定)
- A. 模擬板に約定エンジンが無い(受理→EXPIRED(0)連発)
- B. Private WS/REST の“約定報告”未配線(受理はされるがfill検知できない)
- C. IOCの送信仕様ミス(TIF/PO/帯域制限—ペイロード/ログで実値確認)
直近の“証跡パック”4本(最低限見るべきもの)
保存して変化を見る用:
short_(orders_sent|fills|reject|ioc_timeout|cancels)_total
short_(req_ack|cancel)_ms_(bucket|sum|count)
(先頭数行)short_(ev_bps_total|ev_bps_count|price_improve_bps_total|slip_cost_bps_total)
short_ob_fetch_total|short_skip_total|short_bad_price_total
次のアクション(30–60分でEVを“通電”)
- epoch再作成(古い異常値の残骸リセット)
rm -rf /tmp/bsb_mp && mkdir -p /tmp/bsb_mp/current
→ metrics-serve再起動 →short_bad_price_total==0
を確認 - ACK/DONEの可視化を追加(原因A/B/Cの即判定)
short_ack_total{tif="IOC",post="false"}
short_done_total{status="FILLED|EXPIRED|CANCELED"}
- ログ:
ACK … tif=IOC postOnly=False
,DONE … status=… executed=…
- Market pingで1件の確定fill(EV通電スイッチ)
--force-market --min-notional-usdt 50
(fills>0 と ev_bps_count>0 をまず作る)
- **IOC 5連射(stale skip有効)**で報告経路を判定
executed_delta>0
を差分カウント(EXPIRED
でもpartialならOK)- WS trade or REST executedQty>0 が一度も無ければ B確定(報告配線修正へ)
- 10分スモーク(IOCのみ)
Go判定:EV_bps_avg>+3
&win%>55%
&reject<1%
&CB==0
&ioc_timeout/orders<10%
24h Testnet Canary(移行条件とStop条件)
- 移行条件(上の10分Go判定を満たす)
- 実行:
CANARY_RATIO=0.02
,taker-every=6
, post-only禁止, staleness>300msはskip - Stop:
reject>1%
orCB!=0
orreq→ack p99≥250ms
orcancel p99≥300ms
orioc_timeout/orders≥0.1
命名のぶれ止め(将来の自分を救う)
short_fills_total
=フィル片件数(差分で加算)short_orders_filled_total
=完全約定の注文件数(任意)short_trades_total
は上とどちらかに統一(推奨:フィル片と同義)short_win_trades_total
=注文基準で判定(フィル片は数量加重で集約してからEVへ)short_ev_bps_total/count
=注文単位(片は集約)
DoD(このフェーズ)
short_bad_price_total==0
が継続- Marketで確定fill →
ev_bps_count>0
- IOCで fills>0(差分カウントで検知)
- 10分スモークGo判定クリア
CEX/DEX arbbot:開発進捗サマリ
目的・KPI(据え置き)
- 目的:AUTO→GOコンバージョンを立ち上げ、最初の有益な5本を安定生成
- 当面KPI:
AUTO→GO ≥ 30%
、unit_mismatch ≤ 3%
、miss_2nd ≤ 30件
直近の数値サマリ(前回90分計測)
- AUTO→GO:26.7%(目標未達)
- WHY内訳トップ:
unit_mismatch
14.7%(53件)miss_2nd
13.1%(47件)gross<min
12.2%(44件)
完了済み(実装)
- 比較の正規化 一本化
NormalizedQuote
導入、preok→last-lookで同一オブジェクトを貫通- 比較用
mid = (dq + cb) / 2
に統一
- ageゲート+二段ガード
stale_quote
を unit_mismatchに混在させない(VWAP_MAX_AGE_MS=250
)unit_mismatch
HARD=8% / SOFT=2% の二段
- VWAP経路の安定化
VWAPQuote
型/MockConnector.get_vwap()
/VWAPProvider.best()
を実装- 複数CEXの$12 BID/ASK VWAPから最良採用
- FSM互換レイヤ
FSMAdapter
でrecord_hit/on_hit
、cooldown_off
のAPI差を吸収delta_hit_ms
の取得を標準化
- 一貫性チェッカー
- preok/last-lookの正規化入力ドリフト検知(テスト時アサート)
- 診断ログの拡充
unit_mismatch
時にside/vwap_side/cb_px_usdt/dq_px_usdt/mid/fx/tick/quote_age_ms/ex/route
を1行出力
- 起動時サニティログ
vwap_notional/age_max_ms/ttl_s/unit_mismatch_{hard,soft}
を1行出力
現行運用設定(確認済み)
NET_EDGE_MIN_BPS=38 TTL_SECONDS=3.0 UNIT_MISMATCH_SOFT=0.02 UNIT_MISMATCH_HARD=0.08 VWAP_NOTIONAL_USD=12 VWAP_INTERVAL_MS=100 VWAP_MAX_AGE_MS=250 SECOND_WINDOW_MS=1500
- 時間帯制御:USオープン±30分のみ自動GO
- 429制御:適応ガード(>1/10minで一時
GUARD_SEC=2
)
セルフテスト結果(3分チェック)
- 正規化+二段ガード:
- 12%差 →
unit_mismatch
- 2.5%差 →
disagree_2pct
- age>250ms →
stale_quote
- 12%差 →
- 方向検知:
dex_buy_cex_sell → CEX=BID
/dex_sell_cex_buy → CEX=ASK
(OK) - preok→last-look同一性:OK
直近の修正ログ(Fix)
- Fix-1:VWAP取得不可の解消(型定義・Mock・Provider実装)
- Fix-2:HitStateMachineメソッド名齟齬の吸収(Adapter)
- Fix-3:Detector内のage→unitの順でのゲート適用/mid固定/サニティログ
未確認事項・保留中
- 最新45分ランの実測(USオープン±30分):
AUTO→GO
実値、unit_mismatch
の偏り(通貨/向き/桁/age)、delta_hit_ms
の分布(p80/p95)
gross<min
の銘柄別傾向(SOL/RAYなどでの差分)
現状ステータス(要約)
- 土台:価格取得/正規化/ガード/FSM/ログは揃った
- ボトルネック:前回は
unit_mismatch
とmiss_2nd
が主因 - 状態:45分ランによる確認フェーズに入れる状態(準備完了)