Skip to content
All library documents

Monthly Equal-Weight Bitcoin and Ethereum Rebalancing

Code Lumibot strategies

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.