← All experiments

Experiment 003 · Asset allocation

Stocks, Bonds, and a Contextual Bandit

Follow one investor from age 22 through every quarter the shared data allows. Can a learning system build a better long-term path by choosing between U.S. stocks and bonds, or by continuously mixing the two?

Frozen backtest · loading…

intuition before equations

Two roads for the first $1,000

Stocks are usually the growth engine, while high-quality bonds are often the steadier counterweight. A fixed portfolio includes both. Here we ask whether an algorithm can use recent market information to choose the better investment for the next three months.

StocksSPY

Broad exposure to large U.S. companies through the S&P 500.

or
BondsAGG

Broad exposure to the U.S. investment-grade bond market.

Long-horizon backtest

What became of a lifetime of deposits?

Every path starts with $1,000 at age 22. The quarterly deposit also starts at $1,000 and then rises with inflation. This assumes the investor's wages, and therefore the amount available to invest, grow with the general price level. SPY and AGG stay put, 60/40 rebalances, the all-in bandit chooses one asset, and the contextual mix chooses an exact percentage of each.

Loading the frozen result…

the short version

Findings and Next Steps

What worked

The decisive bandit won this history

The all-in bandit finished at $617,689, ahead of SPY at $502,040, while also experiencing a smaller maximum drawdown. Its quarterly choice matched the better asset about 66% of the time.

What fell short

The smarter mix was not smarter enough

The contextual mix finished at $302,226, below the simple 60/40 portfolio at $310,981. Its cautious tilts reduced risk, but its forecasts did not add enough return to justify the extra machinery.

What I learned

One path can flatter a rule

The all-in result is striking, not conclusive. It comes from one ETF era with one frozen specification, and repeated quarterly deposits make timing and market regime especially important.

What I would try next

  • Test earlier stock and bond index proxies across more economic regimes.
  • Run rolling out-of-sample tests instead of judging one continuous path.
  • Stress-test taxes, execution costs, contribution timing, and simpler allocation rules.

Quarter by quarter

How did it split the money?

Each vertical slice is one quarter. Blue is the percentage in SPY and gold is the percentage in AGG. Hover or tap to see the exact mix and the all-in model’s choice.

how the machine thinks

Context changes the bet

A normal two-armed bandit remembers only which arm paid off. A contextual bandit also looks at the situation before choosing. We run it two ways: a classical all-in choice, plus a risk-aware contextual mix. The revised mix learns the return difference between SPY and AGG directly, retreats toward 60/40 when its estimate is uncertain, trims stock exposure when volatility is unusually high, and avoids small trades.

  1. 01

    Calculate the current signals

    At the end of each quarter, calculate six signals using only the adjusted prices available on that date. No information from the next quarter is used.

  2. 02

    Score the choice

    The all-in bandit keeps one reward model per asset. The mix uses one shared model for SPY’s next-quarter return minus AGG’s, which makes better use of its limited quarterly history.

  3. 03

    Explore when unsure

    The uncertainty bonus favors an asset in contexts the model has not seen often. The first two quarters also deliberately try one asset each.

  4. 04

    Choose or blend

    The all-in version takes the higher score. The mix starts from 60/40, tilts only when the relative-return forecast is convincing, stays between 15% and 90% SPY, and moves halfway toward each new target.

  5. 05

    Add the next deposit

    After the quarter’s growth is measured, the investor contributes to every strategy before the next allocation executes. The deposit starts at $1,000 per quarter and rises with CPI over time.

  6. 06

    Learn, then wait a day

    Only completed-quarter returns update the models. Each new allocation executes one full trading session after its context is observed.

Six signals only

The information used each quarter

These six features summarize recent trend, risk, market stress, and diversification. We keep the list short because the quarterly dataset is not large.

for those who want the symbols

The Math Zone

The intuition is “predicted reward plus curiosity.” Let a be an asset arm, q a quarter, and xq the six-signal context plus an intercept.

01 · context

What the model sees

xq=[1,m3m,m12m,v,d,ρ,τ]

Relative momentum at two horizons, a volatility gap, stock drawdown, stock-bond correlation, and relative trend distance.

02 · memory

Learned coefficients

θa=Aa1ba

Each asset maintains its own ridge-regression estimate of how context has related to its observed quarterly rewards.

03 · choose

LinUCB score

pa,q=θaTxq+αxqTAa1xq

The first term exploits the larger predicted reward. The square-root term explores uncertainty. Here α = 0.075, fixed in advance.

04 · blend

Risk-aware stock weight

d^q=θTxq,gq=11+2uqwq*=clip(0.60+0.30gqtanh(d^q0.05),0.15,0.90)wq=wq1+0.50(wq*wq1)

The model forecasts the SPY-minus-AGG return d̂. Uncertainty u reduces confidence g, pulling the target toward 60/40. A volatility guardrail can lower the target further, and changes under three percentage points are skipped.

05 · observe

Quarterly reward

ra,q=Pa,q+1Pa,q1

The selected or held ETFs’ adjusted close-to-close returns are observed only after the next quarter finishes.

06 · update

The observed models learn

AaAa+xqxqTbaba+ra,qxq

The all-in bandit updates only its chosen arm. Because the mix holds both ETFs, its shared model updates from the observed SPY-minus-AGG return every quarter.

07 · wealth + saving

The lifetime path

Cq=1000IqI0Vq+1=Vq(1+rqcq)+Cq

The deposit Cq starts at $1,000 and grows with CPI Iq, reflecting wages and investable income rising with the general price level. Growth happens first, then the deposit arrives. Reallocation costs 0.10% times turnover.

What this analysis can tell us

This is one historical path with two modern ETFs, and it should not be treated as a retirement recommendation. The investor reaches age 44 because that is where the available snapshot ends. We do not project any future results. AGG limits the shared history because it launched in September 2003. ETF adjusted prices provide a useful approximation of total returns, but they are not a point-in-time institutional index dataset. The test also ignores taxes and fund tracking differences. Finally, market relationships can change, so the result depends on the particular period tested.

Asset descriptions come from State Street’s SPY materials ↗ and iShares’ AGG materials ↗. The diversification framing follows the SEC’s Investor.gov guide ↗. Momentum horizons are informed by the published time-series momentum research ↗. The risk and turnover guardrails follow the practical concerns described in Markowitz Portfolio Construction at Seventy ↗ and Stanford’s work on portfolio optimization with transaction costs ↗. Volatility scaling is motivated by Moreira and Muir’s volatility-managed portfolios research ↗. The all-in learning rule is the disjoint linear model from the original LinUCB paper ↗. Quarterly contributions grow using the monthly seasonally adjusted CPI-U from the U.S. Bureau of Labor Statistics via FRED ↗. This experiment is for education and is not investment advice.