Bot DeFi bot DEX 環境構築・インフラ 開発ログ

🛠️開発記録#255(2025/6/22)Hyperliquid Sniper v0→v1 開発戦記──24 h 無停止までの“4ガード”と学習サイクル確立

本記事では、Hyperliquid で動く Liquidation Sniper Bot の “ゼロイチ開発” を立ち上げ、24 時間テストランを実行できる状態 まで到達する過程を振り返ります。Poetry + src レイアウトで環境を再構築し、4つのミニマム監視(ガード) を2時間で通電。さらに Sniper 戦略 PoC を pytest グリーンで固め、GitHub Actions と Slack 通知を組み合わせた Fail-Fast→Iterate 開発サイクルを確立しました。

現在は 24 h テストネットランが進行中で、ログと Parquet を収集中です。本稿では「とにかく早く実データを回し、ログから学習を始める」ために削ぎ落とした要点と、実際につまずいたポイントを共有します。完走後に得られる最終統計や考察は、次回以降の記事で詳報予定です。

第0章 開発サマリ

✔️ 学び

  • 設定ハブの一元化: default.yml + cfg クラスで環境差異を吸収すると、テストと本番の切替が一瞬。
  • “4 ガード”優先で安心して PoC を回せる。最小構成でも再接続・Heartbeat・ログ回転・Slack Fatal があれば夜は眠れる。
  • CI Smoke < 5 min を先に通すと、後続タスクの安心感が段違い。

⚠️ 詰まったポイント

  • Decimal 変換時に /100quantize を忘れ、価格バッファが 100 倍に膨張。
  • TTL の単位差異(秒→ミリ秒)で注文が即時失効し、fill 率が 0 %に。
  • hyperliquid_snipersrc/ 配下に置いた結果、CLI が ModuleNotFoundpackages 定義追加で解決。

🚀 次アクション

  • 24 h テストネットログを DuckDB で集計し、fill_rateslip_bp を Slack 日次レポートに自動送信。
  • adaptive_spread() を実装し、目標 Fill 70 % に向けてバッファを動的最適化。
  • Parquet 再生型の Replay バックテストを整備し、戦略改良を回帰テスト付きで高速化。

次章以降では、環境構築から戦略実装、CI/監視、24 h ランの実践データまでを順を追って解説していきます。

第1章 プロジェクト再起動:Poetry × src レイアウトで土台を固める

Poetry 2.1.3 を導入し、ソースを src/ パッケージ構成 に統一しました。これにより仮想環境と依存がコードツリーから完全に分離され、ローカルと CI の環境差異をゼロにできます。pyproject.toml には

packages = [{ include = "hyperliquid_sniper", from = "src" }]

を追記し、どのシェルからも python -m hyperliquid_sniper.cli が実行可能になりました。また、設定一元化用に default.yml とシンプルなラッパ cfg クラスを実装し、テスト時には monkeypatch で簡単に上書きできる仕組みを作っています。

✔️ 学び

  • 依存地獄は早期に鎮圧するほうが得。src レイアウト+Poetry の 2 点セットで import 事故が激減。
  • 設定とコードを分離すると、pytest・CLI・Docker それぞれで挙動を切り替えやすい。

⚠️ 詰まったポイント

  • packages 定義を忘れて ModuleNotFoundError が多発。
  • pytest.inipythonpath=./src を書き忘れるとテストだけが失敗。

🚀 次アクション

  • cfg環境プロファイル (testnet/mainnet) を追加し、切替を env 変数 1 行に。
  • VSCode の launch.json / pythonPath を src 構成向けに固定してチーム共有。(不要かも)

第2章 4 つの守護者:ミニマム監視&ログ基盤を 2 時間で通電

運用トラブルの “初動 30 秒” を守るため、4 ガード を最優先で実装しました。

  1. WS 自動再接続(指数バックオフ)、2) Heartbeat → Slack Fatal、3) バッファ Flush & Parquet 保存、4) loguru ローテーション (100 MB / retention 10 days)

✔️ 学び

  • “まず落ちない” より “落ちてもすぐ起きる” をコード量最小で済ますと開発サイクルが速い。
  • ログを Parquet + DuckDB で統一すると、後からの集計が圧倒的に楽。

⚠️ 詰まったポイント

  • Decimal でパーセント値を扱うときに /100 忘れ → price_buffer が 100 倍。
  • ローテーション後のパス変更で FileHandler が迷子になり、ログが欠損。

🚀 次アクション

  • loguru → Prometheus exporter の 二重書きをフェーズ 2 で実装。
  • Heartbeat を /ping Slack 用ステータス絵文字に連動させ、視覚的な死活管理へ。

第3章 Liquidation Sniper PoC──価格バッファ 0.2 % の矢を放て

戦略の最小版は 「直近 Liquidation 検知 → ±0.2 % に逆張り指値 → TTL30 s で撤退」Decimal.quantize() で 4 桁精度に統一し、REST 注文 TTL をミリ秒に変換しました。安全停止用に _running フラグも追加。

✔️ 学び

  • 価格計算は Decimal + quantize + ROUND_HALF_UP が鉄板。
  • FakeAPI でテストを作ると pytest が 0.6 s で完走し、回帰が早い。

⚠️ 詰まったポイント

  • TTL 単位ミスで注文が 即失効、fill 率 0 %。
  • 未 fill キャンセル GC を忘れ、注文が墓場行きに。

🚀 次アクション

  • adaptive_spread() を EMA ベースで実装し、fill70 % を目指す。
  • fill / cancel / slip を 1 Parquet に統合し、学習材料を整備。

第4章 CI Smoke & Slack 通知──“壊したら即バレ”の開発フロー

GitHub Actions に workflow_dispatch を追加し、pytest + collector 10 trades が 5 分以内で回る “Smoke CI” を整備。起動通知と fatal 通知を Slack に流すことで、夜間でも異常検知が即座に届く体制が整いました。

✔️ 学び

  • CI Smoke を最小で通すと “壊れたコミット” が main に乗らず精神衛生◎。
  • Slack Webhook 通知は メッセージ全削除より連番投稿 のほうが履歴が追いやすい。

⚠️ 詰まったポイント

  • macOS runner の TLS 証明書差異で Slack 送信が 403。certifi 更新で解消。
  • cache キーの衝突で Poetry install が 2 分 → 5 分に膨張。hashFiles を lockfile 指定に。

🚀 次アクション

  • Nightly で 6 h リプレイテスト を GitHub Large Runner に分離。
  • Slack messages を blocks kit に変換し、PNL スナップショットを添付。

第5章 24 h 無停止ラン:回り始めたデータをどう活かすか(実行中レポート)〈更新版〉

5-1 途中経過サマリ(+2 h 時点)

指標備考
Parquet サイズ16 KB / 1 500 rowsdata/parquet/trades_realtime.parquet(バッファ20件×75 flush)
ログ行数約 3 000 行logs/sniper.log(再接続 0、fatal 0)
Heartbeat30 s 間隔で送信Slack 健康チェック OK
Ping RTT (p95)≲ 350 msDEBUG ログ値より
Sniper 発注数0(まだ Liq 無し)Liquidation フラグ待ち

ログ断片

Buffer reached 20, saving...
Successfully appended 20 trades to ...parquet
Heartbeat sent

5-2 学び(進行中でも得られたこと)

  • バッファ20件+60 s flush で小刻みに Parquet 追記すると、途中で bot を落としても分析用データがほぼ失われない。
  • macOS の du は GNU オプションが使えない ─ du -hd 2 data のように -d 指定で代替できる。
  • HL WebSocket は JSON 形式の {"type":"ping"} を受け付けず、ws.ping() が正解。エラーチャンネルに吐かれるだけで致命的ではないが、ログが汚れるので修正推奨。

5-3 詰まったポイント(暫定)

  1. Liquidation フラグが付与されず Sniper が発注ゼロ
    • ⇒ size 閾値判定など擬似トリガ実装を検討
  2. RTT が瞬間的に 600 ms 超え
    • ⇒ フェーズ2で Latency Monitor → Prometheus へ昇格させる根拠を再確認

5-4 次アクション(テストラン完走後)

  • Parquet を DuckDB で集計し、fill %・slip bp・reconnect count を Slack 日次レポートへ自動送信。
  • adaptive_spread() を EMA ロジックで実装し、fill 70 % に向けてバッファを自動可変化。
  • Replay バックテスト基盤を整備し、今回の実ログを入力に回帰テストを高速化。

※ 完走後の最終統計とチューニング結果は、続編記事で詳細報告予定。


この記事が、オンチェーン系 DEX Bot を “小さく作って速く回す” 際の設計と実装のヒントになれば幸いです。次回は、今回集めた 24 h 実ログをもとに adaptive_spread() のチューニングReplay バックテスト基盤 を深掘りします。お楽しみに!

-Bot, DeFi bot, DEX, 環境構築・インフラ, 開発ログ