Portfolio Construction (Single-Strategy Multi-Asset)¶
Build multi-asset portfolios with rebalancing using a single strategy.
What this notebook shows:
- How to build an equal-weight portfolio across multiple assets
- Monthly rebalancing within ONE strategy
- Portfolio construction with
order_target_percent
What this notebook does NOT show:
- Multiple independent strategies running simultaneously
- For multi-strategy portfolios (multiple strategies with isolated capital), see Notebook 09: Multi-Strategy Portfolio
Key Difference:
- This notebook: ONE strategy managing MULTIPLE assets
- Notebook 09: MULTIPLE strategies, each with independent capital and logic
📋 Notebook Information
- RustyBT Version: 0.1.2+
- Last Validated: 2025-11-07
- API Compatibility: Verified ✅
- Documentation: API Reference
In [1]:
Copied!
from rustybt import TradingAlgorithm
from rustybt.analytics import setup_notebook
from rustybt.api import order_target_percent, symbol
setup_notebook()
from rustybt import TradingAlgorithm
from rustybt.analytics import setup_notebook
from rustybt.api import order_target_percent, symbol
setup_notebook()
✅ Notebook environment configured successfully - Async/await support enabled - Pandas display options optimized - Progress bars configured
Equal-Weight Portfolio¶
In [2]:
Copied!
class EqualWeightPortfolio(TradingAlgorithm):
"""Equal-weight portfolio with monthly rebalancing."""
def initialize(self, context) -> None:
"""Initialize the portfolio strategy."""
# Define the assets in our portfolio
context.assets = [symbol(s) for s in ["SPY", "TLT", "GLD", "VNQ"]]
# Calculate target weight for each asset (equal weight)
context.target_weight = 1.0 / len(context.assets)
# Schedule monthly rebalancing (first trading day of each month)
from rustybt.api import schedule_function, date_rules, time_rules
schedule_function(
self.rebalance,
date_rules.month_start(),
time_rules.market_open()
)
def rebalance(self, context, data) -> None:
"""Rebalance portfolio to equal weights."""
for asset in context.assets:
# Set each asset to its target weight
order_target_percent(asset, context.target_weight)
# Example usage:
# To run this strategy, you would use run_algorithm():
#
# from rustybt.utils.run_algo import run_algorithm
# import pandas as pd
#
# results = run_algorithm(
# start=pd.Timestamp('2020-01-01', tz='utc'),
# end=pd.Timestamp('2023-12-31', tz='utc'),
# initialize=EqualWeightPortfolio().initialize,
# handle_data=EqualWeightPortfolio().handle_data,
# capital_base=100000.0,
# bundle='yfinance',
# data_frequency='daily',
# )
class EqualWeightPortfolio(TradingAlgorithm):
"""Equal-weight portfolio with monthly rebalancing."""
def initialize(self, context) -> None:
"""Initialize the portfolio strategy."""
# Define the assets in our portfolio
context.assets = [symbol(s) for s in ["SPY", "TLT", "GLD", "VNQ"]]
# Calculate target weight for each asset (equal weight)
context.target_weight = 1.0 / len(context.assets)
# Schedule monthly rebalancing (first trading day of each month)
from rustybt.api import schedule_function, date_rules, time_rules
schedule_function(
self.rebalance,
date_rules.month_start(),
time_rules.market_open()
)
def rebalance(self, context, data) -> None:
"""Rebalance portfolio to equal weights."""
for asset in context.assets:
# Set each asset to its target weight
order_target_percent(asset, context.target_weight)
# Example usage:
# To run this strategy, you would use run_algorithm():
#
# from rustybt.utils.run_algo import run_algorithm
# import pandas as pd
#
# results = run_algorithm(
# start=pd.Timestamp('2020-01-01', tz='utc'),
# end=pd.Timestamp('2023-12-31', tz='utc'),
# initialize=EqualWeightPortfolio().initialize,
# handle_data=EqualWeightPortfolio().handle_data,
# capital_base=100000.0,
# bundle='yfinance',
# data_frequency='daily',
# )