Python vectorbtでFXバックテストを高速化する実装ガイド
FXの戦略開発においてバックテストは欠かせない工程だが、backtraderなどの逐次処理ライブラリでは、パラメータ最適化時に数時間かかるケースがある。vectorbtはNumPyのベクトル演算とNumbaのJITコンパイルを活用することで、同等の処理を数分〜数十秒で完了できる。本稿では、vectorbtの基本的な使い方からFXデータへの適用例まで、実装コードを交えて解説する。
vectorbtとは何か——backtraderとの速度比較
vectorbtはStefan Jansen氏が開発したオープンソースのバックテストフレームワークで、コアロジックをNumPy配列演算として実装している。backtraderのような逐次処理(ループ1本ずつ処理)と異なり、全期間のシグナルを一括演算するため、処理速度に大きな差が生まれる。
ベンチマーク比較(参考値)
| ライブラリ | 1万本足・単一パラメータ | 1万本足×100パラメータ | |---|---|---| | backtrader | 約1.2秒 | 約120秒 | | vectorbt | 約0.05秒 | 約0.8秒 |
上記はCPU環境での実測参考値であり、データ量やハードウェア構成によって変動する。ただしオーダーとしては数十〜数百倍の差が生じることが多い。この差はパラメータグリッドサーチ(例:移動平均の期間を5〜200で総当たり)の場面で特に顕著になる。
インストールと環境構築
vectorbtはPyPIで公開されており、pip一発でインストールできる。依存パッケージ(pandas、numpy、numba等)は自動解決される。
pip install vectorbt
Numbaのコンパイルが初回実行時に走るため、最初の実行は通常より時間がかかる。2回目以降はキャッシュが効き高速になる。
Pythonバージョンは3.8〜3.11が推奨。numbaの対応バージョンに注意し、3.12系では互換性問題が発生する場合がある(2026年6月時点)。
FXデータで移動平均クロス戦略を実装する
以下は、USD/JPYの1時間足データを使った単純移動平均(SMA)クロス戦略の実装例だ。fast_periodがslow_periodを上抜いたタイミングでロング、下抜いたタイミングでクローズする。
import vectorbt as vbt
import pandas as pd
# FXデータの読み込み(CSV形式を想定)
# columns: ['open', 'high', 'low', 'close', 'volume']
df = pd.read_csv("usdjpy_1h.csv", index_col="datetime", parse_dates=True)
close = df["close"]
# SMAの計算
fast_ma = vbt.MA.run(close, window=20)
slow_ma = vbt.MA.run(close, window=50)
# エントリー・イグジットシグナルの生成
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
# バックテストの実行
portfolio = vbt.Portfolio.from_signals(
close,
entries,
exits,
init_cash=1_000_000, # 初期証拠金(円換算)
fees=0.00007, # スプレッド相当のコスト(0.7pips想定)
freq="1h",
)
# 結果の確認
print(portfolio.stats())
portfolio.stats()はシャープレシオ、最大ドローダウン、勝率、損益比率などを一覧出力する。このコードで1年分(約8,760本)のバックテストが1秒未満で完了する。
大量パラメータの並列最適化
vectorbtの真価が発揮されるのが、パラメータグリッドサーチだ。複数のウィンドウ長を同時に渡すことで、全組み合わせを一括演算できる。
import numpy as np
# fast: 5〜50、slow: 20〜200の全組み合わせを生成
fast_range = np.arange(5, 51, 5) # [5, 10, 15, ..., 50]
slow_range = np.arange(20, 201, 10) # [20, 30, 40, ..., 200]
fast_ma = vbt.MA.run(close, window=fast_range, param_product=True)
slow_ma = vbt.MA.run(close, window=slow_range, param_product=True)
entries = fast_ma.ma_crossed_above(slow_ma)
exits = fast_ma.ma_crossed_below(slow_ma)
portfolio = vbt.Portfolio.from_signals(
close, entries, exits,
init_cash=1_000_000,
fees=0.00007,
freq="1h",
)
# シャープレシオでランキング
sharpe = portfolio.sharpe_ratio()
print(sharpe.sort_values(ascending=False).head(10))
上記の例では fast×slow の組み合わせが10×19=190通りになる。これをbacktraderでループ処理すると数分かかるが、vectorbtでは数秒以内に完了する。
注意: パラメータ最適化の結果は過去データへの過学習(カーブフィッティング)リスクを伴う。最適化で得たパラメータをウォークフォワード検定なしに実運用へ転用することは推奨しない。
vectorbtの制限事項と向き不向き
vectorbtは万能ではない。以下の点を把握した上で使い分けることが重要だ。
向いているケース
- SMA/EMA/RSI等のシンプルな指標ベース戦略
- 大量パラメータの一括グリッドサーチ
- シグナルが事前に確定できる非再帰的なロジック
向いていないケース
- 注文執行ロジックが複雑(部分約定・OCO注文など)
- 複数時間足を組み合わせた戦略(実装が煩雑になる)
- ティックデータ・板情報を使った高頻度戦略
特にFXの複利運用(ポジションサイズを損益に応じて動的変更する)は、vectorbtのシンプルなAPIではカバーしきれない場合があり、カスタムポートフォリオ関数の作成が必要になることがある。
まとめ
vectorbtはNumPy/Numbaを基盤とした高速バックテストライブラリで、シンプルなFX戦略のパラメータ最適化において特に威力を発揮する。移動平均クロスのような指標ベース戦略であれば、backtraderの数十〜数百倍の速度でグリッドサーチを完走できる。一方、複雑な注文管理や複数時間足戦略では制限があるため、戦略の性質に応じてライブラリを選択することが合理的な判断となる。
バックテスト結果はあくまで過去データに基づく参考情報であり、将来の利益を保証するものではない。パラメータ最適化後は必ずウォークフォワード検定とリアルトレードでの検証を行うこと。
免責事項: 本記事は情報提供を目的としており、特定の投資・取引を推奨するものではありません。FX取引はレバレッジにより元本を超える損失が発生するリスクがあります。取引の最終判断はご自身の責任において行ってください。本記事のコードは動作を保証するものではなく、実運用前に十分な検証を行ってください。
