Bot 開発ログ

🛠️開発記録#285(2025/8/20)本日の開発ログ

今日は基盤を育てつつ開発の方針も根本から見直すこともした日でした。

“稼げるか”証明が私の現在の課題で、この部分が足を引っ張ってbotの開発が目標値の30〜40%程度の達成度になっています。

これらのbotの最小Liveを回してEV>0を証明するまで、全体であと3〜6週間程度はかかる見通しなので、引き続き他の戦略を実行するbotの開発も継続して、使える武器を増やしていきます。

MMbot:開発ログ&サマリ

  • できていること
    • Exporterを**単一HTTPサーバ(MMBotHTTP/1.0)**に統一。/metrics 稼働、/control(enable/disable)200応答
    • KPI設計と実装の整備mm_ev_order_attempt_total / mm_ev_order_total(ACK)/ mm_ev_reject_total語義分離完了。
    • レイテンシ計測の基盤mm_lat_request_to_ack_seconds / mm_lat_total_seconds / mm_cancel_rtt_seconds を追加。
    • ビルド/環境情報mm_build_info{env,sha,base} 露出。
    • UserStream(ListenKey取得+WS接続・二段フェイルオーバ、fill捕捉)を実装しRunnerに統合。
    • ドキュメント/方針の転換:**常時パッシブMM→ゲーティッドMM+反転/裁定(二刀流)**へ。
  • 詰まっていること(ブロッカー)
    1. ネットワーク:ホストでも https://api.binance.co.jp/api/v3/timetimeout(上位FW/ISPの443 egress制限)。
    2. 監査ログ/metrics のACCESSは出るが、/controlログ可視が不安定(機能は200応答)。
    3. 実データ:上記①のため Canary未通電段別ヒストはBOOT以外のサンプル未採取、UserStream動作も未検証。
  • 今日のゴール
    **「1本通す→計測→止める」**を確定させる。= 443疎通(code:200)→ place_canary → 段別ヒスト増分 → /am-webhook 停止。

1. タイムライン(主要イベント)

  1. 初期不具合の収束
    • -2014 API-key format invalidGlobal→Japanエンドポイント混在、API鍵未設定を解消。
    • PYTHONPATHの実行パス齟齬(/app/src vs /app/mm_bot)/古いイメージ参照ProcessLockを解消。
  2. Exporterの統一
    • prometheus_client.start_http_server 依存を廃止し、ThreadingHTTPServerで /metrics /control /am-webhook を一元
    • attach_runner(self)Runnerインスタンス直参照を保証。
  3. /control の 405解消 → 200応答
    • @api_route("/control", methods=["GET","POST"])→のち単一サーバ実装へ移行。
    • enable/disable の理由ログ/カウンタは配線済み。
  4. KPIの語義修正(重要)
    • mm_ev_order_attempt_total:送信試行回数
    • mm_ev_order_totalACK成功のみ
    • mm_ev_reject_total:拒否/例外
      → 以前の「送信時に order_total++」をACK後に限定
  5. 観測・レイテンシ基盤
    • ヒストグラム:request→ack / total / cancel_rtt を追加。
    • mm_build_info{env,sha,base} 露出。
  6. UserStream 実装
    • JP RESTで ListenKey、WSは wss://stream.binance.co.jp/ws → 失敗時 wss://stream.binance.com:9443/ws の二段接続。
    • executionReport(TRade)で mm_ev_fill_total、PnL器(fees/spread)へ加算。Runnerへ統合。
  7. 戦略の刷新
    • 常時パッシブMMをやめ、SpreadExcursion gate+短TTLAGMMと、反転クォート BRQの二刀流へ転換。
    • Go/No-Go基準(Paper 24–48h:EV>0 / Fill≥35% / Reject≤3%)を確立。

2. 現在のシステム構成(抜粋)

  • コントロール/control(POST):enable_live / disable_live / place_canary
  • メトリクス:Prometheus pull(8080),主なメトリクス
    • 制御mm_control_actions_total{action=...} / mm_status_new_orders_enabled
    • KPImm_ev_order_attempt_total / mm_ev_order_total / mm_ev_reject_total / mm_ev_fill_total
    • PnL(器)mm_pnl_components_total{kind∈[fees,spread,slippage,adverse]}
    • レイテンシmm_lat_request_to_ack_seconds / mm_lat_total_seconds / mm_cancel_rtt_seconds
    • ビルドmm_build_info{env,sha,base}
  • 停止:Alertmanager → /am-webhookdisable_live(ログ+カウンタ)

3. 完了タスク / 未完タスク

完了

  • Exporter統一(MMBotHTTP/1.0)/Runner attach
  • /control 機能(200応答)
  • KPI語義分離(attempt/ack/reject)
  • レイテンシ・ビルド情報の露出
  • UserStream 実装+Runner統合(接続ロジック・二段WS)
  • 方針刷新(AGMM+BRQ)とドキュメント反映

未完(ブロッカー含む)

  • ネットワーク疎通:ホストでも api.binance.co.jp:443 timeout(FW/UTM/ISP)
  • /control監査ログの安定化ACCESS などのログが常に見える状態へ(現状APIは返るがログが無音なケースあり)
  • Canary 1本通電mm_ev_order_totalACKで +1
  • 段別ヒストの“実”サンプル:BOOT以外の増分
  • UserStream 実接続検証mm_ev_fill_total 増分確認

4. 不可解点(原因仮説と一次切り分け)

  1. /control ログ無音
    • 機能は200返却。ログが無音=ハンドラ冒頭のログが出ていない
    • 仮説:do_POST以外(GET)で叩いている/logger.propagate=FalsebasicConfig(force=True)起動順で未適用/grepパターン不一致
    • 一次切り分け:ハンドラ冒頭で print + loggerlog_message() オーバーライド、POSTで打鍵、レスポンスに ts / exporter_id を返す
  2. 443 timeout(ホストでも)
    • Docker以前。上位FW/回線の 443 宛先制限が本丸。
    • 暫定:別回線Cloud VM/(Linuxなら)network_mode: "host" で「まず1本」を通す。
  3. Shadow混入の懸念
    • place_canary 本文はOK。呼び出し前の mode 分岐で早期returnがないか、ランタイムの本文表示で確認済。

5. 受入基準(本フェーズ)

  • /controlPOSTACCESSログ or 理由ログ1行、mm_control_actions_total 増分、mm_control_last_ts_seconds 更新
  • ネット:ホストで https://api.binance.co.jp/api/v3/timecode:200
  • Canarymm_ev_order_attempt_total≥1 かつ mm_ev_order_total≥1(ACKベース)、mm_lat_request_to_ack*_bucket非BOOT増分
  • UserStreamuserstream connected ... がログに1行、mm_ev_fill_total 増分(自然fill もしくは暫定IOCで1件)

6. 改善フロー(直近 60–90分)

  1. 443疎通(最優先)
    • ホストで code:200 を先に出す(別回線/Cloud VM/host network)。
  2. /control ログの可視化
    • ハンドラ冒頭の print+logger、log_message()、レスポンスに ts / exporter_id
  3. Canary 1本 → 段別ヒスト増分
    • ACKで mm_ev_order_total++
  4. UserStream 生存監視
    • mm_health_userstream_up を 0/1 で露出、接続ログを1行。

7. 戦略面の整理(ゲーティッドMM+BRQ)

  • AGMM(Alpha-Gated MM)
    • SpreadExcursion gate:直近15分 p80×1.5 以上だけ ON
    • TTL撤退:500ms(Vol高→700–900ms/低→350ms)
    • 片翼・裏置き:BOB/BOA基準、α弱い時は1–2ティック裏
  • BRQ(Burst Reversion Quoter)
    • 短窓 OFI×微反転で“瞬間”置き → TTL短め
  • 在庫スキューsize = base * (1 - β*inv_ratio)(β≈0.6 初期)
  • Go/No-Go:Paper 24–48h → EV>0 / Fill≥35% / Reject≤3%

8. 付随の運用ベストプラクティス

  • Day-0チェック(起動直後に5秒):
    /control POST=200 / runner_attached / mm_bot path=/app/mm_bot / base_url=co.jp / exchange time=200
  • Exporter単一宣言:メトリクス定義は1ファイルのみ。他は import して .inc()/.set()
  • SecretsはENV/metricscfg_has_keys だけ露出。
  • 再作成コマンドの固定化
    docker compose rm -sf mmbot && docker compose up -d --build --force-recreate mmbot

9. いまの到達度(“稼ぐ”をゴール)

  • 実行/可視化:~70%(Exporter統一・KPI/レイテンシ露出、制御200)
  • リスク/停止:~60%(Webhook→停止OK、監査ログの安定化が残り)
  • EV実証:~20%(疎通ブロックでCanary未通電、実サンプル未採取)
  • 総合≈55%(±5%)疎通を解けば一気に上がる位置。

10. 次の一手(超短縮版)

  1. 回線/上位FWapi.binance.co.jp:443 の許可 → ホストで code:200
  2. /control ログを必ず1行出す(ハンドラ冒頭+メトリクス補助+レスポンス足跡)。
  3. place_canaryattempt/order 増分、段別ヒストの実増分。
  4. UserStream 接続ログmm_ev_fill_total を1件でも立てる。
    → ここまで通ったら、AGMM/BRQの初期パラメータ(bp/TTL/在庫β)をメトリクス分布から即チューニングします。


MMbot:筋悪ポイント&改善ポイント(TL;DR)

  • 最大のズレ:EVが立つ場にいないのに、インフラを先に磨いた」。
  • 戦略の根本: 手数料10bpsのBTC/JPY現物で常時パッシブMMは数学的に負け筋。
  • 実装順序: Canary→Fill→EVの三点セットを先に固めず、Exporterやログ体裁に多くの時間を費やした。
  • 運用判断: 443疎通(回線)を最初に潰さなかったため、「1本通す」までが遅延。

1) 戦略選定の筋が悪い点

  1. 常時パッシブMM(BTC/JPY・maker 10bps・リベート無)に固執
    • なぜ悪い:片側スプレッド<手数料が常態。リベート無しだと期待値はほぼ負。
    • 直し方ゲーティッドMM(SpreadExcursion/反転時のみ)+時間帯/銘柄選別へ。実効メーカー≤2–3bpsまたは**別所(低fee/リベート)**で回す。
  2. ヘッジ前提の設計を持たず在庫に素で晒す
    • なぜ悪い:トレンド局面でadverse選択に飲まれる。
    • 直し方先物/パーペでの瞬間ヘッジを想定(在庫上限を引き上げ、片翼撤退ルールを明示)。
  3. Queue位置/TTL/裏置き(1–2tick back)の初期設計不足
    • なぜ悪い:BOB/BOAで同値競争→fillは悪いときにだけ付く。
    • 直し方TTL≒350–900ms裏置きをαの強弱で切替、Queue滞留時間でサイズ/TTLを動的調整。
  4. 銘柄・時間帯の“勝てる窓”探索が後手
    • なぜ悪い:板構造は時間帯/イベントでEVが大きく変動。
    • 直し方:p80スプレッド・reject率・adverse中央値で運用窓を自動スケジュール

2) 実装・順序の筋が悪い点

  1. “1本通す”単一路線(Canary)が序盤に常設されていない
    • なぜ悪い:ACKもFillも無いと、以降の議論が全部抽象になる。
    • 直し方/control: place_canaryDay-0から常備(LIMIT_MAKER×遠値×最小notional)。
  2. ネット疎通(443)が塞がっているのに、Infraを先に磨いた
    • なぜ悪い:外部APIに届かない限りEV検証に入れない。
    • 直し方最初の5分で curl /time → 200。ダメなら別回線/Cloud VM/host networkに切替えて当日中に通す
  3. Exporter二重構成/ログ体裁に過剰投資
    • なぜ悪い:EVに直結しない。プロは監査OKの最小形に留めて次へ。
    • 直し方単一HTTPサーバ+**メトリクス監査(mm_control_actions_total, last_ts)**で十分。
  4. UserStream(fills)より先に周辺機能へ時間
    • なぜ悪い:Fillが取れないとPnL分解が永遠に進まない。
    • 直し方ListenKey→WS接続を最初週の必達。接続生存Gauge(0/1)で監視。

3) 計測・KPIの筋が悪い点

  1. order_total の語義が“送信時”だった(ACK後じゃない)
    • なぜ悪い:意志決定KPIが嘘になる。
    • 直し方attempt / order(ACK) / reject三分離(修正済は◎)。
  2. 段別レイテンシとCancel RTTが後手
    • なぜ悪い:どこで詰まっているか分からず闇雲に最適化。
    • 直し方request→ack / cancel_rtt / total最初週で入れ、p50/p95/p99の“窓”を決める。
  3. PnL分解の器が遅い(fees/spread/slippage/adverse)
    • なぜ悪い:EVが立っているかの判定ができない。
    • 直し方値は雑でも先に叩く。後で精度を上げる。

4) 運用・プロセスの筋が悪い点

  1. ビルド/ホットパッチが日々ブレる
    • なぜ悪い:再現性が失われる。
    • 直し方その日どちらかに固定/metricsbuild_sha を必ず露出。
  2. PYTHONPATH/実行モジュールのドリフト
    • なぜ悪い:古いコードが動き続ける。
    • 直し方mm_bot path=/app/mm_botDay-0セルフチェックを追加。
  3. Secrets(APIキー)直書きの時期があった
    • なぜ悪い:漏洩リスク→資金喪失。
    • 直し方:ENV/Secretsで管理、cfg_has_keys だけをメトリクス露出。
  4. “完成理解”を求めてタスクを長く抱える
    • なぜ悪い:学習サイクルが遅い。
    • 直し方Go/No-Goの受入を明文化し、通ったら即次へ(例:p99/RPS 非NaNKPI3行Paper 24–48h)。

5) プロの型:改善後の運用テンプレ(毎日90分の核)

  • T+10m:Day-0セルフチェック(/control 200、runner attach、mm_bot path、base_url、/time 200
  • T+20mCanary 1本(ACKで order_total +1、段別ヒストに実サンプル)
  • T+20mUserStream 接続(Gauge up、fill→fees/spread を加算)
  • T+20mAlert E2E(ダミーcritical→disable_live ログ+カウンタ)
  • 残りSpreadExcursion gateTTL撤退24–48h Paperで EV>0/Fill≥35%/Reject≤3% を満たしたら最小Liveへ

6) 2週間の具体ロードマップ(再掲・短縮)

  • Week 1:疎通→Canary→Fill→EV器(fees/spread)→AGMM(SpreadExcursion+TTL)
  • Week 2:BRQ(反転クォート)+在庫スキュー→Paper→Go/No-Go→極小Live

最後に

厳しい言い方をすれば、**「稼げる土俵が整っていないのに、土俵の周り(Exporter/ログ体裁)を磨きすぎた」**のが今回の最大の筋悪です。
土俵=“EVが立つ条件”を先に満たす(手数料・時間帯・銘柄・ヘッジ/ゲーティング)→Canary/Fill/EVの三点セット最小Live
ここに軸を戻せば、開発速度と勝率は一段上がる。次の一報は 「ホスト /time が200」 で。そこから一緒に“1本→EV”まで畳み切る。

CEX/CEX arb bot:開発サマリ

  • 到達フェーズ:Phase 0「比較の正しさ Fix」最終段
  • 技術達成度(システム完成度)85%
  • “稼ぐ”達成度(収益化への到達度)40% ±5%(AUTO→GO=0%のため。ここが上がれば60%まで跳ね上がる見込み)

核心ブロッカー

  • r = dq / cb = 0.802固定(≒ per-SOL 正規化が最終出力 dq まで貫通していない
  • contract_mismatch 未発火(r<0.90でも gross<min に流れている)
  • ログの diag extradiag への取り込み経路に欠落/別経路)

✅ 完了済み(強い土台)

  • 命名統一fx_bp → fx_bps、変数ゆらぎ解消。
  • 統一出口 _emit 復活:落ちないデータ流し込み(EnhancedArbitrageData.from_any())を標準化。
  • 価格正規化の契約定義
    • jup_to_per_sol_usdt(tap, quote, fx) 実装・単体OK(BUY=100.2 / SELL=99.8)。
    • tap別で per-SOL 化(BUY: in_usdc_total/out_sol_total、SELL: out_usdc_total/in_sol_total)。
  • 符号・VWAP side の原則
    • BUY: (CEX_BID − DEX_perSOL) / mid、SELL: (DEX_perSOL − CEX_ASK) / mid
    • BUYはBID、SELLはASKを使用。
  • FSM/ログ/例外耐性:2-hit FSM、from_any()、一貫性チェッカー、詳細ログの器は整備済み。

❌ 未解決(現ブロッカー)

  1. r分布サニティ不合格r_p10=r_p90=0.8020(固定)
  2. 早期ガード未発火r<0.90でも why=gross<min に流れる
  3. diagが空extradiagに反映されていない(ログで diag={}

🔎 技術的診断(なぜ起きているか・疑い順)

H1. _emit の詰め替え/上書き漏れ

  • _emit 内の詰め替えが 古い属性名を参照、またはその後で data["dq"]=80.16 のように上書きしている疑い。
    • 手本: data.setdefault("dq", getattr(q, "dq_per_sol_usdt", None)) data.setdefault("cb", getattr(q, "cb_per_sol_usdt", None)) data.setdefault("mid", getattr(q, "mid_usdt", None)) # 以降で dq/cb/mid を再代入しない

H2. 直帰ルートの混在(_create_opportunity_data 直呼び)

  • 一部コードが _emit() を経由せず直接 _create_opportunity_data() を返しており、
    per-SOL の詰め替えや diag 取り込みを飛ばしている可能性。

H3. Jupiterモックのキーが契約とズレ

  • BUYで out_sol_total ではなく amount_sol など、期待キー名の不一致により jup_to_per_sol_usdt()総額→per-SOLできていない。

H4. 早期ガードが “別分岐の手前/外側”

  • r を計算しても、その直後に別条件で gross<min を返す分岐が先に評価され、
    contract_mismatch の return に到達していない

H5. diag 取り込み欠落

  • _emit 内で data.setdefault("diag", {}) をせず、data["diag"].update(extra) だけだと未初期化で無効になり得る。
    • 手本: if extra: data.setdefault("diag", {}) data["diag"].update(extra)

🧪 即時チェック(3分・ノブは触らない)

  1. dq/cb/mid の最終詰め替えが per-SOL 名になっているか grep -n 'setdefault("dq"' arbbot/strategy/enhanced_arbitrage_detector.py grep -n 'setdefault("cb"' arbbot/strategy/enhanced_arbitrage_detector.py grep -n 'setdefault("mid"' arbbot/strategy/enhanced_arbitrage_detector.pydq_per_sol_usdt / cb_per_sol_usdt / mid_usdt を参照していること。
    → 直後に data["dq"]=...上書きが無いこと。
  2. 直帰ルートの掃除 grep -n '_create_opportunity_data\(' arbbot/strategy/enhanced_arbitrage_detector.py全呼び出しが _emit() 経由になっていること(直呼びはゼロが正解)。
  3. 契約ガードの実在と位置 grep -n 'contract_mismatch' arbbot/strategy/enhanced_arbitrage_detector.pyr = dq_per_sol_usdt / cb_per_sol_usdt直後if r < 0.90 or r > 1.10: return self._emit("contract_mismatch", tap=tap, sym=sym, extra={"r": r, "jup_contract": contract, **jdiag}) があること。
  4. diag 初期化 grep -n 'diag' arbbot/strategy/enhanced_arbitrage_detector.py | head_emit 内で data.setdefault("diag", {})update(extra) の順になっていること。
  5. モック契約のキー名
    • BUY:in_usdc_total / out_sol_total
    • SELL:out_usdc_total / in_sol_total
      → これ以外(amount_sol など)なら生成側で上記キーにコピー

📈 現在KPI(最新)

  • AUTO→GO:0%(目標 ≥30%)
  • WHYトップgross<min 100%
  • unit_mismatch:0%(目標 ≤3%)
  • miss_2nd:0件(未到達のため。gross解消後に評価)
  • r分布p10=p90=0.8020(不合格)

🎯 次の一手(コード1点だけ)

  • _emitdq/cb/mid 詰め替えdiag初期化を、上記の「あるべき姿」に統一
  • detect_opportunity 内で contract_mismatch ガードを r 計算直後に配置
  • _create_opportunity_data直呼び撤去(全件 _emit 経由に戻す)。
  • Jupiterモックのキー名を契約どおりに揃える(BUY: in+out、SELL: out+in)。

これで r が ±1% に収束し、gross<min 全件 が解消 → AUTO→GO 立ち上がりに入れます。


✅ 受け入れ基準(この順で通過)

  1. r分布合格r_p10 ≥ 0.99 & r_p90 ≤ 1.01
  2. 45分ラン(USオープン±30)AUTO→GO ≥ 30%、WHYに depth/last_look/miss_2nd が現れる
  3. canary最小ロット×5本GO→FILL ≥ 60% & realized_edge_p50 ≥ fees+slip_p75

📒 Run Manifest(再現性)

各ランで保存:

{
  "ts":"<iso>", "git":"<sha>",
  "env":{"NET_EDGE_MIN_BPS":38,"TTL_SECONDS":3.0,"SECOND_WINDOW_MS":1500,"VWAP_MAX_AGE_MS":250},
  "tap":["buy->sell"],
  "dex_norm":"per-SOL(total→/qty)",
  "vwap_side":{"buy":"BID","sell":"ASK"},
  "slip":{"buy":"+","sell":"-"},
  "r_stats":{"p10":0.XXX,"p90":1.XXX},
  "why_top":"gross<min|depth|last_look|miss_2nd",
  "auto_go":0.XX
}

ひとこと

土台は十分強い。 いま止まっているのは “per-SOLが最終 dq に届いていない”ただ一点。
上のチェック&1点修正で r は即合格圏に入ります。

CEX/DEX arb bot開発:筋悪ポイント&改善案

1) モック・ドリフト(Mock ≠ 本番)に時間を溶かした

症状:r=0.802 固定、gross<min全件。Jupiter契約/単位の齟齬を何度も後追い修正。
なぜ悪い:本番の契約(総額→per-SOL、decimals、slip向き)に厳密準拠しないモックは“別ゲーム”。そこに合わせ込むほど実運用から離れる。
Fix(次ループ)

  • 契約→正規化→エッジ”のゴールデンテストを先頭に置く:
    BUY: in_usdc_total/out_sol_total * fx == dq_per_sol_usdt、SELL: out_usdc_total/in_sol_total * fx == dq_per_sol_usdt をCIで落とす。
  • モックはMarketBaselineの単一baseをCEX/DEXで共有、slip向き(BUY:+/SELL:−)だけ可変。これ以外の挙動は禁止

2) 早期不変量を“ゲート”にせず、後段で調整した

症状:r分布不合格のままTTL/SECOND_WINDOW/NET_EDGEなどを触りがち。
なぜ悪い:比較が間違っている状態でタイミングや閾値を調整しても因果が崩れる。
Fixゲート順を固定

  1. r=dq/cb ±1% 合格(BUY=BID/SELL=ASK/符号/FX一回)
  2. AUTO→GO≥30%(ここで初めてTTL/SECOND_WINDOWを触る)
  3. GO→FILL(canaryで実滑り確認)

3) 多ノブ同時調整

症状:TTL/SECOND_WINDOW/NET_EDGE/VWAP間隔/slippageを並行で変更。
なぜ悪い:効果検証が不可能になり、再現もできない。
Fix45分=1ノブ。Run Manifestに1行で「変更ノブ→予想→結果」を残す。

4) 統一出口を外してデータが壊れた

症状_emitを外して _create_opportunity_data 直呼び → diag空、必須フィールド不足、dqが総額に戻る。
なぜ悪い:観測の一貫性が消え、“どこで壊れたか”が追えない。
Fix全ルート _emit() 経由に統一(中で from_any()diag.setdefault({})dq/cb/mid=per-SOL 詰め替え)。

5) tap非対称(BUY→SELLだけ)で検証が偏った

症状dex_buy_cex_sell 片側中心、SELL側ASK/符号の回帰テスト不足。
なぜ悪い:半分のバグ(符号・side・slip向き)が露見しない。
Fix両tapの不変量テストをCIに追加(BUY: BID−DEX、SELL: DEX−ASK)。

6) NET_EDGEを先に緩めた

症状:38→35bpsなどの調整を“比較未合格”の段階で検討。
なぜ悪い:ノイズを拾い、負けトレードが混入。
Fix閾値は最後。まず“正しい比較”と“AUTO→GO立ち上げ”。

7) 動的調整を早期導入

症状:DynamicAdjusterを“基礎が揺れている”段階で動かそうとした。
なぜ悪い:誤ったフィードバックで発散する。
Fix:動的調整は安定後(Step-B以降)の微分だけに使用。

8) 収益化視点の“面取り”が遅い(戦略選定)

症状:SOL/USDTの常時CEX/DEX裁定に固執。
なぜ悪い:2025年のメジャー銘柄常時裁定はHFTの土俵。個人が勝てるのは“短時間×ニッチ”。
Fix(戦略)

  • 時間帯×銘柄の細分化:USオープン±30/ルート再計算直後/薄板アルト。
  • イベント駆動の瞬間エッジ:Jupiterのルート更新・プール再均衡・CEXメンテ明け。
  • サイズ固定の薄取り:$10-$25のVWAPに合わせたマイクロロット多数回
  • 両面化:CEX maker(手数料優遇)× DEX taker など、費用構造に依存した組み合わせを試験。
  • 銘柄横断のαマップ(spread_raw – fees – slip_p75) のp50を銘柄×時間帯ヒートマップで可視化→“勝てる面”に集中。

9) 実弾 canary が遅い

症状:モックで長く滞留。
なぜ悪い:実世界の滑り/約定/キュー待ちをログで体感しないと、いつまでも机上。
Fix最小ロット×5本をUSオープン±30で毎日。pred/quoted/realized_edge_bps を同一行に出す。

10) 事前サニティの自動化不足

症状:r分布合格・契約ガード・VWAP side一致を毎回手で見る。
なぜ悪い:人的ミスが出る。
Fixプリフライトで落とす

  • r_p10>=0.99 && r_p90<=1.01 でない→即Fail
  • BUYで vwap_side=BID / SELLで ASK でない→即Fail
  • diag.jup_contract ∈ {buy_total, sell_total} でない→即Fail

戦術→明日の動き(筋の良い回し方)

  1. r分布を必ず合格(_emit詰め替え・直帰撤去・契約ガードの位置を修正)
    • 合格まで他ノブ禁止
  2. 45分=1ノブAUTO→GO≥30% を立ち上げ
    • WHY=depth → VWAP間隔 100→80ms(CEXのみ)
    • WHY=last_look → age上限 250→200ms
    • WHY=miss_2nd → プリフェッチ(それでもp95>2000msなら窓+200ms)
  3. canary最小ロット×5本GO→FILL≥60%realized_edge_p50 ≥ fees+slip_p75 を確認
  4. 面の拡張:tap両側・もう1銘柄・時間帯横展開(αマップで決定)

まとめ

  • 技術土台は強い
  • 筋が悪かったのは:モック最適化・多ノブ同時・不変量をゲートにしなかった点。
  • やることは単純:契約→正規化→r合格→1ノブ→canary。
    ここを守れば、AUTO→GO 0% → 30%台は届く。その先で戦略選定(ニッチ×時間帯×サイズ)にリソースを回せば、“個人が勝てる面”に乗れる。

ショート系bot開発:進捗サマリー

  • 計測・基盤:multiprocess集約と /metrics サーバは復旧。EVは Summary一本化short_ev_bps_(sum|count))に移行済み。
  • EV配線:Δ(WS/REST)→ 注文終端(FILLED/EXPIRED/CANCELED)で VWAP→EV算出まで動作。ネットEV(taker手数料控除)も導入済み。
  • 執行req→ack ≈ 10–11 ms、reject=0、CB=0。
  • FFL/スモーク:FFLは3/6 fill(50%)まで改善した回あり。ただし 10分スモークは 1/60〜39/136 と ばらつき大
  • EV実測raw_ev_bp ≈ +0.034(=0.034 bps)だが 手数料7.5 bps控除後は ≈ −7.47 bpsネットでマイナス
  • 前段ゲート:L2流動性ゲート(cum bid ≥ qty)は導入。マイクロ構造ゲートは一時OFF(L2モックが対称で信号0のため)。

いま“できている / 良い”ところ

  • EVの単位・定義が是正(Summary、bps、ネット控除)
  • 注文ライフサイクルの観測:ACK/DONEログ、short_orders_done_total{status}
  • L2健全性ログ:IOC直前に K枚の集計・microprice・age・src を出力
  • FFLルーチン:セッション冒頭の「Market1→IOC×5→3指標」導入

不可解/筋の悪い点(Must-fix)

  1. Fill率の分母が歪む
    • ioc_timeout_total=0 でも fillが低い回があるのに、EXPIRED(0fill) が分母に入っていない瞬間がある。
    • 現状 short_skip_total{reason="no_qty"}(=置く前スキップ)と、「置いたが約定0でEXPIRED」 が混同されている。
      対処short_expires_nofill_totalDONE時(executed=0)で必ずinc。Fill率は
      fills / (fills + expires_nofill + rejects) に統一。
  2. L2モックが対称(sum_bidK=sum_askK=1.000固定)
    • その限り、imbalance/micropriceは常時0付近 → マイクロ構造ゲートが機能しない
      対処:Testnet実板 or 変動を持つシムへ切替えるまで マイクロゲートはOFF継続。L2ゲート(cum量)だけで運用。
  3. EV期待値の目標設定
    • ネットで +3 bps を狙うには raw_ev_bp ≳ 10.5 bps が必要(手数料7.5 bps控除を踏まえる)。
    • 現状 raw ≈ 0.034 bps → 桁が足りない
      対処“置く前に勝てる瞬間だけ撃つ”密度をさらに上げる(下の次アクション)。
  4. /metrics が空になる瞬間がある
    • PROMETHEUS_MULTIPROC_DIR の未設定起動、epoch張替え直後に子が別DIR参照、で空になり得る。
      対処親子とも import前にENV設定、epoch張替えは os.replace() の原子的置換、janitorは古い.dbのみ掃除。

次の一手(30–60分でやること)

目的:Fill率の“真値化”+ 置く前の勝率を底上げ → ネットEVの赤字幅を縮小。

  1. メトリクスの締め
    • short_expires_nofill_total{mode,symbol}(DONEで executed=0 のときinc)
    • ダッシュの Fill率を fills / (fills+expires_nofill+rejects) に差し替え。
  2. 前段ゲートの再調整(シンプルに2本)
    • L2流動性ゲートcum_bid(sell_price) ≥ 1.0 × qty(まずは 1.0 に緩和、統計が安定したら 1.2 に戻す)
    • クロス幅初手2tick固定 → 直近30本の timeout率で 2↔1tick 自動切替(>30%で2、<10%で1)
  3. サイズのゼロ化を撲滅
    • qty_from_notionalsafety係数=1.01 を維持、ログに calc_qty / step / min_qty / min_notional を毎回出す。
    • skip{reason="no_qty"}expires_nofill は別モノとして並列で追跡。
  4. 10分スモーク再測定(Go/No-Goゲート厳守)
    • Gofills/(fills+expires_nofill+rejects) ≥ 0.5avgEV_net > +3 bpstimeout/orders < 0.1
    • No-Goなら:
      • Fill率<0.5 → cross=2tick継続+L2しきい値を 1.0→0.9 に一時緩和
      • avgEV_net≤0 → cooldown導入(連続負けで 3×interval 休止)
  5. 記録の型を固定(レビュ映え&再現性)
    • 4本スナップに expires_nofill を追加。
    • FFL結果(fills>0 / ev_count>0 / staleness≤300ms)を毎セッション先頭に保存。

48–72時間の見取り図(個人でも勝ち筋を太くするために)

  • Phase 1(〜明日):上の 1)〜4) を回し、Fill≥50% を安定させる。
  • Phase 2(明後日〜):L2が“生きた”データ源に切り替わり次第、マイクロ構造ゲートを段階導入
    • 最初は sell_flow_ratio_200ms > 0.60 の単独ゲートから(逆行回避に効く)。
    • 次に imbalanceK、microprice を加えて AND にする(誤発注をさらに削る)。
  • Phase 3EV完全体の拡張(Funding/借入)+ 時間帯/レジームON/OFF
    • 例:高ボラ・イベント直後はOFF/縮小、定常帯に集中。
  • Phase 4AB常時mode="cross1" vs "cross2")で7日ローリングの勝ち腕選択。

ひと言でいうと

  • Fillの“分母”を正しく計る → 置く前ゲートで“負ける瞬間”をさらに間引く → net EVをマイナスからゼロ近辺へ引き上げる、の順で進めば、24h Canaryへ進む意味のある手応えが出る。
  • いまの raw EV(0.034 bps)は桁不足なので、撃つ瞬間の質を上げる以外の近道はない。

ショート系bot:筋悪ポイント&改善提案

結論から言うと、「1–2tickのIOC Takerで勝つ」前提に時間を使い過ぎ、しかも**“勝てる瞬間だけ撃つ”ためのアルファ設計が後手**になっていました。筋が悪かったポイントは次のとおりです。


戦略選定(根本)

  1. Taker1–2tick狙いはネットで負ける前提
     実測の raw EV ≈ +0.034 bps、taker手数料 7.5 bps → ネット ≈ −7.47 bps
     なぜ悪い:構造的に手数料に負ける。ミクロな優位(イベント/板構造/他会場遅延など)が乗らない限り永遠に赤字。
     直し方Takerは**“何で勝つか”を先に定義**(例:清算/イベント直後、他会場スリッページ伝播、特定時間帯のフロー偏り)。それが言語化できないTakerは切る。短期はメイカー混成軽い裁定合成(先物-現物/他板のミクロ乖離)に軸足。
  2. アルファよりインフラ先行
     Prometheusやmp集約に多くの時間→fillすら出ない期間が長い
     直し方FFL(Market1→IOC×5→指標3点)を毎セッション冒頭で完了しない限り、他作業に行かない“開発ゲート”にする。
  3. モック依存でミクロ構造ゲートが“常時0”
     L2が対称(sum_bidK=sum_askK)→ imbalance/micropriceが常に0→ゲートが機能しない
     直し方:Smoke/CanaryはTestnet実板のみ。モックは単体テスト専用に降格。

実装・計測

  1. EVの単位/定義の取り違え
     0.034を「3.4 bps」と読んだり、SummaryとCounterを二重定義。
     直し方bpsで一本化、EVはSummary1本_sum/_count)。**ネットEV(手数料控除後)**を標準に。
  2. Fill率の分母が歪む
     timeout=0%でもfillが低い回→EXPIRED(0fill)をカウントしていない
     直し方expires_nofill_totalDONE時に必ずinc。Fill率定義=fills/(fills+expires_nofill+rejects)に固定。
  3. “待てば刺さる”誤解
     IOCは即判定。待機を伸ばしても約定率は上がらない。
     直し方:待機は報告収束のためだけ。約定率は撃つ前の条件で上げる(次項)。
  4. 前段ゲートの弱さ/後付け
     置く前の勝率を上げるゲート(L2累積・マイクロ構造・フロー)が遅れた。
     直し方:最低でもL2累積(sellまでのbid量 ≥ qty)+クロス幅自動化を常時ON。ミクロ信号は実板で復帰。
  5. p_ref・orderIdの一貫性崩れ
     p_refの取り直し、orderId不一致、Decimal/float混在、price=0.001バグ…基礎品質にノイズ
     直し方注文ID→p_ref固定→送信→受領IDに束縛の順をテストで固定。Decimal一気通貫を徹底。

プロセス・運用

  1. Smoke不合格なのにCanaryへ進む
     露出が先行して学習効率が下がる。
     直し方数値ゲート厳守fills≥50%かつavgEV_net>+3bpsほか)未達は進まない
  2. リスク上限が口約束
     日次コスト/露出上限の自動停止が曖昧。
     直し方日次bps予算を固定(例 −X bps or −$Y)&自動disable_live。再入場はレビュー後。

いまからの修正方針(現実解によせて)

  • 戦略ミックスを見直す
    • テイカーはイベント/清算/遅延伝播など構造的優位が説明できる場面に限定。
    • 日中の定常帯はメイカー(狭い両建て+在庫管理)や軽い裁定でベースの+3〜5 bpsを作る。
  • 撃つ前の品質を最大化
    • L2累積ゲート(≥1.0〜1.2×qty)+**クロス幅自動化(2↔1tick)**常時ON。
    • 実板が取れ次第、sell_flow比率imbalancemicropriceの順で段階導入(ANDゲート)。
  • 定量ゲートを最上位の意思決定に
    • Smoke Go:fills/(fills+expires+rejects)≥0.5 & avgEV_net>+3bps。未達なら即チューニング、進まない。
    • Canary Go(24h):avgEV_net>+2〜3bps維持+SLOクリア。
  • AB常時・人力チューニング禁止
    • mode=cross1(1tick) vs cross2(2tick) を並走。7日ローリングで勝ち腕のみ残す。

1週間ロードマップ(短く太い勝ち筋へ)

  • Day 1–2:L2累積ゲートとクロス自動化を常時ON、Fill率を**50%**に安定。
  • Day 3–4:実板でsell_flow>0.6をゲート化 → avgEV_netの符号がゼロ超えに乗るか確認。
  • Day 5–7:時間帯/レジームON/OFF(高ボラ・イベント直後はOFF)。並行してメイカー/裁定の最小腕を追加し、ベースEVを底上げ。

まとめ

  • 最大の筋悪は、「手数料に勝てないテイカーでインフラを磨き続けた」こと。
  • 勝ち筋は、「撃つ瞬間の質を前段ゲートで上げる」「構造的エッジが説明できる場面に限定」「メイカー/裁定混成でベースbpsを稼ぐ」。
  • これに数値ゲートの厳守AB常時を重ねれば、個人でも**+3〜5 bps ネット**の現実路線が見える。

オンチェーン清算スナイプbot:開発進捗

🎯 目標(今日~直近)

  • **Round-1(実データ)**を完了:
    KEEP ≥ 60%(連続2ラウンド)/p95 ≤ 350ms/EV/5m > 0 → 採用
    採用後:fill_drop ≤ 10%(60分連続)

✅ できていること(緑)

  • Exporter:9106/metrics 常駐、EV(gain/loss)/REPLAY info/knob_current/invar/req_ack_ms 出力確認済み
  • Registryget_registry()統一(重複/default REGISTRY混在の是正)
  • Dev Prometheus別ポート(:9094) で並走起動、sniper-local UP(既存:9090を汚さず運用)
  • 供給検証8分供給p95 正常算出(rate([5m])満足)
  • フロー:擬似データでRound-1配線(1クリック→A/B→有意性→EVゲート)正常
  • 運用基盤:A/B(ブロック5分交互)/二相探索(粗→細)/EV採用ゲート(SIGNIF ∧ EV/5m>0

🟨 進行中(黄→緑に持ち込み可能)

  • Recording Rules:一部 YAML 構文エラー→分割rules_*.yaml/alerts_*.yaml)で運用可
  • fill_dropNaN(原因:ルール未定義/未読込 or exporterでGaugeを作ってしまった)→ルール算出に戻す

🟥 未了(赤)

  • 実アプリ本体(shadow):安定稼働に未達(起動経路の確定、:9106 一本化)
  • Round-1(実データ):未完(直前のスクレイプ/ルール調整待ち)

🔍 不可解/危険ポイント(原因→処方箋)

  1. Prometheusが :9106 をスクレイプしていない
     → 既存:9090はR/O。:9094 を別起動sniper-local を登録(実施済)。
     チェックcurl :9094/api/v1/targetshealth:"up"
  2. Recording Rulesの構文エラー
     → monitoring/final_monitoring_rules.yaml のline 72付近。
     処方:ルールを rules_*.yaml/alerts_*.yaml に分割し promtool check rules/-/reload
  3. fill_drop をGaugeで出力している(NG)
     → 正しくは Recording Rules で算出
     処方:exporter側の hl_fill_drop_5m を撤去、以下を :9094 にロード:参照yamlファイルは別途掲載。
  4. PromQLの集計軸が不正
     → histogram_quantile(... rate(bucket[5m])) は空になりがち。
     sum by (le) (rate(..._bucket[5m]))(銘柄別は sum by (le,symbol))。
     供給6〜8分 は流す(scrape 5s 前提)。
  5. Exporterの多重化:9106--prometheus-port 8001 併存)
     → :9106 一本化、CLI側 exporter は一旦OFF。start_http_server(9106, registry=get_registry())

以下は、3のyamlファイル。※ live/shadow_*ラベル集合(symbol/side/reg)を一致させること。

groups:
- name: hl-drop
  interval: 15s
  rules:
  - record: hl:exec_drop_5m
    expr: clamp_min(1 - (sum(increase(live_exec_attempt_total[5m]))
                     / clamp_min(sum(increase(shadow_exec_attempt_total[5m])), 1)), 0)
  - record: hl:fill_drop_5m
    expr: clamp_min(1 - (sum(increase(live_fill_success_total[5m]))
                     / clamp_min(sum(increase(shadow_fill_success_total[5m])), 1)), 0)
  - record: hl:fill_drop_5m_by_symbol
    expr: clamp_min(1 - (sum by(symbol)(increase(live_fill_success_total[5m]))
                     / clamp_min(sum by(symbol)(increase(shadow_fill_success_total[5m])), 1)), 0)

🛠 直ちにやること(15–30分)

  • ルール分割→検証→リロード promtool check rules monitoring/*.yaml curl -X POST http://127.0.0.1:9094/-/reload
promtool check rules monitoring/*.yaml
curl -X POST http://127.0.0.1:9094/-/reload
  • fill_drop をルールへ移行(上記 rules を追加)

  • 8分供給→プレフライト
export PURL=http://127.0.0.1:9094/api/v1/query
PYTHONPATH="/Users/xxx/Hyperliquid Sniper" \
PROMETHEUS_MULTIPROC_DIR=/tmp/sniper_mp/current \
python -u scripts/sim_feed_metrics.py &
./scripts/120s_preflight.sh
  • 検証クエリ(NaNが消えたか)
curl -s :9094/api/v1/query --data-urlencode \
  'query=histogram_quantile(0.95, sum by (le) (rate(mm_total_latency_ms_bucket[5m])))'
curl -s :9094/api/v1/query --data-urlencode 'query=hl:keep_rate_5m_fallback'
curl -s :9094/api/v1/query --data-urlencode 'query=hl:fill_drop_5m'

🚀 次の一手(実データ Round-1)

前提p95 / keep / fill_drop が非NaN

  1. 実アプリ shadow 起動→2分待機 :参照コードは下部に記載。
  2. 攻め順決定→1クリック(段階A)
    • ./scripts/ltk_attack_decision.sh(不足時は {"knob":"OI_Z","direction":"down","step":0.1} を暫定)
    • ./scripts/one_click_evaluation.sh ...(5分A/B→CSV)
  3. 採用判定(EVゲート)
    • 採用SIGNIF ∧ PASS+SIGNIF ∧ (hl:ev5m > 0)
    • NS/DEFER:10分窓 or MIN_DENOM↑(300–500)
    • FAILrollback→段階B(L2_THIN↑ or BURST↓ の片方のみ)
  4. 採用後:drop常設 → Canary最小ノッチON(25USD)
    • 60分 hl:fill_drop_5m ≤ 0.10 を監視(銘柄別 hl:fill_drop_5m_by_symbol を併読)
PYTHONPATH="/Users/xxx/Hyperliquid Sniper:$PYTHONPATH" \
PROMETHEUS_MULTIPROC_DIR=/tmp/sniper_mp/current \
python -m src.hyperliquid_sniper.cli trade --mode shadow --enable-metrics --log-level INFO &

📈 KPI & マイルストーン(24h目標)

  • KEEP ≥ 60% …… 連続2ラウンド
  • p95 ≤ 350ms …… 維持
  • EV/5m > 0 …… 2ラウンド連続 → 採用
  • fill_drop ≤ 10% …… 60分連続(全体&ワースト銘柄)

📊 進捗率(現時点の見立て)

  • 基盤構築:100%
  • モニタリング(ルール):90%
  • 擬似データ検証:100%
  • 実アプリ稼働:30%(shadow起動経路の安定化が残り)
  • Round-1(実データ):0% → 本タスクで着手可
  • 総合達成度(“稼ぐ”まで)約75%

🧭 この後ほしい出力(貼れば即 次ノブ指名)

  1. curl -s :9094/api/v1/targets | jq '.data.activeTargets[] | {job,url:.scrapeUrl,health:.health}'
  2. ./scripts/120s_preflight.sh の結果(OK/NGのみで可)
  3. 2行ヘルス(直近ラウンド)+ CSV最新1行drop内訳Top3

一言まとめ

根本(:9106未スクレイプ)は回避済み。 残りは ルール整備と集計軸を直してNaN→実値にすれば、そのまま実データ Round-1に入れる。ここまでの積み上げは十分。あとは1クリック→A/B→EVで採否に集中する。

清算スナイプ:筋悪ポイント&改善提案

P0|直ちにP/Lを殺す類(戦略×実装の根っこ)

  1. エッジ不在のままインフラ先行(Infra ≫ Edge)
  • Why: Prom/Exporter/ダッシュは強いのに、“何で勝つか”の仮説→検証→縮小実弾が後手。学習データ(実 fill/失敗)が貯まらず最適化が空回り。
  • Fix Now: EV先行に完全転換。採用条件=SIGNIF ∧ EV/5m>0を厳守。今日の実データRound-1を影→最小canaryで必ず通す(たとえKPIが荒くても)。
  1. 清算スナイプの“勝ち筋”を楽観視(個人の比較優位を外している)
  • Why: 清算は待ち時間×同着勝負×PO/queue細工の競技。個人で継続して抜くにはキュー最適化/市場条件選別など“味付け”が必須。
  • Fix Now: 銘柄×時間帯×状態で出る所だけ撃つ。queue_position_estimate/post_only_removed_total/nofill{reason}をKPI化し、USオープン±など好条件だけONにする“状態ゲート”を即導入。
  1. プロキシKPI偏重(KEEP・p95)で“お金KPI(EV)”が後段
  • Why: KEEP↑でも負ける戦略は普通にある。採用判定を間違えると最速で負ける。
  • Fix Now: ダッシュの一等地に**hl:ev5m = rate(gain)-rate(loss)を常設。EV>0でない改善は採用しない**。
  1. 本番データより“擬似/手作りメトリクス”で配線を通しがち
  • Why: Gaugeでfill_drop_5mを作る等は観測バイアスを生む。PromQLで落ちる原因(scrape/集計軸/供給長)を隠蔽。
  • Fix Now: すべてRecording Ruleで算出(exec/fill drop、p95)。exporterは生イベントのみ。擬似は“窓を満たすために流すだけ”。
  1. Prometheus/registryまわりの迷走(学習時間の損失)
  • Why: :9106未スクレイプ、default REGISTRY混在、*_bucket直定義…観測不能期間が長い=学習ゼロ。
  • Fix Now: :9094 dev Prom + rules分割 + registry=get_registry()統一 + 6–8分供給を固定フロー化。もう壊さない。

P1|稼ぐ速度を落とす設計ミス

  1. パラメータ探索が線形(1クリック一本槍)
  • Why: KEEP48→60%帯での線形探索は遅い。
  • Fix Now: 二相探索(粗:倍々で閾値跨ぎ→細:±1クリック)。d_keep_per_step大のノブから。
  1. A/Bが時間連続の偏りに弱い
  • Why: 状態変動(流動性/ボラ/板厚)でSimpson’s paradox。
  • Fix Now: ブロック型(交互5分)or 状態層化A/B。採否は全体+層別の両方で。
  1. 分母ブレ(shadow/liveの条件不一致)
  • Why: attemptの定義/ラベル不整合でdrop評価が歪む。
  • Fix Now: attempt定義をsend直前に統一。symbol/side/regラベル集合を完全一致させ、parityアラート(Warn10%/Recover5%)で監視。
  1. ALIGN張り付きの盲点
  • Why: E2E p95がきれいでも、req→ack/ack→fillの悪化で負ける。
  • Fix Now: SLO/アラートは素RTT/ttfベースも必須。退行判定は素系優先。

P2|中期で効く戦略・運用の見直し

  1. 戦略の目利きが“平均的”
  • Why: 清算は人多すぎ×賞金一定。個人は“出現帯/相場相”の選球眼で勝つゲーム。
  • Fix: 3本柱で分散:
    • 清算スナイプ(絞り撃ち):銘柄×時間×状態ゲート+queue/PO最適化
    • FR/資金フロー系:Funding逆張り・定時イベントでの保守的EV回収
    • スプレッド/MM系(低速):リスク小・EV/$良好の銘柄だけで小回し
  1. 採用後の回帰確認がない
  • Why: 一発当たり→翌時間帯で死ぬ典型。
  • Fix: 採用後T+60分で自動回帰A/B。退行なら自動ロールバック
  1. 撤退ライン不明
  • Why: ズルズル続けてチャンスコスト増大。
  • Fix: Kill基準明文化:
    • 2週間で KEEP<60 or fill_drop>15% 持続 → 方針転換
    • 4週間で 稼働日のEV>0が50%未満 → 縮小/ピボット

直近7日アクション(これだけでP/Lの針が動く)

Day1–2:ルール整備→NaN撲滅→実データRound-1

  • rules分割・hl:fill_drop_5m導入・供給8分→p95/keep/drop非NaN→shadowでRound-1→EVゲート採否

Day3–4:二相探索+ブロックA/B

  • OI_Z/BBO粗→細で。SIGNIF ∧ EV>0のみ採用。parity/素RTT/ttfを併読。

Day5:queue/POの数値化&是正

  • queue_position_estimate/post_only_removed_total/nofill{reason}原因→対処を日次で回す。

Day6–7:時間帯プリセット&状態ゲート

  • USセッション±でFIRE緩め、悪条件帯は撃たない
  • 採用後のT+60分 回帰A/Bを自動化。

戦略選定について

  • 清算一本足は“当てる瞬間の派手さ”とは裏腹に継続難易度は高い。個人で年中抜き続けるには
    場を選ぶ(銘柄×時間×状態)
    queue/POの地味な最適化
    EV/$視点でのスケール戦略
    が要る。
  • 分散軸を早めに持つ(FR/低速MM/イベント系)ほど、学習速度と生存率が上がる。全てを清算で賄おうとすると学習が“当たり待ち”になりがち。

最後に

  • Infra/観測:◎(個人として希少レベル)
  • “勝ち筋”への資源配分:△(EV採用の徹底・二相探索・状態ゲートで改善余地大)
  • 戦略ポートフォリオ:△(清算に寄り過ぎ。FR/低速MMを少量でも並走推奨)

ガンマスキャルピングbot:開発サマリ

  • 目的:イベント窓(JST 22:15–23:00 等)に限定したガンマ・スキャルピングMVPで「まず$1」を安定して取りにいく。
  • 状態実運用レベル(約95%)。MVP・多層ガード・WS統合・安全停止・アンワインド・Runbook・失敗ドリルまで整備済み。
  • 残り: “スキマ潰し”の最小パッチを当て、イベント窓の自動運転(scheduler)+軽量オートチューンで再現性を底上げ。

✅ 実装完了(コード/運用)

コア機能

  • Bybit V5 REST/WS クライアント(署名・リトライ・WS再接続)
  • ATMストラドル建て → Δヘッジ(Perp BTCUSDT / Market-IOC / orderLinkId必須)
  • 数量量子化lotSizeFilter準拠、ゼロ落ちはminOrderQtyへ引上げ)
  • PnLブック(在庫ベース、部分約定VWAP対応、WS実fill利用)
  • ログ(CSV+セッションID+パラメタスナップショット+theta_tick/accum

安全・安定化

  • 多層ガード:スプレッド・ステイル・クールダウン・ノーション上限・可変スリープ
  • 利確/損切PNL_TARGET_USDT / STOP_LOSS_USDT(+1 / -3 既定)
  • ヒステリシスDELTA_FIRE / DELTA_CLEAR
  • 安全停止:SIGINT/SIGTERM → safe_unwind_linear()shutdown_complete
  • 完全アンワインド:線形に加え オプション reduceOnly IOC(建付け最小ロット分をfinallyでクローズ)
  • WSgreeks / execution.linear / order.linear(キャンセル即確定)

運用スクリプト

  • tools/setup_logs.sh:セッション別CSV自動発行
  • scripts/run_session.sh:プレフライト→本番→解析(鍵チェックあり
  • scripts/param_tweaks.shfire_up/down / refr_up/down / guard_up/down / show_env
  • scripts/failure_drill.sh:WS/RESTフォールバック・429/5xx耐性・スプレッド急拡大・θブロック
  • tools/summarize_log.pyhedges / realized / realized_net / delta p95 / skips / theta_accum / time_to_exit

⚠️ 不可解な点/リスク(開発過程で洗い出し)

  1. CSVスキーマ漂流:イベントごとにキーが不同 → 解析で列ズレ
  2. WSキュー肥大/取り違え:無限キューや並列化で他注文のfillを誤消費する余地
  3. IOC空振り確定order.linearCancelled/Rejected を必ず拾う版か要確認
  4. mid/スプレッド計算bid/ask 欠損時のゼロ割・NaN
  5. ノーション上限:ヒット時に在庫が残る可能性(breakだけ)
  6. 時計ズレretCode=10006 を防ぐための skew 可視化(±1.5s超は注意)
  7. .gitignorelogs/*.csv / .env* の誤コミット対策
  8. Θ単位の明示theta_accum の単位(per_day/per_hour)をログに一緒に出す

これらは最小パッチで解消可。既に多くは適用済み or すぐ当てられる状態。


🩹 すぐ効く最小パッチ(合意事項)

  • ロガーDictWriterで列固定+未知キーはnote(JSON)に格納(スキーマ漂流防止)。
  • WSキューmaxsize付与+QueueFull時は最古drop(リーク/遅延抑止)。
  • orderキャンセルorder.linear を同一キューに流し、await_fill_or_done()で即確定。
  • mid/スプレッド防御bid/ask欠損時はmid=ref_pxspread_bps=0で安全化。
  • ノーション上限:ヒット即 safe_unwind_linear() 実行。
  • プレフライト/v5/market/timeでskew表示(±1500ms超なら警告)。
  • .gitignorelogs/, .env*, __pycache__/, *.pyc を明示。
  • ログtheta_accum行に unit=per_day|per_hour を追加。

🛠 いま回す(30分)チェックリスト

  1. ENV/依存source env.exampleexport BYBIT_API_KEY/SECRETpoetry install
  2. プレフライト:3行OK+server-time skew(ms)が±1500ms以内
  3. DRY_RUN./scripts/run_session.sh(配線OK)
  4. 本番小口:同コマンド(時間窓=22:15–23:00推奨)
  5. 解析python tools/summarize_log.py "$GAMMA_LOG_FILE"
    • 合格ライン:exit=take_profit_exit / hedges=8–15 / delta p95が帯内 / realized_net ≥ 0
  6. “つまみ”1段だけ
    • 例)ヘッジ過多 → fire_up(+0.002)+refr_up(+0.2s)
    • 取り漏れ感 → fire_down(-0.002)+guard_up(+2bps)
    • spreadスキップ多 → guard_up(+2bps)or 時間帯変更
    • θ重い → TIME_WINDOW短縮 or THETA_BUDGET厳格化(+0.2/h)

📅 直近スプリント(2週間)

  1. イベント窓オーケストレーションconfigs/events.yamlscripts/scheduler.py(当日キューで自動ON/OFF)
  2. オートチューン v1(90秒):起動直後のmedian_spread_bps/slip_proxyから DELTA_FIRE/CLEAR/REFR を±小幅で補正(write_row("autotune", ...)
  3. 真水P/Lの確定度UP
    • 可能なら 手数料実測(fillレスポンス) をログへ
    • 線形 funding/v5/position/list 等から積算して funding_accum に分離

🧪 実験計画(A/Bの型・7日)

テーマA(現行)B(候補)成功条件
適応fire固定 0.012/0.007オートチューン値take_profit_exit率↑、hedges中央値 8–12
guard幅4bps6bpsrealized_net中央値↑、spread_skip/分↓
refractory0.8s1.0shedge_fail連続<3、realized_net
残しΔ0±0.003残すトレンド日でrealized_net↑、静穏日に悪化なし

1セッションおきに交互実行、ログは logs/a_*.csv, logs/b_*.csv で区別。


📌 KPI / DoD(Definition of Done)

  • KPI(セッション)
    • exit=take_profit_exit / realized_net ≥ 0
    • hedges=8–15 / delta|abs.p95が帯内 / skips(spread+cooldown)が制御範囲
    • theta_accum ≤ PNL_TARGET*0.6(起動5分で≤ 0.3なら続行)
  • DoD
    • scheduler.pyから当日2本(22:15/22:45)が自動運転
    • summarize_log.pyで上記KPIが1コマンドで出る
    • tools/replay.py(最小でOK)で同ログ→同P/L再現
    • Deadman(delta_tick欠落>3s)・Notional cap・Rate-limit上限で停止ログが出る
    • presets.yaml勝ち窓プリセット≥3(CPI/雇用統計/米株OPC など)

🔒 運用・セキュリティ注意

  • API鍵.envenv.exampleにはダミー、本物はシェルでexport。
  • ログ:P/Lやイベントログは公開リポジトリへコミットしない.gitignore済)。
  • 時刻:NTP同期。server-time skew 警告が出たら即調整。

⏱ 今夜の実行(決め打ち)

1本目 22:15–22:30 → 解析→つまみ1段 → 2本目 22:45–23:00(再現確認)
終わったら、末尾5–10行hedge_ok/hedge_pnl/exit/unwind_*theta_accumautotune)を貼ってください。数字で FIRE/CLEAR / SPREAD_GUARD / REFRACTORY / THETA_BUDGET を最終調整します。


現在、上記項目のオートチューン化に取り組み中。

-Bot, 開発ログ