Bot

開発記録#155(2025/3/25)「論文ベースのbot開発フローpart.17 初週チェック結果の分析」

2025年3月25日

前回の記事に引き続き、今回も仮想通貨botの開発状況をまとめていきます。

本記事では「暗号通貨のパンプ&ダンプスキームの検出」に関する論文をベースにbot開発の過程をまとめていきます。

📊 初週チェック結果の分析とシステム調整

次のステップでは、初週チェック結果の分析を行い、その結果をもとにシステムの最適化を実施します。


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接続障害時のリトライ処理を追加

システムの再デプロイ

  1. 新しいDockerイメージのビルドとプッシュ
docker build -t your_dockerhub_username/crypto_bot:latest .
docker push your_dockerhub_username/crypto_bot:latest
  1. 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エラー、データ損失の発生有無を重点的にチェック
Yodaka

次のステップでは、システムの安定性を確保するためのポイントについてまとめます。

関連
開発記録#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ギビ”に増やしたので、ざっくり言えば『ちょっと机を広くした』くらいのイメージです。」

見出しテキスト

✅ 読み方は:

「いちギビ」から「いってんごギビ」
もしくは、
「いちギビバイト」から「いってんごギビバイト」


✅ 解説:

  • GiGibibyte(ギビバイト) の略で、
    1 Gi = 1,073,741,824 バイト(≒1024³ バイト) です。

これは、よく聞く「GB(ギガバイト)」とはちょっと違って、
2のべき乗(1024単位)で数えるときに使う正式な単位です。


🔎 例えて言うなら:

  • 1Gi(ギビ) = 1024Mi(メビ)
  • それに対して、1GB(ギガ) = 1000MB(メガ)

なので、Kubernetesやメモリ割り当ての世界では「Gi」「Mi」などの単位がより正確な容量指定として使われています。


✍️ 最後に一言

Botを“働かせる”って、実は結構繊細なチューニングが必要なんですよね。
ちゃんと見守って、負荷をコントロールして、エラーには粘り強く対応する。

Bot開発って、単にコードを書くだけじゃなくて、
「どうやって快適に動かしてあげるか」までが開発の一部なんだなと、改めて思います。


というわけで、今回のおまけはこの辺で。
また次回も、技術の裏側にある「ちょっとした気配り」や「落とし穴」を紹介していきます。

仮想通貨bot開発ラジオ、よだかでした。

おまけ:ハッカー的な視点でコード分析してみた

Yodaka

ハッカー的な視点でこのコードを見たとき」、どれくらいエレガントか、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() でファイル存在チェック+エラーハンドリング済み
  • 出力に件数つきで明瞭化(成功件数 / 全体件数

🎙️ まとめ:

このコードは“ちゃんと使える道具としての美しさ”を意識して整えました。
冗長な部分を削りつつ、リスクを潰して、他の環境でもすぐに動く。
ハッカーの視点では、**「堅牢さと拡張性のバランスを保ってるか?」**が大事なんですよね。

-Bot