前回の記事に引き続き、今回も仮想通貨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 通知は 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 数 も条件に入れ、ノイズに釣られた無駄発注を抑止する。 |
これらを押さえておくと、記事の内容やコードの意図がサクッと読み解けるはずです!