前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
0. はじめに
- 個人でマーケットメイク系の仮想通貨 Bot を育てている
- 今回は “可観測性の強化” が主テーマ
- ※売買シグナルの具体的数値・秘匿アルゴリズムは伏せます
1. 今回の到達点(概観)
| 項目 | ステータス (公開版) | 
|---|---|
| 取引所環境 | パブリック API(名称は非公開) | 
| Bot モード | 本番ネット/最小ロット運用 | 
| 新規実装 | 可観測性強化(スプレッド・深さ・レイテンシ・手数料をリアルタイム収集) | 
| 現フェーズ | 24 h データ収集(自動停止なし/DD ガードのみ) | 
| 次フェーズ | 収集データ → パラメータ最適化 & 手数料圧縮 | 
2. 追加した主要機能(秘匿情報を除いた説明)
| # | 機能 | 目的・メリット | 実装トピック | 
|---|---|---|---|
| 1 | minQty ガード | 取引所の最小注文数量を自動取得し、設定ミスで API エラーにならないよう保護 | 起動直後に REST 1 call | 
| 2 | METRIC ログ化 | “スプレッド幅・tick 数・板厚・ループレイテンシ” を 1 周ごとに出力 | loguru+ JSON serialize | 
| 3 | 複合エントリー判定 | スプレッドの拡大だけでなく、tick 数 の下限もチェックしてノイズ発注を防ぐ | spread% × 最小 tick の AND 条件 | 
| 4 | Fee 集計 (Gross↔Net) | 手数料を別カウント → 真の収益 (Net) を可視化 | fills の execFeeを加算 | 
| 5 | Slack 通知改善 | Cycle / Fee / Netを即時共有、DD Warn / Exit も自動送信 | Incoming-Webhook API | 
| 6 | レイテンシヒストリ | ループ時間の p95 を算出し、ネットワーク・処理遅延を監視 | numpy.percentile | 
Tip: “とりあえず何でも可視化 → 後で要らないメトリクスを削る” 方が失敗が少ない。
3. 可観測性を高めるコードの書き方 Tips
- 標準出力に即 flush - Docker の log ではバッファリングに要注意
- DEBUGで盛って- INFOで絞る ─- .envで Slack 送信レベル だけ切替
- JSON ログ → pandas 直読み - 後段解析が段違いにラク
- 例外は握りつぶさず “HDLR ERR: …” と最小限で吐く - 落ちどころが一目でわかる
- long-running loop は p95 / p99 を持つ - “最悪寄りの遅延” を掴む指標
4. テスト/計測フロー(抜粋)
graph LR
  A[Docker build] --> B[Unit & Lint (CI)]
  B --> C[/mainnet small-lot run/]
  C --> D{24 h JSON logs<br>SQLite trades}
  D --> E[Notebook / CLI 解析]
  E --> F[Param update (.env)]
  F --> C
- CI: pytest + ruff だけでも「うっかりバグ」激減
- 24 h 計測: まず <24 h> 計測でログを溜め、Notebook で解析
- 解析 CLI: python tools/summary.py logs/*.jsonで即グラフ生成
5. 収集しているデータと役割
| データ | 格納先 | 用途 | 
|---|---|---|
| 板情報 (price gap / depth) | JSON ログ | スプレッド・流動性と Fill 成功率の相関分析 | 
| loop_ms | JSON ログ | レイテンシ・p95 監視→ボトルネック特定 | 
| 手数料 (execFee) | SQLite & Slack | Net PnL 計算、Fee 削減効果の検証 | 
| 取引履歴 (price, qty) | SQLite | ペアリングして Cycle PnL を確認 | 
| DD Warn / Exit イベント | Slack | 異常終了の即時把握 | 
6. 本日の学び
- 「とにかく測る → 走らせる → 統計を見る」 - 早期に“不確実性”を炙り出せる
- Slack 通知は Warn / Cycle / Summary の 3 階層にするとノイズが減る
- Fee を Net で見ると “勝っているつもり” が幻覚 だったりするので要注意!
7. さいごに
- 次は 24 h ログを使った パラメータ最適化 と レイテンシ改善 に取り組む
- Bot 運用は “小さく回してデータを信じる” に尽きる
Disclaimer: 本記事は技術共有を目的としたものであり、投資助言ではありません。実売買の際はご自身のリスクでお願いします。
技術スタック
- Python 3.12 / asyncio / aiohttp
- Docker Compose + Poetry
- pybotters(取引所 REST & WS)
- loguru / numpy / sqlite3
- 通知:Slack Incoming-Webhook
- テスト:pytest, ruff
🧩 用語集(今回の記事で出てきたキーワードをかんたん解説)
| 用語 | 意味・背景 | Bot 文脈での使いどころ | 
|---|---|---|
| Net PnL (net profit & loss) | 取引で得た 粗利益 (Gross PnL) から、 取引手数料・スワップ・資金調達コストなど “直接コスト” を差し引いた最終損益。 | 「勝てていると思ったら手数料で赤字だった…」問題を防ぐため、必ず Net ベースでパフォーマンスを見る。 | 
| p95 / p99 | 統計学の 95 %・99 %パーセンタイル。 サンプル値を小さい順に並べ、上位 5 %(or 1 %)の境界値。 | ループ遅延や API レイテンシを監視するとき、平均より “最悪に近い遅延” を掴む指標として使う。 | 
| Fee を Net で見る | 手数料を コストとして控除し、損益を Net で評価すること。 | スキャル系や MM 系は手数料比率が高いので、「Gross 2 USD 儲かって Fee 2.5 USD」で実質負け…というケースが頻発。 | 
| ruff | Python 用の 超高速 linter / formatter。 PEP8 違反や unused import を数百倍速で検出。 | CI に組み込んで “うっかりミス” をプッシュ前に潰す。開発ループが速い Bot 開発と相性◎。 | 
| 例外を握りつぶす | except: passのように、エラー詳細を記録せず無視してしまうこと。 | 実運用 Bot では 「何が起きたか分からない停止」 を招くので厳禁。最低限 logger.exception(e)で痕跡を残す。 | 
| 即 flush | print(..., flush=True)やlogger.add(..., enqueue=True)などで バッファリングを待たずにログを吐くこと。 | Docker コンテナや systemd では、バッファが溜まるとログが遅配 → デバッグ不能になるため“即 flush”が鉄則。 | 
| JSON serialize | ログ出力を {"key": value}形式の 純 JSON で保存すること。 | 後段で pandas.read_json()→ 可視化までをワンライナーで行える。CSV より型崩れしにくい。 | 
| REST 1 call | WebSocket ではなく HTTP‐REST を 1 回だけ呼ぶこと。 | 起動時の設定取得(minQty など)を 瞬間的に済ませて WS 処理をブロックしない。 | 
| TICK_THR / TICK_THR 判定 | TICK_THRは 最低限欲しい “tick 差” を整数で指定する環境変数。例: TICK_THR=2なら bid↔ask が 2 tick(0.2 USD)以上開くまでは発注しない。 | スプレッド%だけでなく 絶対 tick 数 も条件に入れ、ノイズに釣られた無駄発注を抑止する。 | 
これらを押さえておくと、記事の内容やコードの意図がサクッと読み解けるはずです!
👇ラジオで話したこと
「こんにちは、よだかです。きょうは 開発ログ22──
 題して『データで磨くマーケットメイク Bot』。 “安全に 24 時間データを集めて次の一手へ” がテーマです。
 難しい単語は随時フォローしていきますので、耳だけ参加でも大丈夫!」
1|今回どこまで進んだ?
- 取引所:本番ネット、でもロットは 最小。
- 新機能:スプレッド・板厚・レイテンシ(処理遅れ)・手数料をリアルタイム収集。
- 運転モード:24 時間ノンストップ。ストッパーは「DD(ドローダウン)ガード」だけ。
ワンポイント解説
可観測性=“Bot の体温計”。どこが熱い=重い=遅いを察知する仕組みのこと。
2|追加した 5 つの機能
| # | 何を足した? | ざっくり目的 | 裏側テク | 
|---|---|---|---|
| 1 | minQty ガード | 取引所の “最小注文量” を自動取得→設定ミス防止 | 起動時に REST を 1 回だけ | 
| 2 | METRIC ログ | スプレッド幅・板厚・ループ遅延を毎周 METRIC …行で出力 | loguru+ JSON | 
| 3 | 複合エントリー判定 | スプレッド “%” × tick差 の AND 条件→ノイズ発注を防ぐ | spread_pct >= X && tick >= Y | 
| 4 | Fee 集計 | 手数料を別カウント→“Net 利益” を即確認 | fill の execFeeを合算 | 
| 5 | レイテンシ・ヒストリ | ループ時間の p95 を出して最悪遅延を監視 | numpy.percentile | 
tick は「価格の最小刻み」。BTCUSDT なら 0.01 USDT。
p95=上位5 %地点。平均でなく“ほぼ最悪”を掴む指標です。
3|“測れる Bot” の書き方 Tips
- print は即 flushprint(..., flush=True)にして、Docker のバッファ遅延をゼロに。
- DEBUG で盛って INFO で絞る
 Slack にはレベルWARN以上だけ送ると夜中が静か。
- JSON ログ → pandas
 純 JSON で吐けばpd.read_json一撃で集計できる。
- 例外は握りつぶさないexcept Exception as e: logger.exception(e)――“何で止まった?” が3秒で分かる。
- ループは p95 / p99 も記録
 「平均 50 ms だけど p99 が 400 ms」ならネットか DB が詰まり始めた証拠。
4|実測データ 24 h プロセス
Docker build → pytest & ruff (CI) → mainnet small-lot run → 24h JSON logs / SQLite trades → Jupyter or CLI 解析 → .env にパラメータ反映 → 再RUN
例:spread 幅と Fill 成功率の散布図を描いて
「tick ≥2 なら成功率 70 %、tick=1 は 30 %。
→ じゃあ TICK_THR=2 に固定しよう」──データで決められる!
- とにかく測る → 走らせる → 統計を見る
 勘より 24 h ログの方が正直。
- Slack 通知は 3 階層WARN/CYCLEサマリ/1日トータルに分けると “緊急だけ響く”。
- Fee を引いて初めて勝ち
 Gross 2 USDT − Fee 2.5 USDT = 実は負け…を早期発見。
- スプレッドログを DB に定期収集 → heatmap 可視化
- GitHub Actions で pytest+gitleaks自動スキャン
- tools/agg.pyで1行グラフ出力→パラメータ最適化へ
「きょうは “データで磨く Bot” をテーマにお届けしました。
今後はログ可視化⇒レイテンシ削減の深掘りなどをテーマにする予定です。
――それでは安全に、良いトレード&開発を!」
