vectorbt について
vectorbt は、クオンツトレーダーや研究者向けの Python ベクトル化バックテストライブラリです。pandas ベースのシグナル、パラメーター検索、パフォーマンス分析、描画を一つのワークフローで扱えます。
主な機能
- 01ベクトル化ポートフォリオのバックテスト
- 02ブール型のエントリー・決済シグナル
- 03パラメーターグリッド検索
- 04組み込みパフォーマンス指標
- 05バックテスト結果の描画
活用シーン
- 01価格データで取引戦略を検証
- 02パラメーターの組み合わせを比較
- 03リスクと取引統計を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill vectorbtインストール後、Claude Code で/vectorbtを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api_guide.mdoptimization_guide.mdscripts/backtest_example.pyparameter_sweep.py詳細
vectorbt によるベクトル化バックテスト
概要
vectorbt は、ベクトル化バックテスト用の Python ライブラリです。バーごとのループではなく、NumPy/pandas の配列演算を使って戦略シミュレーションを実行します。そのため、イベント駆動型フレームワーク(backtrader、zipline)よりも 100~1000 倍高速で、数千通りの組み合わせに対するパラメーター最適化を数秒で実行できます。
主な強み:
- NumPy のベクトル化による圧倒的な速度
- パラメーターのグリッド検索と最適化を標準搭載
- 50 種類以上の組み込みパフォーマンス指標(シャープレシオ、ソルティノレシオ、カルマーレシオ、最大ドローダウン、プロフィットファクター)
- 豊富なプロット機能(資産曲線、ドローダウン、取引マーカー、ヒートマップ)
- pandas とネイティブに統合されているため、データはすべて DataFrame のまま扱えます
インストール
uv pip install vectorbt pandas numpy
vectorbt は pandas、NumPy、Plotly を自動的にインストールします。テクニカル指標を使う場合は、pandas-ta もインストールしてください。
uv pip install vectorbt pandas-ta
基本概念
1. シグナル — ブール値のエントリー/エグジット配列
vectorbt の戦略は、ポジションへのエントリーとエグジットを行うタイミングを示す、ブール値の pandas Series(または配列)で表します。
import vectorbt as vbt
import pandas as pd
# Entry: buy when fast EMA crosses above slow EMA
entries = fast_ema > slow_ema
# Exit: sell when fast EMA crosses below slow EMA
exits = fast_ema < slow_ema
vectorbt は競合するシグナルを自動的に処理します(すでにポジションを保有している間はエントリーできません)。
2. Portfolio — バックテストエンジン
vbt.Portfolio.from_signals() は、主要なバックテスト関数です。価格データとエントリー/エグジットのシグナルを受け取り、取引をシミュレーションしてパフォーマンスを計算します。
pf = vbt.Portfolio.from_signals(
close=close_prices,
entries=entries,
exits=exits,
init_cash=10_000,
fees=0.003, # 0.3% per trade
slippage=0.005, # 0.5% slippage
freq="1h", # hourly data
)
3. 指標 — 組み込みのパフォーマンス分析
# Full stats summary
print(pf.stats())
# Individual metrics
print(f"Total Return: {pf.total_return():.2%}")
print(f"Sharpe Ratio: {pf.sharpe_ratio():.3f}")
print(f"Max Drawdown: {pf.max_drawdown():.2%}")
print(f"Win Rate: {pf.trades.win_rate():.2%}")
4. パラメーター最適化 — 数秒で実行できるグリッド検索
スカラーの代わりに配列を渡すと、多数のパラメーターの組み合わせを同時にテストできます。
import numpy as np
fast_periods = np.arange(5, 25, 2) # 10 values
slow_periods = np.arange(20, 60, 5) # 8 values
fast_ma = vbt.MA.run(close, fast_periods, short_name="fast")
slow_ma = vbt.MA.run(close, slow_periods, short_name="slow")
# This creates 80 parameter combinations automatically
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
基本的なワークフロー
ステップ 1:OHLCV データを読み込む
import pandas as pd
# From CSV
df = pd.read_csv("ohlcv.csv", parse_dates=["timestamp"], index_col="timestamp")
close = df["close"]
# From Yahoo Finance (traditional markets)
btc = vbt.YFData.download("BTC-USD", start="2023-01-01", end="2025-01-01")
close = btc.get("Close")
Solana トークンの場合は、birdeye-api スキルを使ってデータを取得し、DataFrame に読み込みます。
ステップ 2:指標を計算する
import pandas_ta as ta
# Using pandas-ta (see pandas-ta skill)
df.ta.ema(length=12, append=True)
df.ta.ema(length=26, append=True)
df.ta.rsi(length=14, append=True)
df.ta.bbands(length=20, std=2, append=True)
# Or using vectorbt built-ins
rsi = vbt.RSI.run(close, window=14)
bbands = vbt.BBANDS.run(close, window=20, alpha=2)
ステップ 3:エントリー/エグジットのシグナルを生成する
# EMA crossover
entries = df["EMA_12"] > df["EMA_26"]
exits = df["EMA_12"] < df["EMA_26"]
# RSI mean reversion
entries = rsi.rsi_below(30)
exits = rsi.rsi_above(70)
ステップ 4:バックテストを実行する
pf = vbt.Portfolio.from_signals(
close=close,
entries=entries,
exits=exits,
init_cash=10_000,
fees=0.003,
slippage=0.005,
size=0.95, # use 95% of available cash
size_type="percent",
freq="1h",
)
ステップ 5:結果を分析する
# Summary statistics
print(pf.stats())
# Trade-level analysis
trades = pf.trades.records_readable
print(f"\nTrade count: {len(trades)}")
print(f"Avg holding period: {trades['Duration'].mean()}")
# Equity curve
pf.plot().show()
# Drawdown chart
pf.drawdowns.plot().show()
主な Portfolio パラメーター
| パラメーター | 説明 | 例 |
|---|---|---|
close | 価格系列(pd.Series または DataFrame) | df["close"] |
entries | ブール値のエントリーシグナル | fast > slow |
exits | ブール値のエグジットシグナル | fast < slow |
init_cash | 初期資金 | 10_000 |
fees | 取引ごとの手数料(割合) | 0.003 (0.3%) |
slippage | 取引ごとのスリッページ(割合) | 0.005 (0.5%) |
size | ポジションサイズ | 0.95 |
size_type | サイズの解釈方法 | "percent", "amount", "value" |
freq | データ頻度 | "1h", "4h", "1d" |
direction | 取引方向 | "both", "longonly", "shortonly" |
accumulate | ポジションの追加を許可するか | False |
sl_stop | 損切り水準(割合) | 0.05 (5%) |
tp_stop | 利益確定水準(割合) | 0.10 (10%) |
パフォーマンス指標
リターン
total_return()— 期間全体の累積リターンannualized_return()— 年率換算の複利リターンdaily_returns()— 日次リターンの Series
リスク
max_drawdown()— ピークからボトムまでの最大下落率annualized_volatility()— リターンの年率換算標準偏差value_at_risk()— 指定した信頼水準での VaR
リスク調整後指標
sharpe_ratio()— ボラティリティ 1 単位あたりの超過リターンsortino_ratio()— 下方偏差 1 単位あたりの超過リターンcalmar_ratio()— 年率リターン / 最大ドローダウンomega_ratio()— 確率で重み付けした利益/損失比率
取引統計
trades.win_rate()— 利益が出た取引の割合trades.profit_factor()— 総利益 / 総損失trades.expectancy()— 取引あたりの平均損益trades.avg_winning_trade()— 勝ち取引の平均利益trades.avg_losing_trade()— 負け取引の平均損失trades.count()— 完了した取引の合計数
パラメーター最適化
グリッド検索
fast_windows = [5, 8, 12, 15, 20]
slow_windows = [20, 26, 30, 40, 50]
# Run all 25 combos at once
fast_ma = vbt.MA.run(close, fast_windows, short_name="fast")
slow_ma = vbt.MA.run(close, slow_windows, short_name="slow")
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
pf = vbt.Portfolio.from_signals(close, entries, exits, fees=0.003)
# Find best params by Sharpe
sharpe = pf.sharpe_ratio()
best_idx = sharpe.idxmax()
print(f"Best params: {best_idx}, Sharpe: {sharpe[best_idx]:.3f}")
ウォークフォワード検証
最適化したパラメーターは、必ずアウトオブサンプルデータで検証してください。
# Split: 70% train, 30% test
split_idx = int(len(close) * 0.7)
train_close = close.iloc[:split_idx]
test_close = close.iloc[split_idx:]
# Optimize on training data
# ... (run grid search on train_close)
# Validate best params on test data
# ... (run single backtest on test_close with best params)
ウォークフォワードの手法と過剰適合の防止について詳しくは、references/optimization_guide.md を参照してください。
暗号資産特有の考慮事項
24 時間 365 日の市場
暗号資産市場は休場しません。営業日ベースの頻度ではなく、時間単位または分単位の頻度を使用してください。
# Correct for crypto
pf = vbt.Portfolio.from_signals(close, entries, exits, freq="1h")
# Wrong — business days assume market closures
# pf = vbt.Portfolio.from_signals(close, entries, exits, freq="1B")
現実的な手数料
Solana の DEX スワップでは、AMM 手数料を含めて通常 0.25~1%の手数料がかかります。CEX の現物取引手数料は 0.05~0.1%です。
# Solana DEX (conservative)
pf = vbt.Portfolio.from_signals(close, entries, exits, fees=0.005)
# CEX spot
pf = vbt.Portfolio.from_signals(close, entries, exits, fees=0.001)
スリッページ
流動性の低いトークンでは、スリッページが 1~5%になることがあります。必ずこれをモデルに反映してください。
# High-liquidity (SOL, ETH): 0.1–0.5%
pf = vbt.Portfolio.from_signals(close, entries, exits, slippage=0.003)
# Low-liquidity memecoins: 1–3%
pf = vbt.Portfolio.from_signals(close, entries, exits, slippage=0.02)
短い履歴
多くのトークンのデータは 1 年未満です。短いサンプルから指標を年率換算する場合は注意してください。
一般的な戦略パターン
EMA クロスオーバー
fast = vbt.MA.run(close, 12, short_name="fast")
slow = vbt.MA.run(close, 26, short_name="slow")
entries = fast.ma_crossed_above(slow)
exits = fast.ma_crossed_below(slow)
RSI 平均回帰
rsi = vbt.RSI.run(close, 14)
entries = rsi.rsi_crossed_below(30)
exits = rsi.rsi_crossed_above(70)
ボリンジャーバンドのブレイクアウト
bb = vbt.BBANDS.run(close, window=20, alpha=2)
entries = close > bb.upper
exits = close < bb.lower
損切りと利益確定
pf = vbt.Portfolio.from_signals(
close, entries, exits,
sl_stop=0.05, # 5% stop-loss
tp_stop=0.10, # 10% take-profit
)
関連スキル
- pandas-ta — テクニカル指標の計算(vectorbt のシグナルに利用)
- birdeye-api — バックテスト用に Solana トークンの OHLCV データを取得
- trading-visualization — バックテスト結果の高度なチャート生成
- portfolio-analytics — ポートフォリオレベルでのより詳細なリスク/リターン分析
- position-sizing — 最適なポジションサイズを決定する方法
- risk-management — ポートフォリオレベルのリスク制御
- regime-detection — 適応型戦略のための市場レジームの把握
ファイル
参考資料
references/api_guide.md— Portfolio、指標、プロット、データ読み込みに関する vectorbt API の完全なリファレンスreferences/optimization_guide.md— グリッドサーチ、ウォークフォワード検証、過学習の防止、最適化のベストプラクティス
スクリプト
scripts/backtest_example.py— 合成データを使用した 3 つの戦略のバックテスト比較(EMA クロスオーバー、RSI 平均回帰、ボリンジャーブレイクアウト)scripts/parameter_sweep.py— ウォークフォワード検証を用いた EMA クロスオーバーのパラメーターグリッドサーチ