backtrader について
backtraderは、Pythonで取引開発を行う人向けのイベント駆動型バックテストフレームワークです。価格データをバー単位で処理し、注文やポジションをシミュレートします。内蔵ブローカー、複雑な注文管理、複数時間足の処理に対応します。
主な機能
- 01バー単位のイベント駆動型バックテスト
- 02成行、指値、逆指値、ブラケット注文
- 03手数料、スリッページ、証拠金のシミュレーション
- 04複数時間足データのリサンプリング
- 05内蔵のサイザーとパフォーマンス分析器
- 06カスタム指標とプロット
活用シーン
- 01注文の約定状況に依存する戦略を検証
- 02エントリー、損切り、利確のブラケット注文をテスト
- 03複数時間足の取引ロジックをシミュレート
- 04リターン、ドローダウン、取引記録を分析
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill backtraderインストール後、Claude Code で/backtraderを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api_guide.mdstrategy_patterns.mdscripts/backtest_strategy.pybracket_orders.py詳細
Backtrader
Backtraderは、データをバーごとに処理するPythonのイベント駆動型バックテストフレームワークです。組み込みのブローカー、注文管理、ポジション追跡によって、現実的な約定をシミュレートします。vectorbtやpandasなどのベクトル化フレームワークとは異なり、Backtraderは履歴を1バーずつ処理し、過去の約定、部分約定、条件付きブラケット注文に依存する複雑な注文ロジックを実装できるコールバックを呼び出します。
イベント駆動型とベクトル化の比較
| 項目 | Backtrader(イベント駆動型) | vectorbt(ベクトル化) |
|---|---|---|
| 実行モデル | バーごとのコールバック | 配列全体に対する操作 |
| 速度 | 遅い(Pythonのループ) | 高速(NumPy/Numba) |
| 注文タイプ | 成行、指値、逆指値、逆指値付き指値、ブラケット、OCO | 成行のみ(ネイティブ) |
| 現実性 | 手数料、スリッページ、証拠金に対応した組み込みブローカー | スリッページを手動でモデル化 |
| 複数時間足 | ネイティブのresampledata | 手動でアラインメント |
| 最適な用途 | 複雑な戦略、ブラケット注文、ポートフォリオ | 高速なパラメーターの総当たり、シンプルなシグナル |
次のような場合はBacktraderを使用します:
- ブラケット注文(エントリー+損切り+利確を1つの単位として扱う)
- 逆指値付き指値注文またはトレーリングストップ注文
- 注文に依存するロジック(最初の約定後に買い増す、N本のバー内に約定しなければキャンセルする)
- 複数時間足の戦略(日足シグナル、時間足での執行)
- 現実的な手数料とスリッページのモデル化
次のような場合はvectorbtを使用します:
- 数千通りの組み合わせによる高速なパラメーター最適化
- 複雑な注文管理を伴わないシンプルなロング/ショートのシグナル
- 結果の迅速なプロトタイピングと統計分析
コアコンセプト
Backtraderには、イベントループを介して連携する5つのコアオブジェクトがあります。
1. Cerebro(エンジン)
中心となるオーケストレーターです。Cerebroに戦略、データフィード、アナライザー、サイザーを追加してから、run()を呼び出します。
import backtrader as bt
cerebro = bt.Cerebro()
cerebro.addstrategy(MyStrategy, fast_period=10, slow_period=30)
cerebro.adddata(data_feed)
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 0.3%
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="sharpe")
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
cerebro.run()
2. Strategy(ロジック)
Strategyのサブクラスに、すべての取引ロジックを記述します。主なメソッドは次のとおりです。
__init__()— インジケーターを定義します。バックテスト開始前に1回実行されます。next()— バーごとに呼び出されます。ここで注文を出します。notify_order(order)— 注文ステータスが変化したとき(送信済み、受理済み、完了、キャンセル、証拠金不足、期限切れ)に呼び出されます。notify_trade(trade)— 取引が開始または終了したときに呼び出されます。ここで損益にアクセスできます。
class EMACrossover(bt.Strategy):
params = (
("fast_period", 10),
("slow_period", 30),
)
def __init__(self) -> None:
self.ema_fast = bt.ind.EMA(period=self.p.fast_period)
self.ema_slow = bt.ind.EMA(period=self.p.slow_period)
self.crossover = bt.ind.CrossOver(self.ema_fast, self.ema_slow)
def next(self) -> None:
if not self.position:
if self.crossover > 0:
self.buy()
elif self.crossover < 0:
self.close()
3. Data Feed
BacktraderのデータフィードはOHLCVのラインを提供します。最も一般的な方法は、pandasのDataFrameから読み込むことです。
import pandas as pd
df = pd.DataFrame({
"open": [...], "high": [...], "low": [...],
"close": [...], "volume": [...],
}, index=pd.DatetimeIndex([...]))
data = bt.feeds.PandasData(dataname=df)
cerebro.adddata(data)
CSVファイルの場合:
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # no open interest column
)
4. Broker
組み込みのブローカーは、設定可能な現金、手数料、スリッページを使って注文の約定をシミュレートします。
cerebro.broker.setcash(100_000)
cerebro.broker.setcommission(commission=0.003) # 0.3% per trade
# Cheat-on-open: execute at the open of the signal bar (avoids lookahead)
cerebro.broker.set_coo(True)
5. Analyzers
アナライザーは、バックテストの完了後にパフォーマンス指標を計算します。
cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name="sharpe",
riskfreerate=0.0, annualize=True, timeframe=bt.TimeFrame.Days)
cerebro.addanalyzer(bt.analyzers.DrawDown, _name="drawdown")
cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="trades")
cerebro.addanalyzer(bt.analyzers.Returns, _name="returns")
results = cerebro.run()
strat = results[0]
sharpe = strat.analyzers.sharpe.get_analysis()
dd = strat.analyzers.drawdown.get_analysis()
trades = strat.analyzers.trades.get_analysis()
注文タイプ
Backtraderは、現実的な暗号資産のバックテストに欠かせない複雑な注文タイプに対応しています。
成行注文
self.buy() # market buy
self.sell() # market sell
self.close() # close current position
指値注文
self.buy(exectype=bt.Order.Limit, price=95.0)
self.sell(exectype=bt.Order.Limit, price=105.0)
逆指値注文
価格が逆指値の水準に達すると、成行注文が発動します:
self.sell(exectype=bt.Order.Stop, price=90.0) # stop loss
逆指値付き指値注文
価格が逆指値の水準に達すると、指値注文が発動します:
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)
ブラケット注文
エントリー+損切り+利確を不可分の単位として扱います。損切りが約定すると、利確はキャンセルされます(逆の場合も同様です)。
self.buy_bracket(
price=100.0, # entry limit
stopprice=95.0, # stop loss
limitprice=110.0, # take profit
exectype=bt.Order.Limit,
stopexec=bt.Order.Stop,
limitexec=bt.Order.Limit,
)
ATRベースのストップを使ったブラケット注文のパターンについては、references/strategy_patterns.mdを参照してください。
ポジションサイジング(サイザー)
サイザーは、注文ごとに売買するユニット数を決定します。
# Fixed size
cerebro.addsizer(bt.sizers.FixedSize, stake=100)
# Percent of portfolio
cerebro.addsizer(bt.sizers.PercentSizer, percents=95)
# All available cash
cerebro.addsizer(bt.sizers.AllInSizer, percents=95)
カスタムサイザー:
class RiskSizer(bt.Sizer):
params = (("risk_pct", 0.02),)
def _getsizing(self, comminfo, cash, data, isbuy):
risk_amount = cash * self.p.risk_pct
atr = self.strategy.atr[0]
if atr <= 0:
return 0
size = risk_amount / atr
return int(size)
暗号資産に関する考慮事項
24時間365日の市場
暗号資産は24時間取引されています。日足バーを使用する場合、除外する週末はありません。特定の時間帯を分析する場合は、セッション時間を設定するか、sessionstart/sessionendを使用してください。
高い手数料
Solana上のDEXスワップでは、通常、取引ごとに0.25~0.30%の手数料がかかります。それに応じて手数料を設定してください:
cerebro.broker.setcommission(commission=0.003) # 0.3% round trip per side
小数単位でのサイジング
暗号資産は小数単位で取引できます。Backtraderはこれにネイティブで対応しているため、特別な設定は不要です。
スリッページ
現実的なシミュレーションを行うには、cheat-on-openを有効にし、スリッページを追加します:
cerebro.broker.set_coo(True)
cerebro.broker.set_slippage_perc(0.001) # 0.1% slippage
変動の大きいデータ
暗号資産のOHLCVデータには、極端に長いヒゲが含まれることがよくあります。ボラティリティに適応できるよう、固定パーセンテージのストップではなく、ATRベースのストップを使用してください。
マルチタイムフレーム
Backtrader では、単一のストラテジー内でデータを複数の時間足にリサンプリングできます。
data_1h = bt.feeds.PandasData(dataname=df_1h)
cerebro.adddata(data_1h)
# Resample 1h to daily
cerebro.resampledata(data_1h, timeframe=bt.TimeFrame.Days, compression=1)
ストラテジー内でのアクセス方法:
def __init__(self):
self.ema_1h = bt.ind.EMA(self.datas[0], period=20) # hourly
self.ema_daily = bt.ind.EMA(self.datas[1], period=20) # daily
カスタムインジケーター
class SpreadIndicator(bt.Indicator):
lines = ("spread", "zscore",)
params = (("period", 20),)
def __init__(self):
mean = bt.ind.SMA(self.data, period=self.p.period)
std = bt.ind.StdDev(self.data, period=self.p.period)
self.lines.spread = self.data - mean
self.lines.zscore = self.lines.spread / std
プロット
Backtrader には matplotlib ベースのプロット機能が含まれています。
cerebro.plot(style="candlestick", volume=True)
ヘッドレス環境では、ファイルに保存します。
import matplotlib
matplotlib.use("Agg")
figs = cerebro.plot(style="candlestick")
figs[0][0].savefig("backtest_result.png", dpi=150)
他のスキルとの連携
- pandas-ta:インジケーターを外部で計算し、データフィードの列として追加します。追加のラインの設定については、
references/api_guide.mdを参照してください。 - trading-visualization:
notify_tradeから取引ログをエクスポートし、ビジュアライゼーションスキルでプロットします。 - position-sizing:ケリー基準またはボラティリティ目標型のサイザーには、
position-sizingスキルを使用します。 - risk-management:
risk-managementスキルのポートフォリオレベルのガードレールをストラテジーのフィルターとして適用します。 - slippage-modeling:
slippage-modelingスキルのスリッページ推定値を使用して、set_slippage_percを設定します。
ファイル
リファレンス
references/api_guide.md— Cerebro、Strategy、Broker、Analyzer、Data Feed の API リファレンスreferences/strategy_patterns.md— 再利用可能なストラテジーパターン:クロスオーバー、平均回帰、マルチタイムフレーム、カスタムインジケーター
スクリプト
scripts/backtest_strategy.py— アナライザーと合成データを使用した、EMA クロスオーバーの完全なバックテストscripts/bracket_orders.py— RSI エントリーと ATR ベースのストップを使用したブラケット注文のデモ
クイックスタート
uv pip install backtrader pandas numpy matplotlib
python scripts/backtest_strategy.py --demo
python scripts/bracket_orders.py --demo