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.
npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a claude-codeWhat 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-code2Manually: put the files in place
~/.claude/skills/vectorbt/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/vectorbt/
1Skills CLI (Vercel)
npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a codex2Manually: put the files in place
.agents/skills/vectorbt/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a cursor2Manually: put the files in place
.cursor/skills/vectorbt/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install agiprolabs/claude-trading-skills vectorbt2Manually: put the files in place
.github/skills/vectorbt/SKILL.md1Skills CLI (Vercel)
npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a gemini-cli2Platform CLI
gemini skills install https://github.com/agiprolabs/claude-trading-skills --path skills/vectorbtManually: put the files in place
.devin/skills/vectorbt/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add agiprolabs/claude-trading-skills --skill vectorbt -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
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