Getting Started with RustyBT¶
This notebook provides a quick introduction to backtesting with RustyBT.
What you'll learn:
- Setting up the notebook environment
- Creating a simple trading strategy
- Running a backtest
- Visualizing results with interactive charts
- Exporting data for analysis
Estimated runtime: 2-3 minutes
📋 Notebook Information
- RustyBT Version: 0.1.2+
- Last Validated: 2025-11-07
- API Compatibility: Verified ✅
- Documentation: API Reference
1. Setup¶
First, let's configure the notebook environment and import required libraries.
In [1]:
Copied!
# Setup notebook environment
from rustybt.analytics import setup_notebook
setup_notebook()
# Import libraries
from rustybt import TradingAlgorithm
from rustybt.api import (
order,
set_commission,
set_slippage,
symbol,
)
from rustybt.finance.commission import PerShare
from rustybt.finance.slippage import VolumeShareSlippage
from rustybt.utils.run_algo import run_algorithm
from rustybt.analytics import plot_equity_curve, plot_returns_distribution
import pandas as pd
# Setup notebook environment
from rustybt.analytics import setup_notebook
setup_notebook()
# Import libraries
from rustybt import TradingAlgorithm
from rustybt.api import (
order,
set_commission,
set_slippage,
symbol,
)
from rustybt.finance.commission import PerShare
from rustybt.finance.slippage import VolumeShareSlippage
from rustybt.utils.run_algo import run_algorithm
from rustybt.analytics import plot_equity_curve, plot_returns_distribution
import pandas as pd
✅ Notebook environment configured successfully - Async/await support enabled - Pandas display options optimized - Progress bars configured
2. Create a Simple Strategy¶
Let's create a basic buy-and-hold strategy that purchases a stock at the start and holds it.
In [2]:
Copied!
class BuyAndHold(TradingAlgorithm):
"""Simple buy and hold strategy."""
def initialize(self, context) -> None:
"""Initialize strategy - runs once at start."""
# Configure trading costs
set_commission(PerShare(cost=0.001, min_trade_cost=1.0))
set_slippage(VolumeShareSlippage(volume_limit=0.025, price_impact=0.1))
# Store the asset we want to trade
context.asset = symbol("AAPL")
context.bought = False
def handle_data(self, context, data) -> None:
"""Called every trading period."""
# Buy once at the start
if not context.bought:
# Get current price
price = data.current(context.asset, "close")
# Calculate shares to buy (invest 100% of capital)
cash = context.portfolio.cash
shares = int(cash / price)
if shares > 0:
order(context.asset, shares)
context.bought = True
class BuyAndHold(TradingAlgorithm):
"""Simple buy and hold strategy."""
def initialize(self, context) -> None:
"""Initialize strategy - runs once at start."""
# Configure trading costs
set_commission(PerShare(cost=0.001, min_trade_cost=1.0))
set_slippage(VolumeShareSlippage(volume_limit=0.025, price_impact=0.1))
# Store the asset we want to trade
context.asset = symbol("AAPL")
context.bought = False
def handle_data(self, context, data) -> None:
"""Called every trading period."""
# Buy once at the start
if not context.bought:
# Get current price
price = data.current(context.asset, "close")
# Calculate shares to buy (invest 100% of capital)
cash = context.portfolio.cash
shares = int(cash / price)
if shares > 0:
order(context.asset, shares)
context.bought = True
3. Run Backtest¶
Now let's run the strategy over historical data.
In [3]:
Copied!
# Run the backtest
# Note: This requires a data bundle. See 02_data_ingestion.ipynb to set up data first.
#
# Example usage (uncomment after setting up a bundle):
# results = run_algorithm(
# start=pd.Timestamp('2020-01-01', tz='utc'),
# end=pd.Timestamp('2023-12-31', tz='utc'),
# initialize=BuyAndHold().initialize,
# handle_data=BuyAndHold().handle_data,
# capital_base=100000.0,
# bundle='yfinance', # or your bundle name
# data_frequency='daily',
# )
#
# print(f"Backtest complete! Final portfolio value: ${results['portfolio_value'].iloc[-1]:,.2f}")
# Run the backtest
# Note: This requires a data bundle. See 02_data_ingestion.ipynb to set up data first.
#
# Example usage (uncomment after setting up a bundle):
# results = run_algorithm(
# start=pd.Timestamp('2020-01-01', tz='utc'),
# end=pd.Timestamp('2023-12-31', tz='utc'),
# initialize=BuyAndHold().initialize,
# handle_data=BuyAndHold().handle_data,
# capital_base=100000.0,
# bundle='yfinance', # or your bundle name
# data_frequency='daily',
# )
#
# print(f"Backtest complete! Final portfolio value: ${results['portfolio_value'].iloc[-1]:,.2f}")
4. Visualize Results¶
Once you have results, you can create interactive visualizations.
In [4]:
Copied!
# After running backtest (see above), visualize results:
# Assuming you have 'results' from running the backtest:
# results = run_algorithm(...)
# Plot equity curve with drawdown
# fig = plot_equity_curve(results, show_drawdown=True)
# fig.show()
# Plot returns distribution
# fig = plot_returns_distribution(results)
# fig.show()
# After running backtest (see above), visualize results:
# Assuming you have 'results' from running the backtest:
# results = run_algorithm(...)
# Plot equity curve with drawdown
# fig = plot_equity_curve(results, show_drawdown=True)
# fig.show()
# Plot returns distribution
# fig = plot_returns_distribution(results)
# fig.show()
5. Analyze Performance Metrics¶
View key performance metrics from the results DataFrame.
In [5]:
Copied!
# After running backtest:
# Display key metrics
# print("Performance Summary:")
# print(f"Total Return: {results['returns'].sum():.2%}")
# print(f"Sharpe Ratio: {results['sharpe'].iloc[-1]:.2f}")
# print(f"Max Drawdown: {results['max_drawdown'].min():.2%}")
# print(f"Final Portfolio Value: ${results['portfolio_value'].iloc[-1]:,.2f}")
# After running backtest:
# Display key metrics
# print("Performance Summary:")
# print(f"Total Return: {results['returns'].sum():.2%}")
# print(f"Sharpe Ratio: {results['sharpe'].iloc[-1]:.2f}")
# print(f"Max Drawdown: {results['max_drawdown'].min():.2%}")
# print(f"Final Portfolio Value: ${results['portfolio_value'].iloc[-1]:,.2f}")
6. Export Data¶
Export results to different formats for further analysis.
In [6]:
Copied!
# Export to Polars for high-performance analysis
# import polars as pl
# results_pl = pl.from_pandas(results)
# Save to CSV
# results.to_csv('backtest_results.csv')
# Save to Parquet (efficient columnar format)
# results.to_parquet('backtest_results.parquet')
# Export to Polars for high-performance analysis
# import polars as pl
# results_pl = pl.from_pandas(results)
# Save to CSV
# results.to_csv('backtest_results.csv')
# Save to Parquet (efficient columnar format)
# results.to_parquet('backtest_results.parquet')
Next Steps¶
Now that you understand the basics, explore:
- 02_data_ingestion.ipynb - Learn how to fetch data from various sources
- 03_strategy_development.ipynb - Build more sophisticated strategies
- 04_performance_analysis.ipynb - Deep dive into performance metrics
- 10_full_workflow.ipynb - Complete end-to-end workflow
Key Takeaways¶
- ✅ RustyBT provides a clean API for strategy development
- ✅ Interactive visualizations make analysis easy
- ✅ Results can be exported to any format
- ✅ Built-in support for realistic trading costs
- ✅ Jupyter notebook integration with progress bars and async support