本日は、止める→見える→触れるまで一気に進めた日でした。しかし、「止めの基盤」と「EV検証」の部分がまだ数字と噛み合ってない部分もあるので、明日はこの点を潰していくのがメインタスクになりそうです。
以下の4つに加えてガンマスキャルピングbotの雛形も作成しましたが、実装レベルに満たないため本日の掲載は省略します。
【明日のbot開発覚書】
・CEX/DEX arb:閾値の大幅いじりと新監視の追加はもうやらない。打席を増やす。
・清算スナイプ:窓/TTLは固定。いじるのやめる。
・全体:EV(期待値)証明が後ろ倒しになりがち。基盤の詰めにリソース(時間&学習)を使いがち。「触った結果が+かどうか」の証拠を集めるべき。— よだか(夜鷹/yodaka) (@yodakablog) August 18, 2025
MMbot作業ログ
0) ゴール
- 自動停止メカニズム(Alert →
/am-webhook→disable_live)の完成 - p99/RPS の安定観測とKPIメトリクス基盤の常時可視化
1) タイムライン(重要イベント)
- [構成修正] Exporter と Runner の単一プロセス統合(/metrics & /emit & /control & /am-webhook を同一REGで提供)
- [配線修正]
/control実装(POST, X-Auth-Token)→ Runner のnew_orders_enabled=Falseに連動 - [REG問題解決] REG ID不一致(別プロセス)の解消。ホットパッチで
/app/mm_botに直接差し替え - [重複メトリクス]
Duplicated timeseriesの排除(宣言の重複を整理:Runner側に一意、Monitor側と二重にしない) - [録画式反映] p99/RPS 録画ルールを
*_seconds_bucket前提の式に統一(低トラフィック耐性つき) - [ウォームアップ]
/emit経由で観測データ注入(WARM)→ Prom 側で p99/RPS を非NaN化 - [KPI基盤]
mm_ev_order_totalを /metrics に掲載(発注時インクリメントの足がかり)
2) 実測・検証結果
- /control:HTTP 200(手動停止OK)
- p99 / RPS:
mm_total_p99_ms:5m= 832.16 msmm_total_obs_rps:5m= 0.3221
- ヒストグラム:
mm_lat_total_seconds_bucketの行数 = 60 - KPI掲載:
mm_ev_order_total 0.0(メトリクスは可視、配線は最小) - (一時未達)
disable_live reason=...の理由ログが未表示(/control は効いているがログが拾えない場面あり)
3) 主要な問題と対処
3-1) 古いコードが走っていた
- 兆候:
HAS_control_counter=Falseなど - 原因:ビルド反映漏れ/
/app/srcではなく/app/mm_bot配置だった - 対処:ホットパッチで
/app/mm_bot/...に直接runner.py/http_exporter_std.pyをdocker cp→ 再起動
3-2) Duplicated timeseries
- 兆候:起動時に
Duplicated timeseries in CollectorRegistry - 原因:同名メトリクスの二重宣言(Runner と Monitor)
- 対処:宣言を一意の場所に集約、他は参照のみに変更
3-3) p99 が NaN / RPS = 0
- 原因:観測不足 or 録画式が
_agg_参照 - 対処:
*_seconds_bucketを参照する式に統一+WARM注入 → 解消
3-4) disable_live の理由ログが出ない
- 可能性:logger設定/ハンドラ登録のタイミング、stdout不達
- 対処案(実装方針):
_disable_live()を logger+stdout の二重出力に修正(パッチ準備済み)
4) 現在地(達成度)
- 制御フロー基盤:100%(/control 200、停止フラグ、Webhook口あり)
- メトリクス収集:100%(p99/RPS 非NaN、bucket 60)
- KPI基盤:70%(order は見える/fill・reject・P/L分解は配線中)
- ログ出力(停止理由):90%想定(二重出力パッチ適用で確実化)
総合進捗:~80–85%
5) 直近の改善パッチ(最小差分・要点のみ)
5-1) _disable_live() の確実ログ化
# src/mm_bot/core/runner.py
import logging, sys
...
def _disable_live(self, reason: str = "no_reason"):
self.new_orders_enabled = False
mm_control_actions_total.labels(action="disable_live").inc()
msg = f"disable_live reason={reason}"
logging.getLogger("mm_bot.control").error(msg) # logger経由
print(msg, flush=True) # stdout保険
5-2) Exporterでの受信ログ(任意)
# src/mm_bot/services/http_exporter_std.py (/control 分岐)
logging.getLogger("mm_bot.control").info(f"control executed: disable_live reason={reason}")
5-3) KPIの“配線”を最低1行ずつ
- 発注成功:
mm_ev_order_total.inc() - 約定:
mm_ev_fill_total.inc()+mm_pnl_components_total.labels(kind="spread").inc(spread_jpy) - 拒否:
mm_ev_reject_total.inc()
6) 即時チェック(3本)
# A) /control → 200 → カウンタ増分&理由ログ1行
curl -s -X POST http://localhost:8080/control \
-H "X-Auth-Token: mm-bot-control-2024" -H 'Content-Type: application/json' \
-d '{"action":"disable_live","reason":"manual_test"}' -w "\nHTTP:%{http_code}\n"
curl -s http://localhost:8080/metrics | grep -m1 '^mm_control_actions_total{action="disable_live"}'
docker logs mm-bot-mainnet --tail 200 | grep -i "disable_live reason=" | tail -1
# B) p99 / RPS(非NaN/非0の継続確認)
curl -s 'http://localhost:9090/api/v1/query' --data-urlencode 'query=mm_total_p99_ms:5m'
curl -s 'http://localhost:9090/api/v1/query' --data-urlencode 'query=mm_total_obs_rps:5m'
# C) KPI 1本(order)
curl -s http://localhost:8080/metrics | grep -m1 '^mm_ev_order_total'
7) 次フェーズ(完了後 30〜60分)
- Alertmanager E2E:
/am-webhookで Critical firing →disable_live1行ログ - Grafana 4パネル(プリセット):
- Fill/Reject 率(5m)
- SpreadPnL(日次合算)
- Cancel p95(ms)
- 実行RPS
- Paper EV/bp ミニ集計(CSV→日次EV、分解4要素)
MMbot達成度(「稼ぐ」をゴールにすると)
約 50%(±7%)
土台はかなり前進しましたが、“お金を生む証明”=EV>0 の実証が未了です。いまは「止められる・見える・流れる」段まで整い、**“勝てるかを示す”**の最終区間が残っています。
内訳(重みづけ評価)
| 項目 | 重み | 現状達成 | 加点 |
|---|---|---|---|
| アルファ/EV検証(Backtest→Paper→最小Live) | 40% | 20% | 8 |
| 実行/レイテンシ(p99/RPS、配線) | 25% | 70% | 17.5 |
| リスク/自動停止(Alert→disable_live) | 15% | 70% | 10.5 |
| 可観測性(/metrics, Prom, 録画式) | 10% | 90% | 9 |
| 運用/オペ(手順化・スケール準備) | 10% | 50% | 5 |
| 合計 | 100% | ≈50 |
いま効いている:/control 200、p99/RPS 非NaN、同一REG、KPI基盤(order)
まだ:disable_live理由ログの確実化(微修正)、fill/reject/PnL のKPI配線、Paper→最小LiveのEV実証
ここから 70% に跳ねさせる“3本”
- Paper 24–48h(現実寄り Fill 模型)
- 受け入れ:EV>0 / Fill≥35% / Reject≤3%
- KPIの配線を3行だけ追加(各イベントで1行)
- 発注成功:
mm_ev_order_total.inc() - 約定:
mm_ev_fill_total.inc()+mm_pnl_components_total{kind="spread|fees|…"} - 拒否:
mm_ev_reject_total.inc()
- 発注成功:
- 停止E2Eの確証
/am-webhook→disable_live reason=…がログ+カウンタで残ることを確認
“Go/No-Go”の受け入れ基準(最小Liveへ)
- Prom:
mm_total_p99_ms:5m非NaN、mm_total_obs_rps:5m> 0(継続) - Paper 24–48h:EV>0 / Fill≥35% / Reject≤3%
/am-webhook→ 停止ログ1行+mm_control_actions_total{action="disable_live"}増分- 最小Live(1×, 1日):ネットPnL ≥ 0
MMbot開発:今日の“筋の悪い”ところ(短評)
- インフラの最終1%に時間を使いすぎ
/metrics・/control・REG統一は既に“勝つための必要条件”は満たしていました。そこからログ体裁やプロセス競合の詰めに長く滞留し、EV証明の着手が遅れたのが痛い。 - KPI配線が“基盤止まり”
mm_ev_order_totalは出せたのに、fill / reject / PnL分解の1行配線を後回しに。
→ P/Lの内訳が見えない = 明日の意思決定ができない(最短経路を外す典型)。 - 反映戦術がブレた(ビルド vs ホットパッチ)
build中断→ホットパッチ→再起動…の流れで、/app/src と /app/mm_bot の差に振り回されました。
→ 「今日はホットパッチだけ」など手段を固定し、確認コマンドをテンプレ化すべき。 - “止めた”事実の監査が弱い
発注スキップは効いているのに、disable_live reason=...の監査ログが未出力のまま先へ進んだ。
→ “止まる”は利益を守る最後の柵。ログ+カウンタの二重で即可視化が最短。 - 実験の受入基準/終了条件の宣言が薄い
「いつをもってOKで次へ進むか」が曖昧で、作業の終点が伸びる。
→ “p99/RPSが数値→KPI3行→Paper 60分”の順番ロックを掛けるべきでした。
明日の改善プラン(3時間で70%ラインへ)
ブロックA(45分)— 停止の監査を確実化
- Runner
_disable_live()を logger+stdout 二重出力に(今日のパッチ案でOK)。 - 受入:
/control200 →disable_live reason=manual_testがログ1行mm_control_actions_total{action="disable_live"}が +1
ブロックB(60分)— KPI配線を“3行だけ”
- 置く場所は最低3箇所:
- 発注成功直後 →
mm_ev_order_total.inc() - 約定ハンドラ →
mm_ev_fill_total.inc()+mm_pnl_components_total{kind="spread|fees|slippage|adverse"} - 拒否ハンドラ →
mm_ev_reject_total.inc()
- 発注成功直後 →
- 受入:
/metricsで各メトリクスが見え、WARM/ドライランで非0になる。
ブロックC(45分)— Paper 60分スモーク→EV/bp
- 先頭距離×確率+部分約定の“簡易モデル”でOK(既に実装済みベース)。
- 受入:
EV/bp(spread/adverse/fees/slippageの分解付き)を1枚出力。
ブロックD(30分)— Alertmanager E2E
/api/v2/alertsに firing POST →disable_liveログ+カウンタで確認。- 受入:
MMBotLatencyCriticalfiring→ 停止の事実がログに残る。
明日のガードレール(迷いを潰すルール)
- Exporter/REGには触れない(凍結):/app/mm_bot のホットパッチのみ。
- “ビルド or ホットパッチ”を開始時に固定(明日はホットパッチのみ推奨)。
- 各ブロックに明確な受入条件(上記の「受入」を満たしたら即次へ)。
- 作業前にこの2行だけ実行:
→ 赤が出たら基盤、数値が出たらKPI/EVへ。迷わない。
docker exec mm-bot-mainnet python -c "import mm_bot.core.runner as r; import inspect; print('HAS_disable_live=', 'disable_live reason=' in inspect.getsource(r.Runner))"
curl -s 'http://localhost:9090/api/v1/query' --data-urlencode 'query=mm_total_p99_ms:5m'
一言まとめ
- 今日の躓きは 「基盤の1%詰め」>「EVの可視化」 に偏ったこと。
- 明日は “停止ログ1行+KPI3行+EV1枚” を時間箱でやり切るのが最短ルート。
CEX/DEX arbbot開発ログ
1. 立て直し・計測開始
status_now.pyで健全性確認:watcher=UP/killswitch=UP、429カウンタ=0- 時間帯制御ON:
time_slot_control.sh(USオープン±30分のみ自動GO) - 近接アラート再起動(単発化のため
flock):near_go_alert.sh SOL 0.05(AUTO_TH採用時のみ自動GO)near_go_alert.sh RAY 0.03
2. Jupiter応答の堅牢化(KeyError/data対策)
fetch_now.py:汎用パーサ_parse_jup_out_usdc追加data[0].outAmount/ トップレベルoutAmount/routes[0].outAmount/otherAmountThresholdに対応
- 直ルート+最良ルートの二段取得、安い方を採用
- amount=0.8 SOL、slippageBps=20 に最適化
3. “叩かない”設計(429抑止)
rate_guard.shを適応式に:GUARD_SEC基本+429回数で自動延長fetch_now.pyのget()で 429検知→カウント/成功→0リセット
4. 刺す直前の制御(AUTO→GO 0%対策:ミニパッチA/B/C)
- A: 1stヒット後クールダウン解除 → 2ndヒットを1–2sで確実評価
- B: last-look の計算式を preok と統一(同MID)→ 境界誤キャンセル抑制
- C: WHYログ分解 を導入(stage=gross0/gross10/depth/dry8/preok_false/last_look)
5. depthでの空振り抑止(当たり寄せ)
ladder_try_now.sh:VWAP-BIDの採用($10を呑める平均価格)- (拡張)
depth_ok_any.py作成:OKX/Binance/BybitのVWAPを比較し最良VWAPを採用
6. 観測ログ(第1→第2回)
- 第1回:NEAR=1 / AUTO=69 / GO=0、
skip={'pre-net':53, 'gross<0':84, 'gross<10':2} - 第2回:NEAR=1 / AUTO=85 / GO=0、
why={'depth':6}(WHY生成開始)
→ AUTO↑(+16)、depthで落ちていることが可視化
7. 運用・調整ノブ(If/Then)
gross<0多い → CEX優先/VWAPを維持(OKX→Binance→Bybit)pre-net多い → 0.8SOL/20bps・fx_bp自動反映を維持- AUTO→GO<30% が継続 → TTLを 2.5s→3.0sへ +0.5s 、429平均>1なら
GUARD_SEC=2
8. 今日のDone基準(据え置き)
- 二重ゲートで新規5本(NO-GOは不足数値ログ)
- 5本サマリ:win_rate>0.60 & avg_pnl>0(未達→実行ライン±1bps)
exec_log.jsonl:{ts,tap,pre_net,fx_bp,ladder,dq,df,cb,cf}(+need_delta_px/tap_age_secがあれば尚良)
CEX/DEX arbbot:総合評価(いまの立ち位置)
- 総合達成度:40% ±5%(目安) 収益化の“土台”はほぼ整備済みだが、**実行フェーズ(AUTO→GO→約定)**でまだ刺さっていない状況。
軸別スコア(根拠つき)
| 軸 | 達成度 | 根拠(直近ログから) |
|---|---|---|
| インフラ/監視 | 90% | watcher/killswitch=UP、429適応ガード=0、flock導入済み、時間帯制御ON |
| 価格取得/レート制御 | 85% | fetch_now堅牢化(Jupiter汎用パーサ、直/最良ルート、0.8SOL/20bps、キャッシュ+バックオフ) |
| 実行パイプライン(NEAR→AUTO→GO) | 55% | NEAR→AUTOは十分(直近200行でAUTO=69→85へ改善)だがGO=0。2ヒット/last-look/深さで止まる |
| フィルタ・安全性(ムダ打ち抑止) | 80% | gross<0/gross<+10/dry pre-net<+8/depth/VWAP/last-look の多層フィルタ完備 |
| アルファ/シグナル品質 | 25% | gross<0が最多(84件)、pre-net不足(53件)。TRADES=11・win_rate=0 |
| データ量/再同定可能性 | 30% | 実弾N=11は統計が薄い。near-goスナップショットは蓄積中(p50 needΔ≈0.0112 USDTと“近い”が未到達) |
目下の主要ブロッカー(AUTO→GO=0の原因)
- 板厚不足(WHY: depth):$10を一撃で呑めるBIDが不足(stage=depth 記録あり)
- 境界判定の取りこぼし:2ヒットのTTL/COOLDOWN/last-lookの直前ロジックでキャンセル
- CEX_BID ≤ DEX_Qの場面が多い(gross<0=84) → そもそも到達しにくい時間帯/銘柄が多い
今週の“進捗が見える”目標(Done定義の落とし込み)
- 量:二重ゲートで 新規5本(NO-GOは不足数値ログ)
- 質:5本サマリ win_rate > 0.60 & avg_pnl > 0
- ログ:
exec_log.jsonlが {ts,tap,pre_net,fx_bp,ladder,dq,df,cb,cf}(+必要ならneed_delta_px/tap_age_sec)
ここから“稼ぎへ”最短の3手(設計据え置き・即実行)
- 深さで落ちない:最良VWAP×複数CEX を last-look まで貫通
- 既に導入済:
depth_ok_any.py→ OKX/BNB/BYBIT で $10 VWAP 最良を採用 - 効果指標:WHY: depth 比率が下がること、AUTO→GO比が上がること
- 既に導入済:
- 2ヒットの取りこぼしをさらに減らす
- 1stヒット後COOLDOWN解除は実装済 → **TTLを+0.5s(2.5→3.0s)**に小緩和(429はrate_guardで吸収)
- 効果指標:AUTO→GO ≥ 30% 到達
- 当たり時間帯に集中(USオープン±30のみ自動GO)
- すでにスロット制御ON。**AUTO_TH(SOL 0.015/RAY 0.025)**は据え置き(NEAR→AUTOは十分)
- 429が増えたら一時的に
GUARD_SEC=2(0.5 req/s)→落ち着いたら戻す
期待値の見立て(短評)
- 土台の完成度は高い(≈85–90%)。
- 勝ちに直結する差分は“刺す直前の数秒”:深さ/VWAP/TTLを詰めればAUTO→GOが立ち上がる見込み。
- 近接度のp50≈0.0112 USDTは“届く距離”。CEX側VWAPが乗った瞬間に、2ヒット+last-lookを通過できるはず。
結論
- いまの達成度:40%前後。
- 短期の勝ち筋:最良VWAP×複数CEX+2ヒットTTLの小緩和+時間帯集中で、AUTO→GOを“0→30%”へ引き上げ、最初の5本で**+PnL**を取りに行く。
- 60–90分計測後の数字(サマリ・ファネル・WHY内訳)を頂ければ、実行ライン(±1bps)/AUTO_TH/GUARD_SECをその場で微調整します。
CEX/DEX arbbot:今日の筋悪ポイント(原因 → 影響)
- AUTOは増えたのに GO=0 を“その場”で潰し切れていない
- 原因:2ヒットTTL/COOLDOWN/last-lookの最終段で落下。変更は入れたが効果確認ループが当日中に回り切ってない。
- 影響:NEAR→AUTOの増加(69→85)に対して、当日の実GOが0のまま。
stage=depthの未解決を後回し(WHY: depth が早期に可視化された)
- 原因:$10を呑めるVWAP(しかも複数CEXでの最良)を最終段まで一貫適用する処置が遅れた/確認不足。
- 影響:板薄い見かけBidでpreokまで進んで落ちる → AUTO→GOが立ち上がらない。
- ログの“一致”を崩したまま計測を進めた(NEAR=1に対してAUTO=69/85)
- 原因:near_go の多重起動・ログ源の非対称(SOL/RAY混在/旧プロセス生存)を潰す前にファネルを読んだ。
- 影響:NEAR→AUTO の比率評価が歪む→しきい値の調整判断が遅れる/誤る。
- NET_EDGE_MIN_BPS が unset の時間帯があった
- 原因:環境変数の輸出忘れ/表示上の食い違い。
- 影響:Watcherの表示・挙動の不一致リスク(実行ラインの誤認)。
- “時間帯と負荷”より“設定の微修正”を優先
- 原因:429/awkなどのインフラ改善に時間が割かれ、USオープン±30の当たり時間帯での刺し込みが薄くなった。
- 影響:当たり母集団を取りに行く機会損失。ログは増えたが、稼ぐための打席が増えていない。
明日の改善アクション(90分プラン)— “刺さる”に一点集中
A. 最終段を一気に通す(AUTO→GO ≥30% にする)
- TTL 小緩和を当日中に検証(+0.5s)
- いま 2.5s → 3.0s へ。
- 成功条件:AUTO→GO ≥30%(直近200行で GO≧60×0.3)
- VWAP×複数CEX を last-look まで一貫適用(落ち所=depth潰し)
depth_ok_any.pyの 最良VWAP を preok直前→last-look直前の両方で採用(CBの上書き一貫)。- 成功条件:
why_breakdownの depth 比率↓、GO増加。
- 単価サニティ(unit mismatch)で“異常値”は即キャンセル
abs(cb−dq)/mid < 0.10を満たさなければ[WHY] unit_mismatchで落とす。- 成功条件:誤発射ゼロ(NO-GO理由に unit_mismatch が出たら観測)
B. 観測→判断→即ノブ(10分×2回)
- ログの一致を先に担保
pkill -f near_go_alert.sh→source time_slot_control.sh→ 単発起動(flock済みでも古い個体は止める)。- 成功条件:NEAR の増加に対して AUTO が過大にならない(NEAR≲AUTO)
- ファネル+WHYで即判断
summary_5_trades.py(skip + WHY 内訳)/NEAR・AUTO・GO の3値。- If/Then
- AUTO→GO <30% かつ WHY=depth 多い → GUARD_SEC=2(429抑止&連打抑制)
- WHY=last_look 多い → TTLを +0.5s(最大3.0sまで/戻しは数字で)
- NEAR→AUTO <10% → AUTO_TH を SOL 0.015→0.02、RAY 0.025→0.03 に +0.005 のみ
- 当たり時間帯に集中
- 迷わず USオープン±30分だけ自動GO、他時間は通知のみ。
- 成功条件:その時間帯に GO が立つ(ladder_watch.log に “GO (ladder …)” が出る)
C. ガード(落ちない工夫)
export NET_EDGE_MIN_BPS=38を明示輸出 →check_main_watcher.sh再起動- 429 が 10分平均で >1 → 一時的に
export GUARD_SEC=2(戻すときはunset GUARD_SEC)
“やらないこと”(明日は削る)
- しきい値の大幅いじり(±1bps以上の変更)
- BTC再挑戦(Jupiter mint/ルートが健全化するまでOFF)
- 新しい監視や可視化の追加(WHY内訳・ファネルが揃っている)
できていた良い点(このまま維持)
- Jupiter堅牢化(汎用パーサ、直/最良ルート、0.8SOL/20bps)
- 適応レートガード(429=0)
- 多層フィルタ(gross/乾式pre-net/depth/VWAP/last-look/2ヒット)
- 時間帯制御(USオープン±30の集中)
一言でまとめると
- 筋の悪さは、「最終段の数秒」を今日中に詰め切れず、当たり時間帯の打席を増やし切れなかった点。
- 明日は:最良VWAP×複数CEX一貫適用+TTL+0.5s+時間帯集中で、AUTO→GOを 0%→30% まで引き上げ、最初の5本に到達する。
オンチェーン精算スナイプbot:作業ログ
概要
- 目的:REPLAY基準で KEEP≥60% / p95≤350ms を達成し、その後 drop≤10% を“測れる状態”へ。
- 現在地:p95=300ms 達成、KEEP=48%(16%→48%へ大幅改善)。ltK(insufficient_kinds)支配が残課題。
1. 基盤・計測の是正(統一・可視化)
- 設定一元化:
runtime.RにALIGN_MS / KEEP_CONFIRM_MS / JOIN_WINDOW_MS / TTL_MS / KEEP_CONFIRM_STEPS_MS=[KEEP, KEEP*2]を集約。 - 時刻正規化(sec/µs/ns→ms)& ALIGN依存へ統一。
align_ms_currentを/metricsで公開。 - REPLAYの flush を十分未来へ変更:
future = last_ts + KEEP×2 + ALIGN + 200ms。 - Registry統一:すべて
get_registry()/self.m経由に修正し、default混入を排除。
効果
- p95 が 1000ms固着→300ms へ正常化(ALIGN=300ms)。
2. KEEP確認回路の可視化・安定化
- 確認ジョブ系メトリクス追加:
confirm_(scheduled|processed|kept|faded)_total / heap_depth / next_at_ms。 - exactly-one 設計:JOIN未成立/KEEP失敗の各出口で miss 理由を必ず1つ
inc()。 keep_wait_ms(JOIN→KEEP遅延)/fade_alive_kinds(最終確認での生存種)を追加。
実測
confirm_scheduled=confirm_processed、kept+faded ≈ processedを確認(正常動作)。
3. 片翼死の直叩き(fade対策)
- 弱条件 refresh 実装(毎tick/最小間隔80–100ms):FIREは据置、REFRだけ1クリック緩和。
- 心拍パルス 実装:JOIN→KEEPの間、80–100msごとに missing側だけ refresh(JOIN水増しなし)。
実測
confirm_pulse_total大量、confirm_faded_total → 0、fade_alive_kinds偏重解消。- KEEP 16% → 48% に改善。
4. ltK(K=2未達)への対処(K到達率↑)
- FIREしきい 1クリック緩和(段階的):
- 例)
OI_Z: 1.5→1.4 / BBO_COLLAPSE: 3.5→3.0 / L2_THIN: 0.72(据置)/ BURST_BP: 7(据置)
- 例)
- 以後の攻め案(必要時):
L2_THIN: 0.72→0.75 / BURST_BP: 7→6
実測
- JOIN増・ltK比率の低下を確認(KEEP=48%まで上昇)。
- ただし
insufficient_kinds≈886がなお支配的 → さらなる1クリックが必要。
5. 窓/TTL(現行セット)
ALIGN_MS=300 KEEP_CONFIRM_MS=450 JOIN_WINDOW_MS=700 TTL_MS=3000 REQUIRE_PAIR=0 REPLAY_MODE=0
- ルール:TTL ≥ KEEP_CONFIRM×2 + 100ms を厳守。
keep_wait_msピーク(400–600ms/900–1200ms帯)と矛盾なし → 現状据置で良好。
KPIスナップショット(最新)
- p95:300ms(ヒスト算出/ALIGN=300)✅
- KEEP:48.0%(16%→48%)↗️
- fade:0件(
confirm_faded_total=0)✅ - ltK:
insufficient_kinds≈886❗(残課題)
次の一手(1クリック)
- 目標:KEEP 48% → 60%+(p95は維持)。
- 実施:FIREを1クリック(K到達率↑、質は維持)
OI_Z: 1.4→1.3/BBO_COLLAPSE: 3.0→2.8〜3.0- (必要なら)
L2_THIN: 0.72→0.75/BURST_BP: 7→6
- 観測:2行ヘルス+
insufficient_kinds / keep_wait_ms / fade_alive_kinds / confirm_*を5分ループで確認。 - ガードレール:p95>350ms or keep%<50% になったら直近変更をロールバック。
その次:drop計測ON(影/実 4カウンタ)
shadow/live_exec_attempt_total、shadow/live_fill_success_totalを配線 →fill_rate_shadow/liveとdrop = 1 - (live/shadow)(目標 ≤ 10%)を常時計測。
オンチェーン精算スナイプ:達成度
ざっくり結論:達成度は ~56%(私の目安) です。
「動く・測れる」は整い、p95=300msもクリア。一方でKEEP=48%(目標≥60%)と、drop≤10%の計測/EVゲートが未達。
いまの達成度(重み付きざっくり採点)
- 検知/シグナル実装(20)… 14/20(主要シグナル+整流OK)
- 合議品質(20)… 11/20(KEEP 16%→48%へ大幅改善、目標60–90%まで一歩)
- レイテンシ(15)… 12/15(p95=300ms:ALIGN依存で安定)
- 執行品質/ドロップ(15)… 2/15(shadow/live dropの4カウンタ未配線)
- 会計/EVゲート(10)… 3/10(日次EV→昇格ラインは未運用)
- 監視/可視化(10)… 8/10(confirm系・keep_wait・fade分布まで可視化)
- 安全/運用(10)… 6/10(冪等化・ガード類OK、ゲート最終確定はこれから)
合計:56/100
できていること ✅
- p95=300ms 達成(ALIGN=300ms依存で正常)
- KEEP=16%→48% まで改善(fade=0に収束)
- 確認ジョブ(予約→処理→保持/失敗)メトリクスで動作が数で証明
- 設定・時刻正規化・Registry統一、測定の基盤は安定
まだのこと ❌
- KEEP ≥ 60%(ltK=886が支配 → K=2到達率の底上げが必要)
- drop ≤ 10% の“計測”そのもの(shadow/live 4カウンタ)
- 手数料込みEV>0の運用ゲート(5営業日連続、MaxDD制御)
すぐ上げるための“次の1クリック”
- FIRE だけを段階的に緩めて ltK削減(p95はALIGNで維持)
- 例:A:OI_Z 1.4→1.3, BBO 3.5→3.0(L2/BURST据置)
- 効果が小さければ B:L2 0.72→0.75, BURST 7→6
- drop 計測 ON(影/実 4カウンタ)
shadow/live_exec_attempt_total,shadow/live_fill_success_total→drop = 1 - live/shadowを常時計測
KPI判定(REPLAY基準):KEEP≥60% / p95≤350ms / insufficient_kinds↓ を満たせば、低ノッチCanaryで drop≤10% を見に行けます。
Go/No-Go の“稼ぐ”基準(再掲)
- KEEP ≥ 70–90%
- p95 ≤ 350–400ms
- drop ≤ 10%(shadow vs live)
- 手数料込みEV>0 を 5営業日連続(MaxDDは許容内)
清算スナイプbot:今日の“筋が悪かった”ポイント(なぜ悪い→どう直す)
- 複数ノブを同時に動かした
なぜ悪い:因果がぼけて、効果検証が遅れる(KEEP%が上がった/下がった理由が不明)。
どう直す:1クリック=1ノブ。A/B(前後)でjoin/keep/keep%/p95/insufficient_kindsを必ず比較。 - パルス/refreshの“対象”が広すぎた(当初)
なぜ悪い:missingでない側も延命→JOIN質が落ちやすい・CPU浪費。
どう直す:missing側限定(JOIN時 alive ∪ 現在 alive ∪ near)− 今alive だけに refresh。 - 窓/TTLをいじり続けた(既に fade はゼロ)
なぜ悪い:ボトルネックは ltK(K未到達)。窓/TTLはもう効かない。
どう直す:窓/TTLは ALIGN=300 / KEEP=450 / JOIN=700 / TTL=3000 で固定。以後は FIRE/REFR/pulse だけ。 - 再生プロセスの不安定運用(ポート衝突・旧メトリクス参照)
なぜ悪い:古い結果を見て判断誤り。
どう直す:1プロセス運用+ 起動順の固定(start_http_server(..., get_registry())→ScoringEngine())+ 強制 flush。 - KPIの“反応速度指標”を見ていなかった
なぜ悪い:パルスやREPRの効き所が分からない。
どう直す:keep_wait_ms と fade_alive_kinds を必ず見る(ピーク帯&最頻値)。今後の窓合わせの根拠に。 - ltKをFIREで削る判断が遅れた
なぜ悪い:fadeが消えた時点で、次のボトルネックは明確に ltK。
どう直す:FIREだけ段階的に緩める(REFR/窓は据置、p95はALIGNで固定)。 - “稼ぐ”直結の drop 計測が後ろ倒し
なぜ悪い:KEEPが上がった瞬間に drop を見始めるべき。
どう直す:keep≥60% 到達直後に影/実の4カウンタ配線(attempt/fill_success)。
明日の“最短”プラン(午前で勝ち筋確認)
0. ルール(固定)
- 窓/TTL:
ALIGN=300 / KEEP_CONFIRM=450 / JOIN_WINDOW=700 / TTL=3000固定 - パルス:80ms、missing側限定 refresh(実装済)
- REFR:毎tick、最小間隔 80ms、近い閾値(実装済)
1. 検証ループ(1クリックずつ)
段階A(保守的) — まずこれ
- FIRE:
OI_Z 1.4→1.3、BBO 3.5→3.0(L2/BURST据置) - 再生 → 2行ヘルス+内訳
- 合格:
keep≥60% / p95≤350ms / insufficient_kinds↓→ drop配線ONへ - 未達:段階Bへ
- 合格:
段階B(攻め) — Aで伸びが小さければ
- FIRE:
L2_THIN 0.72→0.75またはBURST 7→6(一度に片方だけ) - 再生 → 同じKPI判定
- p95>350ms or keep<50% に落ちたら直前をロールバック
いずれも 1クリック=1ノブ を厳守。A/B前後をCSV出力すると迷いません。
2. 合格したらすぐ drop 計測ON(影/実4カウンタ)
shadow/live_exec_attempt_total、shadow/live_fill_success_total- レポート:
fill_rate_shadow/live、drop = 1 - (live/shadow)(目標 ≤10%)- 2行KPIに
dropを追記(明日中に“測れる状態”へ)
明日の作業チェックリスト
- 起動順:
http_server→ScoringEngine(Registry統一) - セット固定:
ALIGN=300/KEEP=450/JOIN=700/TTL=3000 - 段階A FIRE 1クリック → 再計測
- 合格 or 段階B FIRE 1クリック → 再計測
- すぐ
drop4カウンタ配線 - 2行ログ+
insufficient_kinds+keep_wait_msピーク+fade_alive_kinds最頻値を保存
成果目標(明日中)
- KEEP ≥ 60%(p95は維持)
- drop 計測ON(影/実)
- 以降:EVゲートへ
短く言えば、**“FIREだけ一段ずつ”**が明日のコア作業です。
ショート系bot:作業ログ
0) サマリー
- ゴール:24h Testnet Canary → α判断
- 進捗:/metrics 集約完全復旧、CB表示の二重化(真実値agg)、数量ゼロ丸め根絶、Canary Smokeのtaker ping実装、発注系4カウンタ導入。
- 残タスク:実 fill の安定発生(EVメトリクス通電)※IOC待機/価格/size or Market pingで即解決可
1) 計測・集約まわり(復旧〜強化)
実装
metrics-serveを symlink/tmp/bsb_mp/current集約に変更(env→import順序を厳守、WSGIでregistry=明示)。- epoch切替:起動時に
run-<ts>を生成 →currentに相対symlinkを張替え。 - ジャニター:stale PID を
mark_process_deadで定期掃除(手動metrics-janitor --ttl-secも可)。 - metrics-sanity で aggregated registry の中身を直検査できるように。
- CB真実値:JSON直読の
short_circuit_state_agg{category}を serve 側 Collector で追加(mp残骸に非依存)。
検証・結果
mini_counter_totalが /metrics に出現 → 集約復旧 OK。short_req_ack_ms_* / short_cancel_ms_*の bucket/sum/count 出現を確認(dryrun 10本)。- CBドリル:
error-sim → health-sim-recoverで 2→1→0 を/metricsと JSON の両方で整合。- ダッシュは
short_circuit_state_aggを既定に。
- ダッシュは
2) 収益メトリクスと可観測性(増強)
実装
- 収益メトリクス(EVの分解と集計)を配線:
short_ev_bps_total|_count,short_trades_total,short_win_trades_total,- スリッページ分離:
short_slip_cost_bps_total(max(slip,0)),short_price_improve_bps_total(max(-slip,0))
- 発注系4カウンタ(ゼロ詰まりの切り分け用):
short_orders_sent_total,short_cancels_total,short_reject_total,short_fills_total
- 数量ゼロ丸め対策:
qty_from_notional(price, min_notional, min_qty, step)を新設(ceil系+min強制)。 - Canary Smoke拡張:
--interval-sec,--duration,--taker-every N,--min-notional-usdt- taker ping(IOC or Market)で確実に fill を狙える経路を追加
検証・結果
- 4カウンタの テスト記録:
orders_sent_total/cancels_total/fills_totalが /metrics に出現(動作OK)。 - 数量:
min_notional=50指定で BTCUSDT qty≈0.001に量子化、0丸めなしを確認。 - EVメトリクス:fill 未発生時は
ev_bps_count=0(想定どおり)。
3) Canary / Gate / ENV
実装
load_settings()経由で ENV オーバーライドを適用(CANARY_ENABLED=true,CANARY_RATIO,MAX_NOTIONALなど)。- Canary gate の“サンプリング5%”に詰まるケースに備え、デバッグ時は
CANARY_RATIO=1.0で通す手順を整理。
検証・結果
preflightOK、canary-smoke実行・ループ稼働(post_only→即cancel と taker ping が選択可)。
4) いまの指標スナップ(代表的なものだけ)
- 発注系:
orders_sent_total↑,cancels_total↑,reject_total=0,fills_total=0(=まだ実 fill 未発生) - レイテンシ:
short_req_ack_ms_* / short_cancel_ms_*が蓄積(dryrun/Smokeで確認済) - CB:
short_circuit_state_agg == 0(平常時)
5) いま残っている詰まり(1点)
- 実 fill が未発生 → EV系が動かない
- 有力因:IOCの置き方/待ち方/サイズ あるいは 約定レポート待機(WS/REST)未配線
- 切り分けに
short_ioc_timeout_total{mode,symbol}(未実装なら追加)を推奨- 発注は通るのに fill/done が返らない場合に増える
6) 次の一手(10〜20分でEVを動かす)
python -m src.cli canary-smoke --symbol BTCUSDT \ --duration 120 --interval-sec 10 \ --taker-every 1 --min-notional-usdt 50 --force-market
- 上記ワンライナーででMarket ping で先に1件 fill を作る
→/metrics:short_fills_total>0,short_ev_bps_count>0を先に確認 - IOC に戻して継続
- 価格:SELLは best_bid - 1tick(
floor_to_tick) - キャンセル/置換禁止(IOCは1発完結)
- 2.0s待機で
await_fill_or_done()(WS or 200ms×10 REST)
- 価格:SELLは best_bid - 1tick(
- 10分Smoke(コスト最適化)
--taker-every 6(1分に1回 taker)へ戻す- Go判定:
EV_bps_avg > +3&win% > 55%&reject < 1%&CB==0
以降、比率は 0.02 に戻して 24h Testnet Canary へ。
7) 追加で入れておくと楽な計測
short_ioc_timeout_total{mode,symbol}(Counter):IOC待機のタイムアウト可視化- 発注ログ(taker経路のみ):
price / qty / orderId / tif / elapsed_msを1行
8) DoD(このフェーズ)
/metrics非空(bucket/sum/count 蓄積)short_fills_total>0、short_ev_bps_count>0(EVが動き出す)- 10分スモークで Go判定クリア
- 24h Testnet Canary へ移行
ショート系bot:達成度
約 50%(±10%)
内訳(目安)
- 計測・信頼性基盤:90%
multiprocess集約の復旧、CB永続化+_agg、ジャニター、収益メトリクス配線、4カウンタ追加、数量ゼロ丸め根絶まで完了。 - 執行性能(短時間):65%
req→ack/cancel のヒストグラム取得は安定。24h連続SLOは未評価。 - 実約定&EV計測:20%
送信/取消/拒否は記録OKだが、実fillが未発生=EV_bps系が未通電。 - 24h Testnet Canary:10%
直前まで準備完了。スモークでEV>0確認→24hが未実施。 - 収益実績:0%
実PnL/EVの連続実績はまだ無し。
いま足りないもの(上げ止まり要因)
- 実fillの安定発生(IOCの価格・待機・サイズ or Market ping)
- EVページの通電(
ev_bps_total/countが実トレードで伸び始めること) - 24h連続SLOの実測(
req→ack p99<250ms / cancel p99<300ms / reject<1% / CB=0)
60%へ上げる最短手順(今日〜明日)
- Market ping(確実に1件fill) →
short_fills_total>0&ev_bps_count>0をまず作る - IOC経路で継続:SELLは
best_bid-1tick、キャンセル/置換禁止、2.0s待機 - 10分スモーク(taker-every=1→6):
Go:EV_bps_avg>+3&win%>55&reject<1%&CB=0 - 24h Testnet Canary:比率0.02で連続SLOとEVを検証
ここまで通せば 達成度は60〜65%、EV>0の連続実績が乗り始めた段階で70%台に入ります。
ショート系bot:本日の筋悪ポイント
きょうの動きを“稼ぐ最短経路”基準で振り返ると、筋が悪かった(回り道になった)点は主に5つです。明日の改善アクションもペアで置きます。
1) 「fillが出るか」を最初に確定しなかった
- 筋が悪い理由: EV系は約定が起きない限り永遠に0。にもかかわらず、IOCの置き方/待機/サイズの検証より前に周辺を整え続けた。
- 明日の改善: 最初の1件をMarketで必ず約定させてEV配線を確定→その後にIOCへ戻す。
- 実行例:
python -m src.cli canary-smoke --symbol BTCUSDT \ --duration 120 --interval-sec 10 --taker-every 1 \ --min-notional-usdt 50 --force-market
- DoD:
/metricsでshort_fills_total>0、short_ev_bps_count>0が増える。
2) IOCで“置く/待つ/サイズ”の3点セットが未完了
- 筋が悪い理由: SELL IOC は best_bid−1tick で置く・置換/キャンセル禁止・2.0s待機 が三種の神器。どれか欠けると fill しない/検知できない。
- 明日の改善: 下3点を一気に固定。
- 価格:
ioc_price = floor_to_tick(best_bid - tick, tick) - 置換/キャンセル: IOC経路では一切呼ばない
- 待機:
await_fill_or_done(timeout=2.0s)(WSなければREST 200ms×10)
- DoD: Marketを外しても
short_fills_totalが増える/ioc_timeout_total==0付近に収束。
- 価格:
3) サイズ検証を早めに固定しなかった
- 筋が悪い理由:
min_notional/step/min_qtyを満たさず qty=0 へ丸め→「送ってるのに刺さらない」と誤解。 - 明日の改善: qty_from_notional() を IOC/Market 両方で使用し、最初は
--min-notional-usdt 50に固定(BTCUSDT, step=0.001想定で qty≒0.001)。- DoD: ログに
spec: tick, step, min_qtyとCalculated qty: ...を1行出し、qtyが0/未満にならない。
- DoD: ログに
4) “返事が来ていない”を測る指標がなかった
- 筋が悪い理由:
orders_sent↑ & fills==0でも、rejectなのか、report未到達なのかが判別不能で時間が溶ける。 - 明日の改善:
short_ioc_timeout_total{mode,symbol}(Counter)を追加し、待機満了時に必ずinc。- DoD:
- rejectなら
short_reject_total↑ - 未到達なら
short_ioc_timeout_total↑
→ 根因が1分で判別できる。
- rejectなら
- DoD:
5) 安全運用の切り替えを明示せずに回した
- 筋が悪い理由: デバッグで
CANARY_RATIO=1.0を使ったまま遷移しがち。事故時に露出が大きい。 - 明日の改善: デバッグ→運用を明示切替。
- デバッグ(最初のfill確認):
CANARY_RATIO=1.0,--force-market - 検証(IOCチューニング):
CANARY_RATIO=1.0,--taker-every 1 - 運用開始(コスト最適):
CANARY_RATIO=0.02,--taker-every 6
- DoD: 切り替え直後の
/metrics4行(orders/fills/reject/EV)を残す。
- デバッグ(最初のfill確認):
明日の実行チェックリスト(30–60分でOK)
- Market ping(fill発生の確定)
- 期待:
short_fills_total>0,short_ev_bps_count>0
- 期待:
- IOC固定(best_bid−1tick/置換キャンセル無し/2.0s待機)
- 期待: Market外しても
fills_totalが増え続ける
- 期待: Market外しても
- サイズ
--min-notional-usdt 50(qty_from_notional())- 期待: qtyログが常に
>= min_qty
- 期待: qtyログが常に
- 時系列4行を保存
curl -s :9523/metrics | grep -E 'short_(orders_sent|fills|reject|cancels|ioc_timeout)_total'
curl -s :9523/metrics | grep -E 'short_(req_ack|cancel)_ms_(bucket|sum|count)' | head
curl -s :9523/metrics | grep -E 'short_(ev_bps_total|ev_bps_count|trades_total|win_trades_total)'
curl -s :9523/metrics | grep -E 'short_circuit_state_agg{category="network"}'
“やめること”メモ(最短経路を守るために)
- REPLAY/インフラの磨き直し先行(fill未確定のまま)
- IOCでキャンセル/置換を混ぜる(fill直前キャンセルの温床)
- 小さすぎる notion(qtyが0に丸められる)
- 板staleness無視(1s超は再取得)
この4点(Marketで1件→IOCで継続→サイズ固定→タイムアウト可視化)を先に通せば、EVメトリクスが動き始め、明日中に「+3bp超/10分スモーク」まで持っていけます。