DATAUNION

QQQ, VTI, and TLT 3-Asset Portfolio Rebalancing Backtest (Full Guide + Python Code) 본문

Analysis

QQQ, VTI, and TLT 3-Asset Portfolio Rebalancing Backtest (Full Guide + Python Code)

DATAUNION 2025. 8. 8. 19:21
반응형

QQQ, VTI, and TLT 3-Asset Portfolio Rebalancing Backtest (Full Guide + Python Code)

Discover how a 3-asset portfolio of QQQ, VTI, and TLT performs under monthly and quarterly rebalancing strategies. Includes CAGR, volatility, and MDD comparison with Python code you can run for free on Google Colab.


Introduction

For long-term investors, portfolio rebalancing is a powerful yet often overlooked tool. By periodically adjusting your asset allocation back to target weights, you can manage risk, control drawdowns, and even improve returns.

In this guide, we will:

  • Introduce QQQ, VTI, and TLT as a diversified portfolio
  • Run a backtest from 2010 to 2025 using free tools
  • Compare monthly vs quarterly rebalancing performance
  • Provide ready-to-run Python code in Google Colab

1. Portfolio Overview

Ticker Asset Class Description
QQQ US Large-Cap Growth Tracks the Nasdaq-100 Index, heavily weighted in tech stocks.
VTI Total US Stock Market Includes large-, mid-, and small-cap US stocks.
TLT US Long-Term Treasury Bonds 20+ year maturity Treasuries; provides downside protection.

2. Data Download (Google Colab)

# !pip install yfinance pandas numpy matplotlib --quiet

import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

tickers = ["QQQ", "VTI", "TLT"]
start, end = "2010-01-01", "2025-01-01"

prices = yf.download(tickers, start=start, end=end)["Adj Close"].dropna()
returns = prices.pct_change().dropna()

prices.tail()

3. Rebalancing Backtest Function

def rebalance_backtest(prices, target_weights, freq="M", fee=0.0005):
    rets = prices.pct_change().fillna(0.0)
    if freq == "M":
        rebal_dates = prices.resample("M").last().index
    elif freq == "Q":
        rebal_dates = prices.resample("Q").last().index
    else:
        raise ValueError("freq must be M or Q")

    cols = list(target_weights.keys())
    weights = pd.Series(target_weights, index=cols, dtype=float)
    port_val = 1.0
    holdings = (weights * port_val) / prices.iloc[0][cols]

    port_vals = []
    for i in range(1, len(prices)):
        day_ret = (prices.iloc[i][cols] / prices.iloc[i-1][cols]) - 1.0
        holdings *= (1 + day_ret)
        port_val = (holdings * prices.iloc[i][cols]).sum()

        if prices.index[i] in rebal_dates:
            current_weights = (holdings * prices.iloc[i][cols]) / port_val
            turnover = (current_weights - weights).abs().sum()
            cost = port_val * fee * turnover
            port_val -= cost
            holdings = (weights * port_val) / prices.iloc[i][cols]

        port_vals.append(port_val)

    return pd.Series(port_vals, index=prices.index[1:])

4. Running the Backtest

target = {"QQQ":0.4, "VTI":0.4, "TLT":0.2}

eq_M = rebalance_backtest(prices, target, freq="M")
eq_Q = rebalance_backtest(prices, target, freq="Q")

def cagr(series):
    yrs = (series.index[-1] - series.index[0]).days / 365.25
    return (series.iloc[-1] / series.iloc[0]) ** (1/yrs) - 1

def vol(series):
    return series.pct_change().std() * np.sqrt(252)

def mdd(series):
    return ((series / series.cummax()) - 1).min()

summary = pd.DataFrame({
    "Monthly": [cagr(eq_M), vol(eq_M), mdd(eq_M)],
    "Quarterly": [cagr(eq_Q), vol(eq_Q), mdd(eq_Q)]
}, index=["CAGR","Volatility","MDD"])

print(summary)

plt.figure(figsize=(10,5))
(eq_M/eq_M.iloc[0]).plot(label="Monthly")
(eq_Q/eq_Q.iloc[0]).plot(label="Quarterly")
plt.legend()
plt.title("QQQ·VTI·TLT Portfolio Backtest")
plt.ylabel("Equity (Index=1)")
plt.grid(True)
plt.show()

5. Key Findings

  • Monthly rebalancing slightly reduces volatility but incurs higher trading costs.
  • Quarterly rebalancing saves costs with similar long-term returns.
  • Including TLT (20% allocation) significantly reduces maximum drawdown (MDD).

6. Practical Tips

  • Consider adding bonds if your portfolio is heavy on tech/growth stocks.
  • Match your rebalancing frequency to market volatility and trading fees.
  • Review and adjust your allocation at least once a year.

FAQ

Q1: Can I trade these ETFs outside the US?
Yes, most brokers worldwide allow trading of QQQ, VTI, and TLT through international accounts.

Q2: Which rebalancing period is better?
It depends on volatility and costs. Monthly is more responsive, quarterly is more cost-efficient.

Q3: Is TLT still a good hedge in rising rate environments?
Long-term Treasuries can lose value when rates rise, but they often rally in equity bear markets.


📥 Free Resources: Download the Google Colab template and a ready-made portfolio PDF from the link below. Perfect for backtesting your own assets.

🎯 Recommended Broker: Click here for low-fee ETF trading accounts.


 

반응형