本記事では、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 変換時に
/100
とquantize
を忘れ、価格バッファが 100 倍に膨張。 - TTL の単位差異(秒→ミリ秒)で注文が即時失効し、fill 率が 0 %に。
hyperliquid_sniper
をsrc/
配下に置いた結果、CLI が ModuleNotFound。packages
定義追加で解決。
🚀 次アクション
- 24 h テストネットログを DuckDB で集計し、
fill_rate
とslip_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.ini
にpythonpath=./src
を書き忘れるとテストだけが失敗。
🚀 次アクション
cfg
に 環境プロファイル (testnet/mainnet) を追加し、切替を env 変数 1 行に。- VSCode の launch.json / pythonPath を src 構成向けに固定してチーム共有。(不要かも)
第2章 4 つの守護者:ミニマム監視&ログ基盤を 2 時間で通電
運用トラブルの “初動 30 秒” を守るため、4 ガード を最優先で実装しました。
- 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 rows | data/parquet/trades_realtime.parquet (バッファ20件×75 flush) |
ログ行数 | 約 3 000 行 | logs/sniper.log (再接続 0、fatal 0) |
Heartbeat | 30 s 間隔で送信 | Slack 健康チェック OK |
Ping RTT (p95) | ≲ 350 ms | DEBUG ログ値より |
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 詰まったポイント(暫定)
- Liquidation フラグが付与されず Sniper が発注ゼロ
- ⇒ size 閾値判定など擬似トリガ実装を検討
- 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 バックテスト基盤 を深掘りします。お楽しみに!