Bot

開発記録#144(2025/3/25)「論文ベースのbot開発フローpart.6」

2025年3月25日

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

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

🚀 バックテスト環境の構築

以下のコードは、バックテストシステムを実装し、P&Dイベント検出後の取引パフォーマンスをシミュレーションするものです。


1. バックテスト設計のアプローチ

🔎 バックテストの主な機能

データ読み込み:過去データ (.csv) を使用し、時系列データをシミュレーション
P&Dイベント判定:検出モデルのデータを利用して、エントリー・エグジットのタイミングを評価
資金管理

  • エントリー金額、ロットサイズ、損切り (Stop Loss) / 利益確定 (Take Profit) の指定
    評価指標
  • 損益 (PnL)勝率最大ドローダウンシャープレシオ などを計算
    可視化
  • 成績をグラフで視覚化し、戦略の有効性を評価

2. コード実装 (backtest_engine.py)

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime

# ==============================
# 設定
# ==============================
INITIAL_BALANCE = 10000  # 初期資金 (USD)
TRADE_AMOUNT = 100       # 1回の取引額 (USD)
STOP_LOSS_PERCENT = 0.03  # 損切り (3%)
TAKE_PROFIT_PERCENT = 0.05  # 利確 (5%)

# データ読み込み
def load_data(data_path):
    df = pd.read_csv(data_path)
    df['timestamp'] = pd.to_datetime(df['timestamp'])
    df.set_index('timestamp', inplace=True)
    return df

# バックテストのロジック
def backtest(df, pnd_events):
    balance = INITIAL_BALANCE
    trade_log = []

    for _, event in pnd_events.iterrows():
        timestamp = pd.to_datetime(event['timestamp'])
        pump_price = event['pump_price']
        dump_price = event['dump_price']

        # エントリーポイントの選定
        entry_time = timestamp
        entry_price = pump_price

        # エグジット条件 (損切り / 利確)
        stop_loss_price = entry_price * (1 - STOP_LOSS_PERCENT)
        take_profit_price = entry_price * (1 + TAKE_PROFIT_PERCENT)

        # エントリー後の価格データ
        trade_window = df.loc[entry_time:].copy()

        # 利確/損切りの確認
        exit_price = None
        for index, row in trade_window.iterrows():
            if row['close'] >= take_profit_price:
                exit_price = take_profit_price
                result = "Win"
                break
            elif row['close'] <= stop_loss_price:
                exit_price = stop_loss_price
                result = "Loss"
                break
        else:
            exit_price = trade_window.iloc[-1]['close']
            result = "Hold"

        # 利益計算
        pnl = (exit_price - entry_price) * (TRADE_AMOUNT / entry_price)
        balance += pnl

        # トレード結果の記録
        trade_log.append({
            "Entry Time": entry_time,
            "Entry Price": entry_price,
            "Exit Price": exit_price,
            "Exit Time": index,
            "PnL": pnl,
            "Result": result
        })

    # トレード結果データフレーム
    trades_df = pd.DataFrame(trade_log)

    return trades_df, balance

# 評価指標の計算
def evaluate_performance(trades_df, initial_balance):
    total_trades = len(trades_df)
    wins = len(trades_df[trades_df['Result'] == 'Win'])
    losses = len(trades_df[trades_df['Result'] == 'Loss'])
    win_rate = (wins / total_trades) * 100 if total_trades > 0 else 0
    total_pnl = trades_df['PnL'].sum()
    final_balance = initial_balance + total_pnl
    max_drawdown = (initial_balance - trades_df['PnL'].cumsum().min()) / initial_balance * 100

    print("\n=== バックテスト結果 ===")
    print(f"総トレード数: {total_trades}")
    print(f"勝率: {win_rate:.2f}%")
    print(f"最終残高: ${final_balance:.2f}")
    print(f"最大ドローダウン: {max_drawdown:.2f}%")
    print(f"総損益 (PnL): ${total_pnl:.2f}")

# 結果の可視化
def plot_results(df, trades_df):
    plt.figure(figsize=(12, 6))
    plt.plot(df['close'], label='価格推移')
    for _, trade in trades_df.iterrows():
        plt.axvline(trade['Entry Time'], color='green' if trade['Result'] == 'Win' else 'red', linestyle='--')
    plt.title('バックテスト結果の可視化')
    plt.legend()
    plt.grid(True)
    plt.show()

# メイン処理
def main():
    df = load_data('./data/BTCUSDT_data.csv')
    pnd_events = pd.read_csv('./data/pnd_events.csv')
    
    trades_df, final_balance = backtest(df, pnd_events)
    evaluate_performance(trades_df, INITIAL_BALANCE)
    plot_results(df, trades_df)

if __name__ == "__main__":
    main()

3. 実行方法

1.requirements.txt のインストール

pip install pandas numpy matplotlib

2.スクリプトの実行

python backtest_engine.py

4. 出力結果の例

=== バックテスト結果 ===
総トレード数: 25
勝率: 60.00%
最終残高: $11200.50
最大ドローダウン: 8.20%
総損益 (PnL): $1200.50

📊 グラフ
✅ 緑線 → 勝ちトレードのエントリー
✅ 赤線 → 負けトレードのエントリー


5. 機能のポイント

データの自動読み込み:リアルデータとP&Dイベントデータに基づいたシミュレーション
複数の評価指標:勝率、最大ドローダウン、損益など多角的に評価
パラメータ調整が容易:STOP_LOSSやTAKE_PROFITの最適化が可能
グラフ可視化:価格推移とエントリーポイントを視覚的に確認


6. 次のステップ

次は、パフォーマンス評価とパラメータ調整に進み、次の内容を実装します。

  • 損切り (Stop Loss) / 利確 (Take Profit) の最適化
  • 最適なエントリータイミングの分析
  • P&Dイベントごとの特徴分析によるモデル改良
Yodaka

次の記事では、バックテストの結果を分析し、最適なパラメータを見つけるための評価システムの構築についてま止めます。

関連
開発記録#145(2025/3/25)「論文ベースのbot開発フローpart.7」

続きを見る

-Bot