Python library for backtesting and analyzing trading strategies at scale
—
Comprehensive library of technical indicators and signal generation tools with factory pattern for creating custom indicators. Includes traditional indicators, advanced statistical measures, and sophisticated signal processing capabilities.
Built-in library of common technical indicators with vectorized implementations for high performance.
class MA:
"""
Moving Average indicator with multiple averaging methods.
Supports simple, exponential, weighted, and other moving average types
with full vectorization for efficient computation.
"""
@classmethod
def run(cls, close, window, ma_type='simple', **kwargs):
"""
Calculate moving average.
Parameters:
- close: pd.Series or pd.DataFrame, price data
- window: int, moving average window size
- ma_type: str, averaging method ('simple', 'exp', 'weighted')
- alpha: float, smoothing factor for exponential MA
- adjust: bool, adjust exponential MA calculation
Returns:
MA: Indicator instance with ma attribute
"""
def ma_crossed_above(self, other):
"""
Generate signals when MA crosses above another series.
Parameters:
- other: pd.Series or MA instance, comparison series
Returns:
pd.Series: Boolean crossing signals
"""
def ma_crossed_below(self, other):
"""Generate signals when MA crosses below another series."""
class MSTD:
"""Moving Standard Deviation indicator."""
@classmethod
def run(cls, close, window, **kwargs):
"""
Calculate moving standard deviation.
Parameters:
- close: pd.Series or pd.DataFrame, price data
- window: int, calculation window
- ddof: int, degrees of freedom (default: 1)
Returns:
MSTD: Indicator instance with mstd attribute
"""
class BBANDS:
"""
Bollinger Bands indicator with configurable parameters.
Calculates upper and lower bands based on moving average and
standard deviation with customizable multipliers.
"""
@classmethod
def run(cls, close, window=20, alpha=2.0, **kwargs):
"""
Calculate Bollinger Bands.
Parameters:
- close: pd.Series or pd.DataFrame, price data
- window: int, moving average window (default: 20)
- alpha: float, standard deviation multiplier (default: 2.0)
- ma_type: str, moving average type (default: 'simple')
Returns:
BBANDS: Indicator with upper, middle, lower attributes
"""
class RSI:
"""
Relative Strength Index momentum oscillator.
Measures speed and magnitude of price changes with values
ranging from 0 to 100, commonly used for overbought/oversold signals.
"""
@classmethod
def run(cls, close, window=14, **kwargs):
"""
Calculate RSI.
Parameters:
- close: pd.Series or pd.DataFrame, price data
- window: int, RSI calculation window (default: 14)
Returns:
RSI: Indicator instance with rsi attribute
"""
class MACD:
"""
Moving Average Convergence Divergence indicator.
Trend-following momentum indicator showing relationship between
two moving averages with signal line and histogram.
"""
@classmethod
def run(cls, close, fast_window=12, slow_window=26, signal_window=9, **kwargs):
"""
Calculate MACD.
Parameters:
- close: pd.Series or pd.DataFrame, price data
- fast_window: int, fast EMA period (default: 12)
- slow_window: int, slow EMA period (default: 26)
- signal_window: int, signal line EMA period (default: 9)
Returns:
MACD: Indicator with macd, signal, histogram attributes
"""
class STOCH:
"""Stochastic Oscillator indicator."""
@classmethod
def run(cls, high, low, close, k_window=14, d_window=3, **kwargs):
"""
Calculate Stochastic Oscillator.
Parameters:
- high: pd.Series or pd.DataFrame, high prices
- low: pd.Series or pd.DataFrame, low prices
- close: pd.Series or pd.DataFrame, close prices
- k_window: int, %K period
- d_window: int, %D smoothing period
Returns:
STOCH: Indicator with percent_k, percent_d attributes
"""
class ATR:
"""Average True Range volatility indicator."""
@classmethod
def run(cls, high, low, close, window=14, **kwargs):
"""
Calculate ATR.
Parameters:
- high: pd.Series or pd.DataFrame, high prices
- low: pd.Series or pd.DataFrame, low prices
- close: pd.Series or pd.DataFrame, close prices
- window: int, ATR period (default: 14)
Returns:
ATR: Indicator instance with atr attribute
"""
class OBV:
"""On-Balance Volume indicator."""
@classmethod
def run(cls, close, volume, **kwargs):
"""
Calculate OBV.
Parameters:
- close: pd.Series or pd.DataFrame, close prices
- volume: pd.Series or pd.DataFrame, volume data
Returns:
OBV: Indicator instance with obv attribute
"""Factory pattern for creating custom indicators and integrating external indicator libraries.
class IndicatorFactory:
"""
Factory for creating custom technical indicators.
Provides framework for building indicators with consistent interface,
parameter validation, and result caching.
"""
@classmethod
def create(cls, name, **kwargs):
"""
Create custom indicator.
Parameters:
- name: str, indicator name
- kwargs: indicator parameters
Returns:
IndicatorBase: Custom indicator instance
"""
class IndicatorBase:
"""
Base class for all indicators.
Provides common functionality including parameter management,
caching, and result access patterns.
"""
def __init__(self, **kwargs):
"""Initialize indicator with parameters."""
def run(self, *args, **kwargs):
"""Run indicator calculation (implemented by subclasses)."""
def talib(name, *args, **kwargs):
"""
Create indicator from TA-Lib library.
Parameters:
- name: str, TA-Lib function name
- args: input data arrays
- kwargs: function parameters
Returns:
IndicatorBase: TA-Lib indicator wrapper
"""
def pandas_ta(name, *args, **kwargs):
"""
Create indicator from pandas-ta library.
Parameters:
- name: str, pandas-ta function name
- args: input data
- kwargs: function parameters
Returns:
IndicatorBase: pandas-ta indicator wrapper
"""
def ta(name, *args, **kwargs):
"""
Create indicator from ta library.
Parameters:
- name: str, ta library function name
- args: input data
- kwargs: function parameters
Returns:
IndicatorBase: ta library indicator wrapper
"""Advanced signal generation system for creating entry/exit rules with support for complex conditional logic.
class SignalFactory:
"""
Factory for creating signal generators.
Provides framework for building custom signal generation logic
with parameter validation and consistent interfaces.
"""
@classmethod
def create(cls, name, **kwargs):
"""Create custom signal generator."""
class RAND:
"""Random signal generator for strategy testing."""
@classmethod
def run(cls, shape, prob=0.1, seed=None, **kwargs):
"""
Generate random boolean signals.
Parameters:
- shape: tuple, output shape (n_rows, n_cols)
- prob: float, probability of True signal (default: 0.1)
- seed: int, random seed for reproducibility
Returns:
pd.DataFrame: Random boolean signals
"""
class RANDX:
"""Random exit signal generator."""
@classmethod
def run(cls, entries, prob=0.1, seed=None, **kwargs):
"""
Generate random exit signals based on entries.
Parameters:
- entries: pd.Series or pd.DataFrame, entry signals
- prob: float, exit probability per period
- seed: int, random seed
Returns:
pd.DataFrame: Random exit signals
"""
class RANDNX:
"""Random entry/exit signal generator."""
@classmethod
def run(cls, shape, entry_prob=0.1, exit_prob=0.1, seed=None, **kwargs):
"""Generate random entry and exit signals."""
class RPROB:
"""Random probability signal generator."""
@classmethod
def run(cls, shape, prob_func=None, seed=None, **kwargs):
"""
Generate signals based on probability function.
Parameters:
- shape: tuple, output shape
- prob_func: callable, function returning probabilities
- seed: int, random seed
Returns:
pd.DataFrame: Probability-based signals
"""Sophisticated stop loss and take profit signal generation with trailing stops and conditional logic.
class STX:
"""Stop signal generator for exits."""
@classmethod
def run(cls, entries, stops, stop_type='stop_loss', **kwargs):
"""
Generate stop-based exit signals.
Parameters:
- entries: pd.Series or pd.DataFrame, entry signals
- stops: float or pd.Series, stop levels
- stop_type: str, stop type ('stop_loss', 'take_profit', 'trail_stop')
Returns:
pd.DataFrame: Stop-based exit signals
"""
class STCX:
"""Stop chain signal generator."""
@classmethod
def run(cls, entries, stops, **kwargs):
"""Generate chained stop signals."""
class OHLCSTX:
"""OHLC-based stop signal generator."""
@classmethod
def run(cls, entries, open, high, low, close, stops, **kwargs):
"""
Generate stop signals using OHLC data.
Parameters:
- entries: pd.Series or pd.DataFrame, entry signals
- open, high, low, close: pd.Series, OHLC price data
- stops: float or pd.Series, stop levels or percentages
Returns:
pd.DataFrame: OHLC-based stop signals
"""
class OHLCSTCX:
"""OHLC-based stop chain signal generator."""class StopType(IntEnum):
"""Stop signal types."""
StopLoss = 0
TrailStop = 1
TakeProfit = 2
class FactoryMode(IntEnum):
"""Signal factory modes."""
Entries = 0
Exits = 1
Both = 2
Chain = 3import vectorbt as vbt
# Download data
data = vbt.YFData.download("AAPL", start="2020-01-01", end="2023-01-01")
close = data.get("Close")
high = data.get("High")
low = data.get("Low")
volume = data.get("Volume")
# Calculate indicators
ma20 = vbt.MA.run(close, 20)
ma50 = vbt.MA.run(close, 50)
rsi = vbt.RSI.run(close, 14)
macd = vbt.MACD.run(close)
bbands = vbt.BBANDS.run(close, window=20, alpha=2.0)
# Access indicator values
ma20_values = ma20.ma
rsi_values = rsi.rsi
macd_line = macd.macd
macd_signal = macd.signal
upper_band = bbands.upper
lower_band = bbands.lower# Moving average crossover signals
entries = ma20.ma_crossed_above(ma50.ma)
exits = ma20.ma_crossed_below(ma50.ma)
# RSI overbought/oversold signals
rsi_oversold = rsi.rsi < 30
rsi_overbought = rsi.rsi > 70
# Bollinger Bands signals
bb_lower_touch = close <= bbands.lower
bb_upper_touch = close >= bbands.upper
# Combine multiple conditions
combined_entries = entries & rsi_oversold & bb_lower_touch
combined_exits = exits | rsi_overbought | bb_upper_touch# Using TA-Lib indicators
import talib
# Create TA-Lib indicator
stoch_k, stoch_d = vbt.talib('STOCH', high, low, close)
# Williams %R
willr = vbt.talib('WILLR', high, low, close, timeperiod=14)
# Commodity Channel Index
cci = vbt.talib('CCI', high, low, close, timeperiod=14)# Random signal testing
random_entries = vbt.RAND.run(
shape=close.shape,
prob=0.05, # 5% entry probability
seed=42
)
random_exits = vbt.RANDX.run(
entries=random_entries,
prob=0.1, # 10% exit probability per period
seed=42
)
# Stop loss signals
stop_exits = vbt.STX.run(
entries=entries,
stops=0.05, # 5% stop loss
stop_type='stop_loss'
)
# Trailing stop
trail_exits = vbt.STX.run(
entries=entries,
stops=0.03, # 3% trailing stop
stop_type='trail_stop'
)
# OHLC-based stops
ohlc_stops = vbt.OHLCSTX.run(
entries=entries,
open=data.get("Open"),
high=high,
low=low,
close=close,
stops=0.02 # 2% stop
)# Calculate indicators on different timeframes
daily_close = close.resample('D').last()
weekly_close = close.resample('W').last()
# Daily and weekly moving averages
daily_ma = vbt.MA.run(daily_close, 20)
weekly_ma = vbt.MA.run(weekly_close, 10)
# Align timeframes for comparison
weekly_ma_daily = weekly_ma.ma.reindex(close.index, method='ffill')
# Multi-timeframe signals
daily_signal = daily_ma.ma > daily_ma.ma.shift(1)
weekly_signal = weekly_ma_daily > weekly_ma_daily.shift(1)
combined_signal = daily_signal & weekly_signalclass CustomRSI(vbt.IndicatorBase):
"""Custom RSI with additional smoothing."""
def run(self, close, window=14, smooth_window=3):
# Calculate standard RSI
rsi = vbt.RSI.run(close, window)
# Apply additional smoothing
smoothed_rsi = vbt.MA.run(rsi.rsi, smooth_window)
return smoothed_rsi.ma
# Use custom indicator
custom_rsi = CustomRSI().run(close, window=14, smooth_window=3)Install with Tessl CLI
npx tessl i tessl/pypi-vectorbt