初回公開:2025‑04‑01 / 最終更新:2025‑04‑24
前回の記事に引き続き、今回も仮想通貨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. 運用ルールの確立
- Botの稼働スケジュール設計
- 障害発生時の対応フロー策定
- 異常検出やリスク回避の優先順位決定
✅ 2. 最終パフォーマンスチェック←今ここ
- シミュレーション結果と実運用結果の比較
- 取引成功率、利益率、エラー率の再評価
- 調整が必要なパラメータの特定
✅ 3. デプロイ後の安定性確認
- Podの状態、リソース使用率の監視
- APIエラーやデータ欠損の確認
- Slack通知やログ記録の精度確認
✅ 1.運用ルールの確立 (Botの稼働スケジュールや障害対応フローの策定)
✅ 2.最終パフォーマンスチェック (シミュレーションと実運用の比較検証)
✅ 3.デプロイ後の安定性確認 (サーバー監視とログの確認)

次のステップとして、2.最終パフォーマンスチェック(シミュレーションと実運用の比較検証)に進みます。
目的
- シミュレーション結果と実運用結果を同じ指標で比較し、再現性を確認
- ズレの要因を特定して パラメータ/ロジックを最終調整
- 本番リリース前に “数値で安心” を取る
0. イントロ
前回(part.23)では 「暗号通貨のパンプ&ダンプスキーム検出」 の論文に基づき、検知ロジックと運用ルールを実装しました。今回の part.24 では、その 検知 Bot を例に「バックテスト vs. 実運用」のパフォーマンスを数値で突き合わせ、最終調整へ進む手順を解説します。
1. ステップ概要
準備 → 比較 → 調整 → 次フェーズ CSV 生成 指標の差確認 パラメータ修正 監視&デプロイ
2. データ準備
2‑1 ファイル構成
results/ ├── backtest_result.csv # バックテスト取引ログ ├── live_trade_log.csv # 実運用ログ └── performance_comparison.py# 比較スクリプト(§3)
2‑2 CSV 列仕様
timestamp | symbol | side | size | price | pnl | balance |
---|
2‑3 backtester_export.py
(全文:バックテスト結果を保存)
#!/usr/bin/env python3 """ backtester_export.py ──────────────────────────────────────────────────────── バックテストで得た取引ログ (list[dict] など) を CSV ファイル `./results/backtest_result.csv` として保存するユーティリティ ❏ 使い方 $ python backtester_export.py └─ ./results/backtest_result.csv が生成される """ from pathlib import Path from datetime import datetime, timedelta import pandas as pd import random # ① ダミーログを用意 ※実際はここをバックテストの生ログに置き換える trade_log = [] base_time = datetime(2025, 3, 30, 10, 0, 0) balance = 10_000 # スタート残高 USDT for i in range(50): ts = base_time + timedelta(minutes=i * 30) side = 'buy' if i % 2 == 0 else 'sell' price = 70_000 + random.uniform(-300, 300) size = 0.01 pnl = random.uniform(-30, 50) balance += pnl trade_log.append({ "timestamp": ts.strftime("%Y-%m-%d %H:%M:%S"), "symbol" : "BTCUSDT", "side" : side, "size" : size, "price" : round(price, 2), "pnl" : round(pnl, 2), "balance" : round(balance, 2) }) # ② DataFrame へ変換 df = pd.DataFrame(trade_log) # ③ 保存ディレクトリを保証して CSV 出力 out_dir = Path("./results") out_dir.mkdir(parents=True, exist_ok=True) csv_path = out_dir / "backtest_result.csv" df.to_csv(csv_path, index=False) print(f"✅ バックテスト結果を保存しました → {csv_path}")
2‑4 live_log_export.py
(全文:実運用ログを整形)
#!/usr/bin/env python3 """ live_log_export.py ──────────────────────────────────────────────────────── Bot が吐いたテキストログ (./logs/live_trade.log) をパースし、 ./results/live_trade_log.csv に整形保存するユーティリティ。 ❏ 想定ログフォーマット [YYYY-MM-DD HH:MM] Trade executed: SYMBOL SIDE SIZE @ PRICE, PnL: PNL, Balance: BAL """ from pathlib import Path import re import pandas as pd # ① 入出力パス log_path = Path("./logs/live_trade.log") out_dir = Path("./results") out_dir.mkdir(parents=True, exist_ok=True) csv_path = out_dir / "live_trade_log.csv" # ② 正規表現パターン a = (r"\[(?P<ts>.*?)\] Trade executed: " r"(?P<sym>\w+) (?P<side>\w+) (?P<size>[\d.]+) @ (?P<price>[\d.]+), " r"PnL: (?P<pnl>-?[\d.]+), Balance: (?P<bal>[\d.]+)") pat = re.compile(a) rows = [] with log_path.open() as f: for line in f: if (m := pat.search(line)): rows.append(dict( timestamp=m["ts"], symbol=m["sym"], side=m["side"], size=float(m["size"]), price=float(m["price"]), pnl=float(m["pnl"]), balance=float(m["bal"]))) if not rows: raise RuntimeError(f"❌ パースできる行が見つかりません: {log_path}") pd.DataFrame(rows).to_csv(csv_path, index=False) print(f"✅ 実運用ログを CSV に変換しました → {csv_path}")
簡易チェックリスト
- 列構成:
timestamp, symbol, side, size, price, pnl, balance
- 欠損ゼロ:
df.isnull().sum()
- 重複ゼロ:
df.duplicated().sum()
3. 比較スクリプト performance_comparison.py
import pandas as pd # ------------------------------------------------------------ def load_data(): """バックテストと実運用 CSV を読み込む""" bt = pd.read_csv('./results/backtest_result.csv') lv = pd.read_csv('./results/live_trade_log.csv') return bt, lv # ------------------------------------------------------------ def calculate_metrics(df): """主要 4 指標を返す""" n = len(df) win = df[df['pnl'] > 0] w% = len(win) / n * 100 if n else 0 pnl = df['pnl'].sum() dd = (df['balance'].cummax() - df['balance']).max() return { 'trades' : n, 'win_rate' : round(w% , 2), 'pnl_total' : round(pnl, 2), 'max_drawdown' : round(dd , 2) } # ------------------------------------------------------------ def compare(): bt, lv = load_data() bt_m = calculate_metrics(bt) lv_m = calculate_metrics(lv) print("\n📈 最終パフォーマンス比較") print(f"{'指標':<15} | {'シミュレーション':<12} | {'実運用':<12}") print("-" * 46) for k in bt_m: print(f"{k:<15} | {bt_m[k]:<12} | {lv_m[k]:<12}") # ------------------------------------------------------------ if __name__ == "__main__": compare()
4. 実行 & 出力例
$ python performance_comparison.py
📈 最終パフォーマンス比較 指標 | シミュレーション | 実運用 ---------------------------------------------- trades | 128 | 116 win_rate | 58.59 | 51.72 pnl_total | 2650.5 | 1780.1 max_drawdown | 420.25 | 690.8
5. 差分を読む:原因 × 改善
指標 | 代表的原因 | 代表的改善策 |
---|---|---|
trades | Bot 停止 / スケジュール漏れ | スケジューラ確認・例外復帰処理 |
win_rate | 遅延 / トリガー劣化 | スリッページ補正・閾値再設定 |
pnl_total | 手数料 / 成行偏重 | 指値+監視発注 / 多段利確 |
max_drawdown | SL 設計が甘い | ATR 等で動的 StopLoss |
6. 最終調整サンプル
# config.yaml before → after RSI_OVERSOLD : 30 → 35 RSI_OVERBOUGHT : 70 → 65 ATR_THRESHOLD :100 → 80 STOP_LOSS_PERCENT :4.2 → 3.0 TAKE_PROFIT_PERCENT:6.8 → 5.5
# トレンドフィルターを追加 df['ma_fast'] = df['close'].rolling(5).mean() df['ma_slow'] = df['close'].rolling(20).mean()
手順
- 調整を反映 → 再バックテスト (
backtester_export.py
) backtest_result.csv
を更新performance_comparison.py
を再実行 → 数値確認
7. まとめ & 次のアクション
- 比較 → 評価 → 調整 のステップ 2 を完了
- 指標が許容範囲なら 監視設計 (Slack 通知・Pod 監視など) を実装
- 次回 part.25 は デプロイ後の安定性確認 を掘り下げます。
📌 フローを自動化する場合は CI で CSV 出力 → 比較 → Slack レポートを回すと便利です。
-
-
開発記録#163(2025/4/2)「論文ベースのbot開発フローpart.25」
続きを見る
👇ラジオで話したこと
こんにちは、Yodakaです。
今回のラジオでは、「仮想通貨Botって、作った通りにちゃんと動いてるの?」というテーマでお話します。
というのも──Botを動かし始める前に「シミュレーションで勝ってた戦略」が、本番環境でもちゃんと勝ってるのか?って、確認しないと怖いですよね。
これを 「最終パフォーマンスチェック」 と呼んで、Bot開発の第2ステップに位置づけています。
🧩 概要:バックテスト vs 実運用の比較
Botって、最初は「過去のチャートでどう動くか」っていう**シミュレーション(バックテスト)**を通して設計します。でも実際にマーケットで動かすと──
- サーバー落ちてた!
- 注文通ってなかった!
- 約定(=注文が通ること)してなかった!
……なんてことが、しょっちゅうあるんですね。
だから「シミュレーション通りに動いてたのか?」をあとから数字で見比べるのが超重要になります。
🗂️ 1. データを準備する
まずは、**「シミュレーション結果」と「実運用の結果」**を、それぞれCSVファイルという表形式のデータにまとめます。
backtest_result.csv
(バックテストの記録)live_trade_log.csv
(本番Botのログ)
この2つができれば、あとはPythonでスクリプトを1本書いて比べるだけ。
🧪 2. どんな指標で比べるの?
比較する項目は、主に以下の4つです:
指標名 | 意味 |
---|---|
trades | トレードの回数(Botが何回売買したか) |
win_rate | 勝率(利益が出た割合) |
pnl_total | 合計の利益(損益) |
max_drawdown | 最大ドローダウン(口座が一番減った瞬間) |
例えば「シミュレーションでは120回トレードしてたのに、実運用では80回しかしてない」とか、「勝率が7割だったのに実運用では5割しかない」など、ズレをあぶり出します。
🧰 3. 比較スクリプトの一部(ざっくり)
def calculate_metrics(df): total = len(df) wins = df[df['pnl'] > 0] return { 'trades': total, 'win_rate': len(wins) / total * 100, ... }
こんな感じで、「勝ってるトレードの数」や「トレード回数」をカウントして指標を作ります。
⚠️ 4. ズレの原因と対策
ズレが出たときの原因と、それに対して何を調整すればいいかの例を紹介します。
ズレ内容 | よくある原因 | 対策 |
---|---|---|
トレード数が少ない | Botが止まっていた | ログで停止原因を調査 |
勝率が下がってる | 市場の動きが予想外だった | スリッページ補正を導入 |
PnLが低い | 注文が成行で高コスト | 指値で発注するよう修正 |
DDが大きい | 損切りラインが甘い | StopLossを強化 |
🔧 5. 最後にやること(最終調整)
もしズレがあれば、以下のようにパラメータを微調整します:
- RSIの基準値を見直す
- 利確や損切りの幅を変える
- トレンドフィルター(移動平均線)を導入する
そして、またバックテストして改善したかを確認。
これを**「数値で検証 → 修正 → 再検証」**とループして、精度を高めていきます。
✅ まとめ
最終パフォーマンスチェックは、言ってみれば「Botの健康診断」です。
頭の中で「勝てる!」と思って作った戦略でも、本番のマーケットは予測不能なことばかり。
だからこそ、「ズレてないか?」を数値で確認する習慣が大事です。
次回は、このBotをいよいよ「本番環境で安定稼働させる」ためのステップ──モニタリングと通知の整備についてお話しします。
ではまた、次回の放送でお会いしましょう!