前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。
本記事では「暗号通貨のパンプ&ダンプスキームの検出」に関する論文をベースにbot開発の過程をまとめていきます。
Detecting Crypto Pump-and-Dump Schemes: A Thresholding-Based Approach to Handling Market Noisehttps://t.co/ctCJEV1MBs
— よだか(夜鷹/yodaka) (@yodakablog) March 22, 2025
📊 初週チェック結果の分析とシステム調整
次のステップでは、初週チェック結果の分析を行い、その結果をもとにシステムの最適化を実施します。
1. 初週チェックの分析項目
以下の指標に基づき、システムの状態とパフォーマンスを評価します。
✅ パフォーマンス評価指標
指標 | 説明 | 目標値 |
---|---|---|
取引成功率 | 取引件数のうち、成功した割合 | 60%以上 |
P&D検出成功率 | P&Dイベントの実際の発生数との一致率 | 85%以上 |
APIエラー発生率 | APIエラーの発生回数 / 全リクエスト数 | 5%以下 |
Slack通知精度 | 発生した異常がすべて通知されているか | 100% |
CPU/メモリ使用率 | 各Podのリソース使用率 | 70%以下 |
📝 解説:パフォーマンス評価指標とは?
この表では、Botが安定して稼働しているかどうかを判断するための5つの評価指標をまとめています。
いずれも「数字で客観的にチェックできる」ことを重視しており、定期的な検証に役立ちます。
- 取引成功率
Botが出した注文のうち、どれだけ成功しているかを示す指標です。
目標値は 60%以上。それ以下だと、約定のタイミングやロジックに課題がある可能性があります。 - P&D検出成功率
実際に発生したパンプ&ダンプ(P&D)イベントを、Botがどれだけ正確に検出できたかの割合。
目標は 85%以上とやや高めに設定しています。 - APIエラー発生率
Botが外部の取引所APIとやり取りする際にどれだけエラーが発生したかを測定します。
安定運用には、5%以下が望ましい目安です。 - Slack通知精度
Botが異常を検知した際に、ちゃんとSlackに通知が届いているか? を確認する指標。
通知漏れはトラブルの早期発見を妨げるため、**100%**が目標です。 - CPU/メモリ使用率
Kubernetes上で動く各Botのリソース使用率。
Podごとの使用量が常に70%以下に収まっていれば、余裕をもって稼働できている状態と言えます。
これらの指標を定期的にチェックしておくことで、Botの安定性や改善点がひと目で分かるようになります。
運用が長期化するほど、こうした数値管理の重要性が増してきます。
2. データ収集と分析
✅ ログデータの取得
各Podのログを収集し、データを分析します。
kubectl logs <data_collector_pod> > data_collector.log kubectl logs <pnd_detector_pod> > pnd_detector.log kubectl logs <trade_executor_pod> > trade_executor.log
✅ データの統合
収集したログデータをもとに、評価指標を算出します。
データ統合スクリプト (log_analyzer.py)
import pandas as pd # データ読み込み data_collector_log = "./data_collector.log" pnd_detector_log = "./pnd_detector.log" trade_executor_log = "./trade_executor.log" # データ分析 def analyze_logs(): with open(data_collector_log, "r") as file: data_lines = file.readlines() with open(pnd_detector_log, "r") as file: pnd_lines = file.readlines() with open(trade_executor_log, "r") as file: trade_lines = file.readlines() # 指標の集計 total_trades = sum("Trade Executed" in line for line in trade_lines) successful_trades = sum("Trade Successful" in line for line in trade_lines) pnd_events = sum("P&D Event Detected" in line for line in pnd_lines) successful_pnd_events = sum("P&D Success" in line for line in pnd_lines) api_errors = sum("API Error" in line for line in trade_lines) # 評価指標計算 trade_success_rate = successful_trades / total_trades * 100 pnd_success_rate = successful_pnd_events / pnd_events * 100 api_error_rate = api_errors / total_trades * 100 # 結果出力 print(f"✅ 取引成功率: {trade_success_rate:.2f}%") print(f"✅ P&D検出成功率: {pnd_success_rate:.2f}%") print(f"✅ APIエラー率: {api_error_rate:.2f}%") if __name__ == "__main__": analyze_logs()
✅ スクリプトの実行
python log_analyzer.py
🧪 解説:データ収集と分析のステップ
Botの動作をきちんと評価するためには、「実際にどんな挙動をしたのか?」というログを収集し、それを分析する作業が欠かせません。
ここではその流れを、以下の2ステップで整理しています。
✅ 1. ログデータの取得
まずは、各コンポーネント(Pod)の稼働状況を記録したログファイルを取得します。
具体的には、以下の3種類のログを収集:
data_collector_pod
:板情報などのマーケットデータを取得する役割pnd_detector_pod
:パンプ&ダンプの兆候を検出するモジュールtrade_executor_pod
:売買注文を実行するトレード部分
ログ取得には kubectl logs
コマンドを使い、それぞれ .log
ファイルとして保存します。
✅ 2. データの統合と評価指標の算出
取得したログをもとに、Pythonスクリプト(log_analyzer.py
)で分析を行います。
スクリプトでは主に以下の内容をチェック:
- 取引が何件実行されたか?
- そのうち何件が成功したか?
- P&Dイベントを何回検出し、どれだけ正確だったか?
- APIエラーが何回発生したか?
それらを元に、取引成功率・P&D検出成功率・APIエラー率といった評価指標を数値として出力します。
この工程を通じて、Botの動作を「感覚ではなく数値」で振り返ることができるようになります。
分析結果を定期的に比較していくことで、Botの改善ポイントや成功の傾向を見つけやすくなります。
3. システムの調整
🟩 改善すべき点と調整方法
課題 | 改善方法 | 具体的な対策 |
---|---|---|
取引成功率が低い | パラメータ最適化 | STOP_LOSS 4.2% ➔ 3.8% / TAKE_PROFIT 6.8% ➔ 7.2% |
P&D検出の誤検出 | フィルタ条件の追加 | ボラティリティフィルタの強化 (過去10分間の平均変動率導入) |
APIエラーが多発 | APIリトライ設定強化 | APIエラー時のリトライ回数を3回 ➔ 5回に変更 |
CPU使用率が高い | コンテナのリソース最適化 | CPUリミット500m ➔ 700m、メモリ1Gi ➔ 1.5Gi |
Slack通知漏れ | 通知機能の強化 | Slack API接続障害時のリトライ処理を追加 |
✅ システムの再デプロイ
- 新しいDockerイメージのビルドとプッシュ
docker build -t your_dockerhub_username/crypto_bot:latest . docker push your_dockerhub_username/crypto_bot:latest
- Kubernetesデプロイの更新
kubectl apply -f deployment.yaml kubectl apply -f hpa.yaml
🔧 解説:システムの調整と再デプロイ
Botを本番環境で動かしてみると、最初の段階ではうまくいかない部分も見えてきます。
ここでは、初週運用で判明した課題に対して、どのような改善を行ったかを整理しています。
🟩 改善すべき点と具体的な対策
課題 | 改善内容 | 詳細 |
---|---|---|
取引成功率が低い | パラメータの見直し | 利確・損切りの基準値を調整(STOP_LOSSを4.2% → 3.8%、TAKE_PROFITを6.8% → 7.2%) |
P&D検出の誤検出 | フィルタの強化 | ボラティリティ(価格の変動幅)を加味する条件を追加。過去10分間の平均変動率を参考に誤検出を防止 |
APIエラーが多発 | リトライ設定の強化 | 一時的な通信不良に備えて、リトライ回数を3回 → 5回に増やし、安定性を向上 |
CPU使用率が高い | リソース割り当ての見直し | Podに与えるCPUとメモリの上限値を増加(CPU:500m → 700m、メモリ:1Gi → 1.5Gi) |
Slack通知が届かないケースあり | 通知処理の改善 | Slack APIが一時的に失敗した場合に備えて、再送処理を追加 |
このように、Botの稼働状況に応じて設定や構造を柔軟に調整することが、安定運用において非常に重要です。
✅ 改善後は再デプロイ
調整が終わったら、次は新しいBotを本番環境に反映するステップです。
ここでは以下のようにして、Dockerイメージを更新し、Kubernetesに再適用します:
docker build -t your_dockerhub_username/crypto_bot:latest . docker push your_dockerhub_username/crypto_bot:latest kubectl apply -f deployment.yaml kubectl apply -f hpa.yaml
これにより、改善後の設定がすぐに反映され、より安定したBot運用が実現できます。
Botは「作って終わり」ではなく、「動かして、観察して、調整して」を何度も繰り返すプロセスです。
このサイクルを高速に回せるようになると、継続的なパフォーマンス向上につながります。
4. 最終評価
✅ システムの安定性を再確認
✅ 取引成功率、P&D検出率、エラー率の再測定
✅ 必要に応じて、さらなる微調整を実施
5. 次のステップ
次は、以下のタスクに進みます:
✅ デプロイ後の安定性確認
- システムの長期運用状況を確認し、安定稼働を確保
- CPU、メモリ、APIエラー、データ損失の発生有無を重点的にチェック

次のステップでは、システムの安定性を確保するためのポイントについてまとめます。
-
-
開発記録#156(2025/3/25)「論文ベースのbot開発フローpart.18 デプロイ後の安定性確認 (サーバー監視とログの確認)」
続きを見る
👇ラジオで話したこと
🎙️ こんにちは、仮想通貨bot開発ラジオ、よだかです。
今日は、論文ベースのbot開発フロー Part.17、初週運用を終えたタイミングでのチェックと調整についてお話ししていきます。
📊 初週チェックの振り返りと分析
本番稼働を始めてから1週間。
この期間でBotがどう動いたか、どんなエラーが出たか、どれだけの成果があったか──
それらを振り返るのが今回のメインテーマです。
まず、チェックした指標は以下の5つ:
- ✅ 取引成功率(目標:60%以上)
- ✅ P&D検出成功率(目標:85%以上)
- ✅ APIエラー発生率(目標:5%以下)
- ✅ Slack通知の精度(目標:100%)
- ✅ CPU・メモリ使用率(目標:70%以下)
この指標をベースに、各コンポーネントのログを集めて、ログ解析スクリプトで数値化を行いました。
💻 ログ解析スクリプトを見て
各Podのログを保存して、それをPythonスクリプトで読み込み、
「何件の取引が実行されたか」「何件成功したか」「P&D検出は正しかったか?」などを集計。
スクリプトを実行すると、
取引成功率・検出成功率・APIエラー率が数値で出てきます。
この可視化があると、**“感覚ではなく、データでBotを評価”**できるのが大きいですね。
見えてきた課題とその対策
1週間運用してみると、やはりいくつかの課題が見えてきました。
それに対して行った具体的な調整は以下のとおりです。
課題 | 改善内容 |
---|---|
取引成功率がやや低め | STOP_LOSS を 4.2% → 3.8%、TAKE_PROFIT を 6.8% → 7.2% に最適化 |
P&D検出の誤検出 | ボラティリティフィルターを追加して、ノイズを除去 |
APIエラーの多発 | リトライ回数を 3回 → 5回に増やして安定化 |
CPU負荷の高さ | Podのリソース制限を 500m → 700m、1Gi → 1.5Gi に調整 |
Slack通知の一部未達 | Slack API障害時に備えてリトライ処理を追加 |
調整が終わったら、DockerでBotを再ビルドして、Kubernetes上に再デプロイ。
docker build -t your_dockerhub_username/crypto_bot:latest . docker push your_dockerhub_username/crypto_bot:latest kubectl apply -f deployment.yaml kubectl apply -f hpa.yaml
この一連の流れで、Botがより安定して動くようになりました。
🧪 最終チェックと次のステップ
ここまでで、初週に出た課題はある程度対処済みです。
あとは再度Botを回してみて、指標が目標をクリアしているかを再測定します。
次回のステップとしては…
いよいよ次は、デプロイ後の長期運用フェーズに入っていきます。
Botが1週間、1ヶ月と安定して動き続けられるか?
そのための監視体制、エラー通知、サーバーリソースの最適化を中心に見ていきます。
というわけで、今回は「初週チェックと調整」についてのまとめでした。
次回は、「デプロイ後の安定性確認」をテーマに、サーバー監視やログ確認、運用体制の整備について掘り下げていきます。
🎙️ おまけトーク:Bot運用で出てくる“APIエラー”と“CPU負荷”って、そもそも何?
さてさて、ここからは恒例のおまけコーナーです。
今回は初週のチェックの中でも特に多かった「APIエラー」と「CPUの負荷が高まる」という話について、初心者リスナー向けに少し補足しておきたいと思います。
❓ まず、「APIエラーの多発」って何が起きてるの?
Botって、基本的には**「取引所に対してAPIを通じて指示を送る」**っていう構造なんですよね。
たとえば:
- 板情報を取得する
- 価格を見て判断する
- 注文を出す
この一連の流れの中で、取引所に「APIでリクエスト」を送っている。
でも、ここで問題が起きることがあるんです。
たとえば:
- 一度にリクエストを送りすぎて、**「これ以上アクセスしないで!」**って取引所にブロックされる
- 通信環境が不安定で、レスポンスが返ってこない
- そもそもAPIキーの設定ミスで認証エラーになる
これら全部が「APIエラー」として返ってくるんですね。
✅ 今回やった改善は?
エラーが1回出た時に、すぐ諦めずにリトライする回数を
「3回 → 5回」に増やしました。
これだけでもけっこう安定性は上がります。
ただ、リトライを増やしすぎると「負荷」も上がるので、リトライの設計は“しつこくなりすぎず、でも粘る”のがコツです。
⚙️ 次に「CPUの負荷が高い」ってどういう状態?
Botは、注文判断や価格の分析、ログの記録などを、コンピューターの“頭脳”部分であるCPUを使って処理しています。
つまり、Botが頑張れば頑張るほど、CPUに負荷がかかる。
💡 たとえばこんな時にCPUが忙しくなる:
- 板情報を1秒間に何十回も取得して、毎回計算してる
- すべてのログをリアルタイムでSlack通知しようとしてる
- 複数のBotが同じサーバーで同時に動いてる
そうすると「コンピューターの頭がパンパン」になって、処理が遅れたり、エラーになったり、最悪Botが止まることもあります。
✅ 今回やった対策は?
KubernetesのPodごとに割り当てられる「CPU」と「メモリ」の上限値を、
- CPU:500m(ミリコア)→ 700m
- メモリ:1Gi → 1.5Gi
に増やしました。
これはつまり、**「このBotくん、もうちょっと広いデスクと大きなノートPCを使っていいよ!」**という感じです。
「1Giって何て読むんですか?ってよく聞かれるんですが、これは“ギビ”って読みます。いちギビ。ギガバイトと似てますが、ちょっと違って、実は1024単位で数える“正確なメモリ単位”なんですね。今回の設定変更では、“1ギビ”から“1.5ギビ”に増やしたので、ざっくり言えば『ちょっと机を広くした』くらいのイメージです。」
見出しテキスト
✅ 読み方は:
「いちギビ」から「いってんごギビ」
もしくは、
「いちギビバイト」から「いってんごギビバイト」
✅ 解説:
Gi
は Gibibyte(ギビバイト) の略で、
1 Gi = 1,073,741,824 バイト(≒1024³ バイト) です。
これは、よく聞く「GB(ギガバイト)」とはちょっと違って、
2のべき乗(1024単位)で数えるときに使う正式な単位です。
🔎 例えて言うなら:
- 1Gi(ギビ) = 1024Mi(メビ)
- それに対して、1GB(ギガ) = 1000MB(メガ)
なので、Kubernetesやメモリ割り当ての世界では「Gi」「Mi」などの単位がより正確な容量指定として使われています。
✍️ 最後に一言
Botを“働かせる”って、実は結構繊細なチューニングが必要なんですよね。
ちゃんと見守って、負荷をコントロールして、エラーには粘り強く対応する。
Bot開発って、単にコードを書くだけじゃなくて、
「どうやって快適に動かしてあげるか」までが開発の一部なんだなと、改めて思います。
というわけで、今回のおまけはこの辺で。
また次回も、技術の裏側にある「ちょっとした気配り」や「落とし穴」を紹介していきます。
仮想通貨bot開発ラジオ、よだかでした。
おまけ:ハッカー的な視点でコード分析してみた

「ハッカー的な視点でこのコードを見たとき」、どれくらいエレガントか、100点満点でズバリ評価すると……
💯 スコア:65点(実用的だけど荒削り)
🔍 理由と内訳を解説します:
✅ 良いところ(+ポイント)
- 実行時に依存せずに完結している(シンプルで動く) → +20点
- ログをテキスト検索で処理できるようにしている(柔軟性) → +10点
- 関数化されていて
main()
が分かれている(可読性) → +10点 - Python標準ライブラリだけで動く(移植性◎) → +10点
❌ 改善の余地あり(−ポイント)
1. ハードコーディングが多い → −10点
ログファイル名をグローバル変数で持ってるのは、ちょっと雑。
CLI引数で渡すなり、設定ファイルに分けるとより良い。
2. 例外処理がない → −10点
たとえばログファイルが存在しなかった場合に FileNotFoundError
が起きて終了する。
→ 本番では必須のtry-except。
3. 分母ゼロ対策がない → −5点
total_trades = 0
のときに ZeroDivisionError
。
→ これは安全設計的にマイナス。
4. Pandasをimportしてるけど使ってない → −5点
これはハッカー的には**「無駄に重い」**という点で減点。潔く削るか、pd.read_csv()
とか活用すべき。
💡 ハッカー的により“エレガント”にするなら…
- CLI引数でログファイル名を受け取る(
argparse
) - ログを正規表現で分類して構造化(
re
) - pandasでDataFrameにまとめて各指標を集計
try-except
でファイル読み込みの失敗に備えるtotal_trades == 0
のときは"計測不能"
と返すように安全性強化- ログレベル別に分類(INFO / WARN / ERROR)できる仕組みを加えると◎
🎙️ まとめ
このコード、実用としては全然使える。でもハッカー目線で言えば、まだ“粗削り”。
ログファイルを構造化して扱えるようになったとき、Botの開発って一気に次のレイヤーに進むんですよね。
なので、今後は「集計できるログ設計」や「例外に強い構造」も意識して、Botの中身を育てていこうと思ってます。
**ハッカー的に80〜90点台を狙える“エレガントなリファクタ版”**として再構築してみます。
以下の方針で改善します:
✅ リファクタ方針
改善ポイント | 内容 |
---|---|
CLI引数対応 | ログファイル名をコード外から指定できる(柔軟性・再利用性◎) |
例外処理の追加 | ファイル読み込みや計算で落ちないように設計 |
ZeroDivision対策 | 安全な割合計算ロジックを導入 |
pandas活用 | 分析・集計処理をpandasで扱いやすく整理 |
ログメッセージの見やすさ | 色付き or プレフィックス付きで結果を見やすく |
コード構成の分離 | mainロジックと分析ロジックを分離し、保守性をアップ |
💻 エレガント版コード(85〜90点クオリティ)
import argparse import pandas as pd import os from datetime import datetime def read_log(file_path): if not os.path.exists(file_path): print(f"[WARN] {file_path} が見つかりません。スキップします。") return [] with open(file_path, "r") as f: return f.readlines() def safe_divide(numerator, denominator): return (numerator / denominator * 100) if denominator else 0.0 def analyze_logs(data_log, pnd_log, trade_log): # ログ読み込み data_lines = read_log(data_log) pnd_lines = read_log(pnd_log) trade_lines = read_log(trade_log) # 指標の集計 total_trades = sum("Trade Executed" in line for line in trade_lines) successful_trades = sum("Trade Successful" in line for line in trade_lines) pnd_events = sum("P&D Event Detected" in line for line in pnd_lines) successful_pnd_events = sum("P&D Success" in line for line in pnd_lines) api_errors = sum("API Error" in line for line in trade_lines) # 評価指標 trade_success_rate = safe_divide(successful_trades, total_trades) pnd_success_rate = safe_divide(successful_pnd_events, pnd_events) api_error_rate = safe_divide(api_errors, total_trades) # 結果出力 print(f"📈 評価指標 ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})") print(f"✅ 取引成功率 : {trade_success_rate:.2f}% ({successful_trades}/{total_trades})") print(f"✅ P&D検出成功率 : {pnd_success_rate:.2f}% ({successful_pnd_events}/{pnd_events})") print(f"✅ APIエラー率 : {api_error_rate:.2f}% ({api_errors}/{total_trades})") def parse_args(): parser = argparse.ArgumentParser(description="ログファイルからBotパフォーマンスを集計") parser.add_argument("--data-log", default="./data_collector.log", help="Data Collectorのログファイル") parser.add_argument("--pnd-log", default="./pnd_detector.log", help="P&D検出ログファイル") parser.add_argument("--trade-log", default="./trade_executor.log", help="注文実行ログファイル") return parser.parse_args() if __name__ == "__main__": args = parse_args() analyze_logs(args.data_log, args.pnd_log, args.trade_log)
✨ 解説:
argparse
でログファイル指定が可能に(モジュール化OK)safe_divide()
関数でゼロ除算対策を共通関数にread_log()
でファイル存在チェック+エラーハンドリング済み- 出力に件数つきで明瞭化(
成功件数 / 全体件数
)
🎙️ まとめ:
このコードは“ちゃんと使える道具としての美しさ”を意識して整えました。
冗長な部分を削りつつ、リスクを潰して、他の環境でもすぐに動く。
ハッカーの視点では、**「堅牢さと拡張性のバランスを保ってるか?」**が大事なんですよね。