Skip to main content
skill CX Codex

backtrader — Claude Code skill: bar-by-bar backtesting

A skill that teaches your agent to write backtests with the Python backtrader framework: bar-by-bar execution, bracket orders, commission and slippage.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add agiprolabs/claude-trading-skills --skill backtrader -a claude-code
Open on GitHub

What backtrader does

The skill hands your agent a reference for backtrader, an event-driven Python backtesting framework. History is walked one bar at a time and next() fires on each bar. That makes order logic depend on what happened before: scale in after a first fill, cancel an order that never filled within N bars.

It covers the five core objects — Cerebro as the engine, a Strategy subclass with next(), notify_order() and notify_trade(), data feeds from pandas or CSV, and the built-in broker with commission and sizing. Order types get their own section: market, limit, stop, stop-limit, plus bracket orders where entry, stop loss and take profit are placed as one unit. There are analyzer examples (SharpeRatio, DrawDown, TradeAnalyzer) and notes on crypto: markets that never close, and DEX swaps on Solana costing roughly 0.25–0.30% per trade.

This is guidance for the agent, not a runnable tool, so the project still needs Python and backtrader itself. Execution is a Python loop, which is why it loses to vectorized libraries on long histories and parameter sweeps. Chasing thousands of combinations on simple signals is the wrong job for it.

What it helps with

  • build a backtest with entry, stop loss and take profit as one unit
  • express logic that depends on previous fills and partial executions
  • fold commission and slippage into simulated fills
  • run a strategy across two timeframes: daily signal, hourly entry
  • get Sharpe, drawdown and per-trade stats after the run

Example prompts for the agent

  • write a backtrader strategy: EMA 10/30, enter on crossover, ATR-based stop loss
  • backtest a bracket order: limit entry with stop and take profit as one unit
  • add the SharpeRatio and DrawDown analyzers and print the results

How to install backtrader

1Skills CLI (Vercel)

npx skills add agiprolabs/claude-trading-skills --skill backtrader -a claude-code

2Manually: put the files in place

~/.claude/skills/backtrader/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/backtrader/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about backtrader

How do I install the backtrader skill in Claude?

Run npx skills add agiprolabs/claude-trading-skills --skill backtrader -a claude-code. The skill file then lives at ~/.claude/skills/backtrader/SKILL.md.

What does the backtrader skill do?

It gives your agent a reference for event-driven backtesting in Python: the bar-by-bar loop, the Strategy class, data feeds, a broker with commission, complex order types and result analyzers.

How is backtrader different from vectorbt?

Backtrader walks history bar by bar and supports bracket, stop-limit and trailing orders with a built-in broker. Vectorbt runs on whole arrays and is faster, but market orders are its only native type.

Source text

SKILL.md · MIT
---
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()`.

```python
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.

```python
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:

```python
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:

```python
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.

```python
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.

```python
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

```python
self.buy()  # market buy
self.sell()  # market sell
self.close()  # close current position
```

### Limit Order

```python
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:

```python
self.sell(exectype=bt.Order.Stop, price=90.0)  # stop loss
```

### Stop-Limit Order

Triggers a limit order when price reaches the stop level:

```python
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).

```python
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.

```python
# 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)
```

Custom sizer:

```python
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)
```

---

## Crypto Considerations

### 24/7 Markets

Crypto trades around the clock. When using daily bars, there are no weekends to skip. Set the session times or use `sessionstart`/`sessionend` if analyzing specific windows.

### High Fees

DEX swaps on Solana typically cost 0.25-0.30% per trade. Set commission accordingly:

```python
cerebro.broker.setcommission(commission=0.003)  # 0.3% round trip per side
```

### Fractional Sizing

Crypto allows fractional units. Backtrader supports this natively -- no special config needed.

### Slippage

For realistic simulation, enable cheat-on-open and add slippage:

```python
cerebro.broker.set_coo(True)
cerebro.broker.set_slippage_perc(0.001)  # 0.1% slippage
```

### Volatile Data

Crypto OHLCV data often has extreme wicks. Use ATR-based stops rather than fixed percentage stops to adapt to volatility.

---

## Multi-Timeframe

Backtrader can resample data to multiple timeframes within a single strategy:

```python
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)
```

Access in strategy:

```python
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
```

---

## Custom Indicators

```python
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
```

---

## Plotting

Backtrader includes matplotlib-based plotting:

```python
cerebro.plot(style="candlestick", volume=True)
```

For headless environments, save to file:

```python
import matplotlib
matplotlib.use("Agg")
figs = cerebro.plot(style="candlestick")
figs[0][0].savefig("backtest_result.png", dpi=150)
```

---

## Integration with Other Skills

- **pandas-ta**: Compute indicators externally, add as data feed columns. See `references/api_guide.md` for adding extra lines.
- **trading-visualization**: Export trade log from `notify_trade` and plot with the visualization skill.
- **position-sizing**: Use the `position-sizing` skill for Kelly or volatility-targeting sizers.
- **risk-management**: Apply portfolio-level guardrails from the `risk-management` skill as strategy filters.
- **slippage-modeling**: Use slippage estimates from the `slippage-modeling` skill to configure `set_slippage_perc`.

---

## Files

### References
- `references/api_guide.md` — Cerebro, Strategy, Broker, Analyzer, Data Feed API reference
- `references/strategy_patterns.md` — Reusable strategy patterns: crossover, mean reversion, multi-timeframe, custom indicators

### Scripts
- `scripts/backtest_strategy.py` — Complete EMA crossover backtest with analyzers and synthetic data
- `scripts/bracket_orders.py` — Bracket order demonstration with RSI entry and ATR-based stops

---

## Quick Start

```bash
uv pip install backtrader pandas numpy matplotlib
python scripts/backtest_strategy.py --demo
python scripts/bracket_orders.py --demo
```

© agiprolabs · MIT · agiprolabs/claude-trading-skills

Similar skills

Everything for Finance and business →

From the same set52

market-microstructure Reads the Solana DEX trade tape: buys versus sells, buyer and seller pressure, trade size distribution. Useful when you want to gauge flow in a token before entering. CX Codex +1 515installs trading-visualization Builds trading charts: candlesticks, equity curves, drawdowns, correlation heatmaps and return distributions. Useful when you need to review a strategy or put together a report. CX Codex +1 508installs exit-strategies Provides systematic exit rules, ATR stop-loss logic, and trailing stop strategies for crypto and Solana trading. Useful for automating disciplined position management. CX Codex +1 505installs strategy-framework Gives you one template for writing a trading strategy down: entry and exit rules, position sizing, risk limits, performance criteria. Useful when the idea exists but the document does not. CX Codex +1 500installs volatility-modeling Estimates crypto volatility, constructs volatility cones, and forecasts regimes via GARCH and EWMA. Useful for position sizing and stop placement. CX Codex +1 494installs ta-lib Provides C-optimized technical analysis with 150+ indicators and 61 candlestick patterns via TA-Lib. Essential for high-performance trading pipelines on large price datasets. CX Codex +1 493installs vectorbt Runs vectorized backtests for trading strategies using NumPy and pandas array operations. It executes parameter grid searches and analyzes portfolio risk. CX Codex +1 492installs whale-tracking Tracks large Solana wallets on-chain: accumulation, distribution and smart money signals before they show up in price. CX Codex +1 493installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor