/backtrader
Event-driven backtesting with bar-by-bar execution, complex order types, multiple analyzers, and custom indicators
$ npx -y skills add agiprolabs/claude-trading-skills --skill backtrader --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/backtrader
Context preview
The summary Claude sees to decide when to auto-load this skill.
Event-driven backtesting with bar-by-bar execution, complex order types, multiple analyzers, and custom indicators
SKILL.md
backtrader.SKILL.mdname: backtrader
description: Event-driven backtesting with bar-by-bar execution, complex order types, multiple analyzers, and custom indicators
Backtrader
Backtrader is a Python event-driven backtesting framework that processes data bar-by-bar, simulating realistic execution with a built-in broker, order management, and position tracking. Unlike vectorized frameworks (vectorbt, pandas), backtrader walks through history one bar at a time, firing callbacks that let you implement complex order logic that depends on previous fills, partial executions, and conditional brackets.
Event-Driven vs Vectorized
| Aspect | Backtrader (event-driven) | vectorbt (vectorized) | |---|---|---| | Execution model | Bar-by-bar callbacks | Whole-array operations | | Speed | Slower (Python loop) | Fast (NumPy/Numba) | | Order types | Market, limit, stop, stop-limit, bracket, OCO | Market only (native) | | Realism | Built-in broker with commission, slippage, margin | Manual slippage modeling | | Multi-timeframe | Native resampledata | Manual alignment | | Best for | Complex strategies, bracket orders, portfolio | Fast parameter sweeps, simple signals |
**Use backtrader when you need:**
- Bracket orders (entry + stop loss + take profit as a unit)
- Stop-limit or trailing stop orders
- Order-dependent logic (scale in after first fill, cancel if not filled in N bars)
- Multi-timeframe strategies (daily signals, hourly execution)
- Realistic commission and slippage modeling
**Use vectorbt when you need:**
- Fast parameter optimization over thousands of combinations
- Simple long/short signals without complex order management
- Quick prototyping and statistical analysis of results
---
Core Concepts
Backtrader has five core objects that interact through an event loop:
1. Cerebro (the engine)
The central orchestrator. You add strategies, data feeds, analyzers, and sizers to Cerebro, then call `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 (your logic)
A Strategy subclass contains all trading logic. Key methods:
- `__init__()` — Define indicators. Runs once before backtesting starts.
- `next()` — Called on every bar. Place orders here.
- `notify_order(order)` — Called when order status changes (submitted, accepted, completed, canceled, margin, expired).
- `notify_trade(trade)` — Called when a trade opens or closes. Access P&L here.
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 data feeds provide OHLCV lines. The most common approach is loading from a 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)For CSV files:
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # no open interest column
)4. Broker
The built-in broker simulates order execution with configurable cash, commission, and slippage.
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
Analyzers compute performance metrics after the backtest completes.
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()---
Order Types
Backtrader supports complex order types critical for realistic crypto backtesting.
Market Order
self.buy() # market buy
self.sell() # market sell
self.close() # close current position
Limit Order
self.buy(exectype=bt.Order.Limit, price=95.0)
self.sell(exectype=bt.Order.Limit, price=105.0)
Stop Order
Triggers a market order when price reaches the stop level:
self.sell(exectype=bt.Order.Stop, price=90.0) # stop loss
Stop-Limit Order
Triggers a limit order when price reaches the stop level:
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)
Bracket Order
Entry + stop loss + take profit as an atomic unit. If the stop fills, the take profit is canceled (and vice versa).
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,
)See `references/strategy_patterns.md` for bracket order patterns with ATR-based stops.
---
Position Sizing (Sizers)
Sizers determine how many units to buy/sell per order.
# Fixed size
cerebro.addsizer(b
Read more
name: backtrader description: Event-driven backtesting with bar-by-bar execution, complex order types, multiple analyzers, and custom indicators
Backtrader
Backtrader is a Python event-driven backtesting framework that processes data bar-by-bar, simulating realistic execution with a built-in broker, order management, and position tracking. Unlike vectorized frameworks (vectorbt, pandas), backtrader walks through history one bar at a time, firing callbacks that let you implement complex order logic that depends on previous fills, partial executions, and conditional brackets.
Event-Driven vs Vectorized
| Aspect | Backtrader (event-driven) | vectorbt (vectorized) | |---|---|---| | Execution model | Bar-by-bar callbacks | Whole-array operations | | Speed | Slower (Python loop) | Fast (NumPy/Numba) | | Order types | Market, limit, stop, stop-limit, bracket, OCO | Market only (native) | | Realism | Built-in broker with commission, slippage, margin | Manual slippage modeling | | Multi-timeframe | Native resampledata | Manual alignment | | Best for | Complex strategies, bracket orders, portfolio | Fast parameter sweeps, simple signals |
**Use backtrader when you need:**
- Bracket orders (entry + stop loss + take profit as a unit)
- Stop-limit or trailing stop orders
- Order-dependent logic (scale in after first fill, cancel if not filled in N bars)
- Multi-timeframe strategies (daily signals, hourly execution)
- Realistic commission and slippage modeling
**Use vectorbt when you need:**
- Fast parameter optimization over thousands of combinations
- Simple long/short signals without complex order management
- Quick prototyping and statistical analysis of results
---
Core Concepts
Backtrader has five core objects that interact through an event loop:
1. Cerebro (the engine)
The central orchestrator. You add strategies, data feeds, analyzers, and sizers to Cerebro, then call `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 (your logic)
A Strategy subclass contains all trading logic. Key methods:
- `__init__()` — Define indicators. Runs once before backtesting starts.
- `next()` — Called on every bar. Place orders here.
- `notify_order(order)` — Called when order status changes (submitted, accepted, completed, canceled, margin, expired).
- `notify_trade(trade)` — Called when a trade opens or closes. Access P&L here.
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 data feeds provide OHLCV lines. The most common approach is loading from a 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)For CSV files:
data = bt.feeds.GenericCSVData(
dataname="ohlcv.csv",
dtformat="%Y-%m-%d",
openinterest=-1, # no open interest column
)4. Broker
The built-in broker simulates order execution with configurable cash, commission, and slippage.
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
Analyzers compute performance metrics after the backtest completes.
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()---
Order Types
Backtrader supports complex order types critical for realistic crypto backtesting.
Market Order
self.buy() # market buy self.sell() # market sell self.close() # close current position
Limit Order
self.buy(exectype=bt.Order.Limit, price=95.0) self.sell(exectype=bt.Order.Limit, price=105.0)
Stop Order
Triggers a market order when price reaches the stop level:
self.sell(exectype=bt.Order.Stop, price=90.0) # stop loss
Stop-Limit Order
Triggers a limit order when price reaches the stop level:
self.buy(exectype=bt.Order.StopLimit, price=100.0, plimit=101.0)
Bracket Order
Entry + stop loss + take profit as an atomic unit. If the stop fills, the take profit is canceled (and vice versa).
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,
)See `references/strategy_patterns.md` for bracket order patterns with ATR-based stops.
---
Position Sizing (Sizers)
Sizers determine how many units to buy/sell per order.
# Fixed size cerebro.addsizer(b
A comprehensive collection of 67 ready-to-use trading, DeFi, and quantitative finance Agent Skills. Works with Claude Code, Cursor, Codex, Gemini CLI, and 30+ other tools.
Repo: agiprolabs/claude-trading-skills
Other skills on trading-skills.
- /birdeye-api
Solana token market data via Birdeye — prices, OHLCV, trades, token metadata, security checks, and trader activity
Open skill - /coingecko-api
Broad crypto market data from CoinGecko covering 13,000+ tokens. Global market stats, historical price data going back years, exchange volumes, trending tokens, and category filters. Best for macro analysis and long-term historical data.
Open skill - /cointegration-analysis
Cointegration testing for pairs trading using Engle-Granger, Johansen, and rolling stability analysis
Open skill - /copy-trading
Wallet evaluation, monitoring, and copy-trade strategy design for Solana DEX trading
Open skill - /correlation-analysis
Cross-asset correlation analysis including rolling correlation, hierarchical clustering, tail dependence, and regime-dependent correlation
Open skill - /cost-basis-engine
Multi-method cost basis computation including specific identification, FIFO, LIFO, HIFO, and proportional average cost with partial sell handling
Open skill

