Monthly Equal-Weight Bitcoin and Ethereum Rebalancing
Summary
This strategy maintains an equal-weight portfolio of Bitcoin and Ethereum using daily checks and monthly rebalancing. At each rebalance, it estimates target quantities from current portfolio value, divides value evenly between the two assets, and submits buy or sell orders to move existing positions toward those targets. It skips adjustments whose trade value is below a small minimum and uses Yahoo Finance data for the stated historical backtest period.
The code describes portfolio construction and execution mechanics rather than a return-seeking signal: it does not use forecasts, trend filters, or valuation measures. The document supplies no backtest performance, transaction cost assumptions, slippage analysis, or comparison beyond naming Bitcoin as the benchmark. Its rebalance tracking compares the month number without the year, so its behavior around year boundaries deserves scrutiny before relying on it in live trading.
Key ideas
- The portfolio targets equal weights in Bitcoin and Ethereum.\nThe strategy checks prices daily and adjusts holdings on the first iteration of each month.\nTrade sizes are based on the difference between current and target quantities.\nSmall trade adjustments below a stated value threshold are skipped.\nThe document gives a backtest setup but reports no performance or trading-cost evidence.
Tags
Full text
# crypto_50_50.py
```py
"""
Crypto 50/50
Asset class: Crypto
Data source: Yahoo Finance (free)
Description: Equal-weight Bitcoin and Ethereum portfolio with monthly rebalancing.
"""
from datetime import datetime
from lumibot.strategies import Strategy
from lumibot.backtesting import YahooDataBacktesting
class Crypto5050(Strategy):
parameters = {
"assets": ["BTC-USD", "ETH-USD"],
"rebalance_day": 1,
}
def initialize(self):
self.sleeptime = "1D"
self.vars.last_rebalance_month = None
def on_trading_iteration(self):
current_date = self.get_datetime().date()
assets = self.parameters["assets"]
weight = 1.0 / len(assets)
# Rebalance on first iteration or first trading day of each month
if (
not self.first_iteration
and self.vars.last_rebalance_month == current_date.month
):
return
portfolio = self.portfolio_value
for symbol in assets:
price = self.get_last_price(symbol)
if not price:
continue
target_qty = (portfolio * weight) / price
current_position = self.get_position(symbol)
current_qty = current_position.quantity if current_position else 0
diff = target_qty - current_qty
if abs(diff * price) < 10:
continue
if diff > 0:
self.submit_order(self.create_order(symbol, diff, "buy"))
elif diff < 0:
self.submit_order(self.create_order(symbol, abs(diff), "sell"))
self.vars.last_rebalance_month = current_date.month
self.log_message(f"Rebalanced: equal weight across {assets}")
if __name__ == "__main__":
Crypto5050.backtest(
YahooDataBacktesting,
datetime(2021, 1, 1),
datetime(2024, 1, 1),
benchmark_asset="BTC-USD",
)
```Shown in full with attribution under the source's licence. Licence: MIT
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.