Skip to main content
skill CX Codex

vectorbt — Claude Code skill: what it does, how to install

Runs vectorized backtests for trading strategies using NumPy and pandas array operations. It executes parameter grid searches and analyzes portfolio risk.

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

What vectorbt does

The skill teaches the coding agent how to evaluate trading strategies with the vectorbt Python library. Instead of processing historical bars in step-by-step loops, calculations rely on vector operations across pandas DataFrames. The agent generates boolean entry and exit arrays, then executes the simulation with vbt.Portfolio.from_signals().

The workflow uses built-in indicators or formulas from pandas-ta. Your Python environment requires uv pip install vectorbt pandas numpy before running scripts. The simulation accounts for transaction fees and price slippage.

Vectorization gives raw speed. The agent can test dozens of parameter combinations simultaneously in seconds. However, strategies requiring complex path-dependent execution rules will demand custom array restructuring before vectorbt can process them.

What it helps with

  • simulate trading strategies without bar-by-bar loops
  • run parameter grid search across moving average windows
  • calculate Sharpe ratio and maximum drawdown for a portfolio
  • evaluate historical trades with slippage and trading fees

Example prompts for the agent

  • Write a vectorbt backtest for an EMA crossover strategy with 0.3% fees
  • Run a grid search over RSI window parameters to maximize the Sharpe ratio
  • Compute trade stats and drawdown plots using OHLCV data from ohlcv.csv

How to install vectorbt

1Skills CLI (Vercel)

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

2Manually: put the files in place

~/.claude/skills/vectorbt/SKILL.md

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

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

Questions about vectorbt

How to install vectorbt in Claude Code?

Run npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a claude-code in your terminal.

What does vectorbt do?

It provides patterns to simulate trading strategies on array data, run parameter optimizations, and compute portfolio risk metrics.

Which Python libraries are required?

You need vectorbt, pandas, and numpy, with optional pandas-ta for technical indicators.

Source text

SKILL.md · MIT
---
name: vectorbt
description: High-performance vectorized backtesting with parameter optimization, portfolio simulation, and rich performance metrics
---

# Vectorized Backtesting with vectorbt

## Overview

vectorbt is a Python library for **vectorized backtesting** — running strategy simulations using NumPy/pandas array operations instead of bar-by-bar loops. This makes it 100–1000x faster than event-driven frameworks (backtrader, zipline), enabling parameter optimization across thousands of combinations in seconds.

**Key strengths:**
- Blazing speed via NumPy vectorization
- Built-in parameter grid search and optimization
- 50+ built-in performance metrics (Sharpe, Sortino, Calmar, max drawdown, profit factor)
- Rich plotting (equity curves, drawdowns, trade markers, heatmaps)
- Native pandas integration — your data stays in DataFrames throughout

## Installation

```bash
uv pip install vectorbt pandas numpy
```

vectorbt pulls in pandas, NumPy, and Plotly automatically. For technical indicators, also install pandas-ta:

```bash
uv pip install vectorbt pandas-ta
```

## Core Concepts

### 1. Signals — Boolean Entry/Exit Arrays

Strategies in vectorbt are expressed as boolean pandas Series (or arrays) indicating where to enter and exit positions:

```python
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 resolves conflicting signals automatically (you can't enter while already in a position).

### 2. Portfolio — The Backtesting Engine

`vbt.Portfolio.from_signals()` is the primary backtesting function. It takes price data and entry/exit signals, simulates trades, and computes performance:

```python
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. Metrics — Built-in Performance Analysis

```python
# 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. Parameter Optimization — Grid Search in Seconds

Pass arrays instead of scalars to test many parameter combos simultaneously:

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

## Basic Workflow

### Step 1: Load OHLCV Data

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

For Solana tokens, fetch data via the `birdeye-api` skill and load into a DataFrame.

### Step 2: Compute Indicators

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

### Step 3: Generate Entry/Exit Signals

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

### Step 4: Run Backtest

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

### Step 5: Analyze Results

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

## Key Portfolio Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `close` | Price series (pd.Series or DataFrame) | `df["close"]` |
| `entries` | Boolean entry signals | `fast > slow` |
| `exits` | Boolean exit signals | `fast < slow` |
| `init_cash` | Starting capital | `10_000` |
| `fees` | Fee per trade (fraction) | `0.003` (0.3%) |
| `slippage` | Slippage per trade (fraction) | `0.005` (0.5%) |
| `size` | Position size | `0.95` |
| `size_type` | How to interpret size | `"percent"`, `"amount"`, `"value"` |
| `freq` | Data frequency | `"1h"`, `"4h"`, `"1d"` |
| `direction` | Trade direction | `"both"`, `"longonly"`, `"shortonly"` |
| `accumulate` | Allow adding to positions | `False` |
| `sl_stop` | Stop-loss level (fraction) | `0.05` (5%) |
| `tp_stop` | Take-profit level (fraction) | `0.10` (10%) |

## Performance Metrics

### Returns
- `total_return()` — cumulative return over the period
- `annualized_return()` — annualized compound return
- `daily_returns()` — Series of daily returns

### Risk
- `max_drawdown()` — maximum peak-to-trough decline
- `annualized_volatility()` — annualized standard deviation of returns
- `value_at_risk()` — VaR at specified confidence level

### Risk-Adjusted
- `sharpe_ratio()` — excess return per unit volatility
- `sortino_ratio()` — excess return per unit downside deviation
- `calmar_ratio()` — annualized return / max drawdown
- `omega_ratio()` — probability-weighted gain/loss ratio

### Trade Statistics
- `trades.win_rate()` — fraction of profitable trades
- `trades.profit_factor()` — gross profit / gross loss
- `trades.expectancy()` — average P&L per trade
- `trades.avg_winning_trade()` — mean profit on winners
- `trades.avg_losing_trade()` — mean loss on losers
- `trades.count()` — total number of completed trades

## Parameter Optimization

### Grid Search

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

### Walk-Forward Validation

Always validate optimized parameters on out-of-sample data:

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

See `references/optimization_guide.md` for detailed walk-forward methodology and overfitting prevention.

## Crypto-Specific Considerations

### 24/7 Markets
Crypto markets never close. Use hourly or minute-based frequencies, not business-day frequencies:
```python
# 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")
```

### Realistic Fees
DEX swaps on Solana typically cost 0.25–1% including AMM fees. CEX spot fees are 0.05–0.1%.
```python
# 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)
```

### Slippage
Low-liquidity tokens can have 1–5% slippage. Always model this:
```python
# 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)
```

### Short History
Many tokens have less than 1 year of data. Be cautious about annualizing metrics from short samples.

## Common Strategy Patterns

### EMA Crossover
```python
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 Mean Reversion
```python
rsi = vbt.RSI.run(close, 14)
entries = rsi.rsi_crossed_below(30)
exits = rsi.rsi_crossed_above(70)
```

### Bollinger Band Breakout
```python
bb = vbt.BBANDS.run(close, window=20, alpha=2)
entries = close > bb.upper
exits = close < bb.lower
```

### Stop-Loss and Take-Profit
```python
pf = vbt.Portfolio.from_signals(
    close, entries, exits,
    sl_stop=0.05,    # 5% stop-loss
    tp_stop=0.10,    # 10% take-profit
)
```

## Related Skills

- **pandas-ta** — Technical indicator computation (feeds vectorbt signals)
- **birdeye-api** — Fetch Solana token OHLCV data for backtesting
- **trading-visualization** — Advanced chart generation for backtest results
- **portfolio-analytics** — Deeper portfolio-level risk/return analysis
- **position-sizing** — Optimal position sizing methodology
- **risk-management** — Portfolio-level risk guardrails
- **regime-detection** — Market regime awareness for adaptive strategies

## Files

### References
- `references/api_guide.md` — Complete vectorbt API reference for Portfolio, indicators, plotting, and data loading
- `references/optimization_guide.md` — Grid search, walk-forward validation, overfitting prevention, and optimization best practices

### Scripts
- `scripts/backtest_example.py` — Three-strategy backtest comparison using synthetic data (EMA crossover, RSI mean reversion, Bollinger breakout)
- `scripts/parameter_sweep.py` — EMA crossover parameter grid search with walk-forward validation

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

Similar skills

Everything for Finance and business →

From the same set55

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 backtrader A skill that teaches your agent to write backtests with the Python backtrader framework: bar-by-bar execution, bracket orders, commission and slippage. CX Codex +1 498installs 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 whale-tracking Tracks large Solana wallets on-chain: accumulation, distribution and smart money signals before they show up in price. CX Codex +1 493installs mean-reversion Statistical toolkit for mean-reversion trading strategies. Validates stationarity with ADF and Hurst tests, calculates half-life, and generates z-score trade signals. CX Codex +1 490installs portfolio-analytics Computes return, risk and risk-adjusted metrics from an equity curve and trade log. Useful after a backtest when you need to compare strategies or ship a report. CX Codex +1 489installs sentiment-analysis A skill that pulls and scores market sentiment from social media, news and on-chain data. Useful when you want to know where the crowd sits before you trade. CX Codex +1 476installs

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