πŸ“œ Analysis 1 2026-05-11
PROMPT
Compare the returns of the following over the 10 year period ending Dec. 31, 2025: Vanguard 2025 TDF Vanguard 2030 TDF 80/20 stock/bond portfolio (Vanguard total stock market fund and total bond market fund)
Daily Driver
ChatGPT
GPT-5.4 Β· Medium
Claude
Opus 4.7 Β· Medium
Gemini
3.1 Pro Β· Medium

Bottom Line

Confidence:
Final Verified Code (22 lines)

Show code

import numpy as np
years = list(range(2016,2026))
vttvx = [7.48,15.94,-5.15,19.63,13.30,9.80,-15.55,14.55,9.44,14.60]
vthrx = [7.85,17.52,-5.86,21.07,14.10,11.38,-16.27,16.03,10.64,16.24]
vtsax = [12.66,21.17,-5.17,30.80,20.99,25.71,-19.53,26.01,23.74,17.12]
vbtlx = [2.60,3.56,-0.03,8.71,7.72,-1.67,-13.16,5.70,1.24,7.15]
p8020 = [0.8*s + 0.2*b for s,b in zip(vtsax,vbtlx)]

def cum_ann(rets):
    g = np.prod([1+r/100 for r in rets])
    ann = g**(1/len(rets)) - 1
    return (g-1)*100, ann*100

print(f"{'Fund':<12}{'Cumulative':>14}{'Annualized':>14}")
for name, r in [("VTTVX",vttvx),("VTHRX",vthrx),("80/20",p8020),("VTSAX (100%)",vtsax),("VBTLX (100%)",vbtlx)]:
    c,a = cum_ann(r)
    print(f"{name:<12}{c:>13.2f}%{a:>13.2f}%")

print("\n80/20 annual returns (rebalanced yearly):")
for y,r in zip(years,p8020): print(f" {y}: {r:6.2f}%")

Detailed Analysis

Expert Code (2 executions)
import math
vtsax = {2016:0.1238,2017:0.2108,2018:-0.0509,2019:0.3054,2020:0.2104,2021:0.2547,2022:-0.1949,2023:0.2605,2024:0.2352,2025:0.2180}
vbtlx = {2016:0.0260,2017:0.0356,2018:-0.0003,2019:0.0871,2020:0.0772,2021:-0.0167,2022:-0.1316,2023:0.0570,2024:0.0124,2025:0.0715}
# no rebalance
stock=0.8
bond=0.2
for y in sorted(vtsax):
    stock*=1+vtsax[y]
    bond*=1+vbtlx[y]
port=stock+bond
cagr=port**(1/10)-1
print('no rebalance growth', port, 'CAGR', cagr*100)
print('end stock weight', stock/port)
Output:
no rebalance growth 3.3707548935585216 CAGR 12.920480468061534
end stock weight 0.9277391758932342
Execution History (2 executions)
Execution 2 of 2: success (selected)
import math
vtsax = {2016:0.1238,2017:0.2108,2018:-0.0509,2019:0.3054,2020:0.2104,2021:0.2547,2022:-0.1949,2023:0.2605,2024:0.2352,2025:0.2180}
vbtlx = {2016:0.0260,2017:0.0356,2018:-0.0003,2019:0.0871,2020:0.0772,2021:-0.0167,2022:-0.1316,2023:0.0570,2024:0.0124,2025:0.0715}
# no rebalance
stock=0.8
bond=0.2
for y in sorted(vtsax):
    stock*=1+vtsax[y]
    bond*=1+vbtlx[y]
port=stock+bond
cagr=port**(1/10)-1
print('no rebalance growth', port, 'CAGR', cagr*100)
print('end stock weight', stock/port)
no rebalance growth 3.3707548935585216 CAGR 12.920480468061534
end stock weight 0.9277391758932342
Execution 1 of 2: success
import math

# Known annual total returns from sources gathered
vt2025 = {
    2016: 0.0748,
    2017: 0.1594,
    2018: -0.0515,
    2019: 0.1963,
    2020: 0.1330,
    2021: 0.0980,
    2022: -0.1555,
    2023: 0.1455,
    2024: 0.0944,
    2025: 0.1460,
}

vthrx = {
    2016: 0.0785,
    2017: 0.1752,
    2018: -0.0586,
    2019: 0.2107,
    2020: 0.1410,
    2021: 0.1138,
    2022: -0.1627,
    2023: 0.1603,
    2024: 0.1064,
    2025: 0.1633,  # from trust/select with same glidepath; used as approximation if needed
}

# Alternative 2025 estimate for VTHRX from 10y cumulative 140.13% on benchmark / 136.47% on trust select used for sensitivity
# VBTLX exact from source annual returns
vbtlx = {
    2016: 0.0260,
    2017: 0.0356,
    2018: -0.0003,
    2019: 0.0871,
    2020: 0.0772,
    2021: -0.0167,
    2022: -0.1316,
    2023: 0.0570,
    2024: 0.0124,
    2025: 0.0715,
}

# VTSAX annual total returns estimated from market/index-like annual returns for CRSP US Total Market / VTI-equivalent
# We use widely reported annual total returns for Vanguard Total Stock Market family for 2016-2025.
vtsax = {
    2016: 0.1238,
    2017: 0.2108,
    2018: -0.0509,
    2019: 0.3054,
    2020: 0.2104,
    2021: 0.2547,
    2022: -0.1949,
    2023: 0.2605,
    2024: 0.2352,
    2025: 0.2180,
}

def cagr(rdict):
    p=1.0
    for y in sorted(rdict):
        p*=1+rdict[y]
    return p**(1/10)-1, p

for name, data in [('VTTVX',vt2025),('VTHRXapprox',vthrx),('VBTLX',vbtlx),('VTSAXest',vtsax)]:
    c,p=cagr(data)
    print(name, 'growth', round(p,6), 'CAGR', round(c*100,4))

# exact 80/20 annual rebalanced portfolio from estimated VTSAX + exact VBTLX
w_stock=0.8; w_bond=0.2
p=1.0
rets=[]
for y in sorted(vtsax):
    r=w_stock*vtsax[y] + w_bond*vbtlx[y]
    rets.append((y,r))
    p*=1+r
print('80/20 annual returns:')
for y,r in rets:
    print(y, round(r*100,3))
print('80/20 growth', round(p,6), 'CAGR', round((p**(1/10)-1)*100,4))

# Sensitivity: if VTSAX 10y CAGR were 14.5,14.7,15.0 what would static blend CAGR be if solved annually impossible,
# approximate using CAGR blend and exact annual blend lower bound not used.
VTTVX growth 2.134156 CAGR 7.8754
VTHRXapprox growth 2.295571 CAGR 8.6648
VBTLX growth 1.217868 CAGR 1.9906
VTSAXest growth 3.908977 CAGR 14.6057
80/20 annual returns:
2016 10.424
2017 17.576
2018 -4.078
2019 26.174
2020 18.376
2021 20.042
2022 -18.224
2023 21.98
2024 19.064
2025 18.87
80/20 growth 3.152349 CAGR 12.1666

Detailed Analysis

Expert Code (1 execution)

import numpy as np
years = list(range(2016,2026))
vttvx = [7.48,15.94,-5.15,19.63,13.30,9.80,-15.55,14.55,9.44,14.60]
vthrx = [7.85,17.52,-5.86,21.07,14.10,11.38,-16.27,16.03,10.64,16.24]
vtsax = [12.66,21.17,-5.17,30.80,20.99,25.71,-19.53,26.01,23.74,17.12]
vbtlx = [2.60,3.56,-0.03,8.71,7.72,-1.67,-13.16,5.70,1.24,7.15]
p8020 = [0.8*s + 0.2*b for s,b in zip(vtsax,vbtlx)]

def cum_ann(rets):
    g = np.prod([1+r/100 for r in rets])
    ann = g**(1/len(rets)) - 1
    return (g-1)*100, ann*100

print(f"{'Fund':<12}{'Cumulative':>14}{'Annualized':>14}")
for name, r in [("VTTVX",vttvx),("VTHRX",vthrx),("80/20",p8020),("VTSAX (100%)",vtsax),("VBTLX (100%)",vbtlx)]:
    c,a = cum_ann(r)
    print(f"{name:<12}{c:>13.2f}%{a:>13.2f}%")

print("\n80/20 annual returns (rebalanced yearly):")
for y,r in zip(years,p8020): print(f" {y}: {r:6.2f}%")
Output:
Fund            Cumulative    Annualized
VTTVX              113.42%         7.88%
VTHRX              129.38%         8.66%
80/20              207.05%        11.87%
VTSAX (100%)       278.46%        14.24%
VBTLX (100%)        21.79%         1.99%

80/20 annual returns (rebalanced yearly):
 2016:  10.65%
 2017:  17.65%
 2018:  -4.14%
 2019:  26.38%
 2020:  18.34%
 2021:  20.23%
 2022: -18.26%
 2023:  21.95%
 2024:  19.24%
 2025:  15.13%

Detailed Analysis

Expert Code (3 executions)
vthrx_ret = [0.1624, 0.1064, 0.1603, -0.1627, 0.1138, 0.1410, 0.2107, -0.0586, 0.1752, 0.0785]
vttvx_ret = [0.1460, 0.0944, 0.1455, -0.1555, 0.0980, 0.1330, 0.1963, -0.0515, 0.1594, 0.0748]
vtsax_ret = [0.1712, 0.2374, 0.2601, -0.1953, 0.2571, 0.2099, 0.3080, -0.0517, 0.2117, 0.1266]
vbtlx_ret = [0.0715, 0.0124, 0.0570, -0.1316, -0.0167, 0.0772, 0.0871, -0.0003, 0.0356, 0.0260]

def calc_annualized(returns):
    val = 1.0
    for r in returns:
        val *= (1 + r)
    return val ** (1/len(returns)) - 1

blend_ret = [0.8 * s + 0.2 * b for s, b in zip(vtsax_ret, vbtlx_ret)]

print(f"VTTVX 10-year annualized: {calc_annualized(vttvx_ret):.4%}")
print(f"VTHRX 10-year annualized: {calc_annualized(vthrx_ret):.4%}")
print(f"80/20 Blend 10-year annualized: {calc_annualized(blend_ret):.4%}")
Output:
VTTVX 10-year annualized: 7.8754%
VTHRX 10-year annualized: 8.6564%
80/20 Blend 10-year annualized: 11.8719%
Execution History (3 executions)
Execution 3 of 3: success (selected)
vthrx_ret = [0.1624, 0.1064, 0.1603, -0.1627, 0.1138, 0.1410, 0.2107, -0.0586, 0.1752, 0.0785]
vttvx_ret = [0.1460, 0.0944, 0.1455, -0.1555, 0.0980, 0.1330, 0.1963, -0.0515, 0.1594, 0.0748]
vtsax_ret = [0.1712, 0.2374, 0.2601, -0.1953, 0.2571, 0.2099, 0.3080, -0.0517, 0.2117, 0.1266]
vbtlx_ret = [0.0715, 0.0124, 0.0570, -0.1316, -0.0167, 0.0772, 0.0871, -0.0003, 0.0356, 0.0260]

def calc_annualized(returns):
    val = 1.0
    for r in returns:
        val *= (1 + r)
    return val ** (1/len(returns)) - 1

blend_ret = [0.8 * s + 0.2 * b for s, b in zip(vtsax_ret, vbtlx_ret)]

print(f"VTTVX 10-year annualized: {calc_annualized(vttvx_ret):.4%}")
print(f"VTHRX 10-year annualized: {calc_annualized(vthrx_ret):.4%}")
print(f"80/20 Blend 10-year annualized: {calc_annualized(blend_ret):.4%}")
VTTVX 10-year annualized: 7.8754%
VTHRX 10-year annualized: 8.6564%
80/20 Blend 10-year annualized: 11.8719%
Execution 2 of 3: success
vttvx_ret = [0.1460, 0.0944, 0.1455, -0.1555, 0.0980, 0.1330, 0.1963, -0.0515, 0.1594, 0.0748]
vtsax_ret = [0.1712, 0.2374, 0.2601, -0.1953, 0.2571, 0.2099, 0.3080, -0.0517, 0.2117, 0.1266]
vbtlx_ret = [0.0715, 0.0124, 0.0570, -0.1316, -0.0167, 0.0772, 0.0871, -0.0003, 0.0356, 0.0260]

def calc_annualized(returns):
    val = 1.0
    for r in returns:
        val *= (1 + r)
    return val ** (1/len(returns)) - 1

blend_ret = [0.8 * s + 0.2 * b for s, b in zip(vtsax_ret, vbtlx_ret)]

print(f"VTTVX (2025) 10-year annualized: {calc_annualized(vttvx_ret):.4%}")
print(f"VTSAX 10-year annualized: {calc_annualized(vtsax_ret):.4%}")
print(f"VBTLX 10-year annualized: {calc_annualized(vbtlx_ret):.4%}")
print(f"80/20 (VTSAX/VBTLX) 10-year annualized (annual rebalance): {calc_annualized(blend_ret):.4%}")
VTTVX (2025) 10-year annualized: 7.8754%
VTSAX 10-year annualized: 14.2357%
VBTLX 10-year annualized: 1.9906%
80/20 (VTSAX/VBTLX) 10-year annualized (annual rebalance): 11.8719%
Execution 1 of 3: success
import datetime
print("Current Date:", datetime.date.today())
Current Date: 2026-05-06
πŸ“œ Analysis 2
πŸ“ˆ Cumulative Stats
Credits
15
Tokens
250,918