Market Forecasting
← Back to overview

DOCUMENTATION

How the experiment was built and evaluated

Complete technical write-up. Every number below comes from the Python pipeline artifacts.

1. Research question

Can price, volume, volatility, momentum, and market-context features improve short-term directional classification of SPY beyond a naive majority-class baseline when evaluated with leakage-safe walk-forward methodology?

2. Data

Primary instrument: SPY daily OHLCV (Yahoo Finance). Context series: VIX, 10-year Treasury yield (^TNX), and S&P 500 (^GSPC). History spans 2015-01-02 → 2026-09-01 (~10+ years; early rows warm up features).

Target: direction_next_day — 1 if Close_(t+1) > Close_t else 0. Features at time t use only information known at or before that day's close.

3. Feature engineering

29 trailing features. No centered windows. Groups: returns, trend, momentum, volatility, volume, market context.

FeatureLookbackIntuition
ret_1d1dImmediate price momentum / mean-reversion cue.
ret_2d2dVery short-horizon cumulative return.
ret_5d5dOne-week return.
ret_10d10dTwo-week return.
ret_20d20dApprox. one-month return.
close_sma55dPrice vs short moving average.
close_sma1010dPrice vs 10-day MA.
close_sma2020dPrice vs 20-day MA.
close_sma5050dPrice vs medium-term MA.
sma5_sma2020dShort vs intermediate trend alignment.
sma20_sma5050dIntermediate vs longer trend alignment.
rsi_1414dOverbought/oversold momentum oscillator.
macd26dTrend/momentum differential.
macd_signal_diff35dMACD histogram / signal crossover strength.
mom_1010dAbsolute 10-day price momentum.
vol_5d5dShort-horizon realized volatility (ann.).
vol_10d10d10-day realized volatility (ann.).
vol_20d20d20-day realized volatility (ann.).
atr_1414dNormalized average true range.
hl_range1dIntraday high-low range as % of close.
vol_pct_change1dDay-over-day volume change.
vol_sma20_ratio20dVolume relative to recent average.
vol_zscore_2020dVolume z-score vs 20-day history.
vix_level1dImplied volatility / fear gauge level.
vix_change_1d1dDaily change in implied volatility.
tnx_level1dTreasury yield level (rate regime).
tnx_change_5d5dShort-horizon yield move.
dist_from_high_2020dDistance from recent 20-day high.
dist_from_low_2020dDistance from recent 20-day low.

Reference model feature importance

XGBoost split importance (association, not causality). Top features shown below.

FeatureImportance
close_sma500.0396
atr_140.0389
vol_20d0.0389
close_sma200.0388
ret_20d0.0376
tnx_change_5d0.0369
tnx_level0.0367
sma20_sma500.0365
dist_from_high_200.0364
mom_100.0358
vol_10d0.0357
ret_1d0.0353

4. Models

  • Majority-class baseline
  • Logistic regression (scaled, class-weighted)
  • XGBoost classifier
  • Small neural net (MLP, early stopping)

Selected for trading: XGBoost by validation roc_auc, then f1. Selection used only pre-holdout walk-forward results; simulation window not used for tuning.

ModelAccuracyPrecisionRecallF1ROC-AUCvs Baseline
Majority Baseline54.79%54.79%100.00%0.7080.4700.00%
Logistic Regression51.81%57.69%45.19%0.5070.514-2.98%
XGBoostSELECTED51.94%56.05%56.89%0.5650.516-2.86%
Neural Net52.19%54.76%73.35%0.6270.497-2.60%

Confusion matrix (XGBoost): TN 327, FP 385, FN 372, TP 491.

5. Walk-forward validation

Random train/test splits are inappropriate for time series — they leak the future. This project uses an expanding training window and quarterly (~63-day) test folds. The final 500 trading days were held out from model selection.

FOLD K
TRAIN
TRAIN — historical data available at fold start
TEST
TEST — next unseen period
THEN EXPAND →
FOLD K + 1
TRAIN
TRAIN — larger historical data (prior test now eligible)
TEST
TEST — next unseen period

Random train/test splitting would leak future information into training and overstate accuracy. Walk-forward evaluation respects time: every prediction is made without seeing the future.

During the simulation, models were retrained on a walk-forward schedule: every 21 trading days (approximately monthly).

6. Trading rules & execution

  • If P(up) ≥ 0.5 → hold SPY; else cash
  • Signal after close t → execute at open t+1 (signal after close(t) → execute open(t+1))
  • Costs: 5 bps transaction + 2 bps slippage per side
  • Starting capital $1,000,000; no shorting or leverage
  • Window: Sep 4, 2024 → Sep 1, 2026 (500 days)

Trade ledger

All 127 fills from the simulation, paired into round-trips with entry/exit, hold time, and P&L after costs.

Round trips
63
Win rate
55.6%
Closed P&L
-$13,070
Open positions
1
#EntryExitHoldEntry $Exit $P&LReturnP(up)Status
1Sep 5, 2024Sep 9, 20244d$551.28$544.27-$12,710-1.27%0.503Closed
2Sep 10, 2024Oct 8, 202428d$548.74$570.02$38,281+3.88%0.540Closed
3Oct 10, 2024Oct 15, 20245d$576.17$584.18$14,254+1.39%0.547Closed
4Oct 16, 2024Oct 24, 20248d$580.19$579.57-$1,097-0.11%0.615Closed
5Oct 25, 2024Nov 1, 20247d$581.92$570.92-$19,630-1.89%0.604Closed
6Nov 4, 2024Nov 7, 20243d$571.58$592.66$37,594+3.69%0.569Closed
7Nov 8, 2024Nov 18, 202410d$596.59$585.81-$19,090-1.81%0.674Closed
8Nov 19, 2024Dec 19, 202430d$585.12$590.95$10,333+1.00%0.617Closed
9Dec 27, 2024Jan 6, 202510d$597.96$595.85-$3,690-0.35%0.590Closed
10Jan 7, 2025Jan 8, 20251d$597.84$588.29-$16,681-1.60%0.528Closed
11Jan 10, 2025Jan 13, 20253d$586.29$575.37-$19,144-1.86%0.537Closed
12Jan 16, 2025Jan 17, 20251d$594.59$596.54$3,318+0.33%0.574Closed
13Jan 21, 2025Feb 19, 202529d$601.09$609.65$14,412+1.42%0.714Closed
14Feb 20, 2025Mar 31, 202539d$611.97$549.45-$104,838-10.22%0.626Closed
15Apr 1, 2025Apr 7, 20256d$557.84$488.85-$113,946-12.37%0.568Closed
16Apr 8, 2025Apr 9, 20251d$522.23$493.09-$45,036-5.58%0.530Closed
17Apr 10, 2025Apr 11, 20251d$532.54$522.64-$14,170-1.86%0.519Closed
18Apr 17, 2025Apr 25, 20258d$528.01$546.27$25,871+3.46%0.581Closed
19Apr 28, 2025May 2, 20254d$551.78$564.33$17,617+2.28%0.516Closed
20May 6, 2025May 13, 20257d$558.32$583.00$34,995+4.42%0.555Closed
21May 27, 2025May 28, 20251d$586.48$591.15$6,576+0.80%0.651Closed
22May 30, 2025Jun 2, 20253d$589.34$587.35-$2,819-0.34%0.514Closed
23Jun 12, 2025Jun 13, 20251d$600.43$598.08-$3,249-0.39%0.516Closed
24Jun 23, 2025Jun 26, 20253d$595.46$608.56$18,207+2.20%0.588Closed
25Jun 27, 2025Jul 1, 20254d$613.31$615.93$3,611+0.43%0.607Closed
26Jul 2, 2025Jul 7, 20255d$617.67$622.92$7,218+0.85%0.559Closed
27Jul 8, 2025Jul 11, 20253d$621.78$622.30$715+0.08%0.573Closed
28Jul 16, 2025Jul 18, 20252d$624.18$628.86$6,429+0.75%0.645Closed
29Jul 21, 2025Jul 29, 20258d$629.21$637.90$11,927+1.38%0.559Closed
30Jul 30, 2025Aug 1, 20252d$636.37$625.86-$14,447-1.65%0.530Closed
31Aug 5, 2025Aug 19, 202514d$632.23$642.67$14,211+1.65%0.675Closed
32Aug 20, 2025Aug 28, 20258d$639.85$646.79$9,490+1.08%0.562Closed
33Aug 29, 2025Sep 16, 202518d$647.92$661.01$17,861+2.02%0.568Closed
34Sep 24, 2025Sep 26, 20252d$664.98$659.05-$8,043-0.89%0.502Closed
35Sep 29, 2025Oct 7, 20258d$664.83$672.07$9,745+1.09%0.559Closed
36Oct 9, 2025Oct 13, 20254d$674.00$660.19-$18,529-2.05%0.509Closed
37Oct 14, 2025Nov 3, 202520d$657.63$685.19$37,112+4.19%0.513Closed
38Nov 4, 2025Nov 14, 202510d$676.58$664.91-$15,913-1.72%0.528Closed
39Nov 18, 2025Nov 21, 20253d$662.56$654.59-$10,910-1.20%0.505Closed
40Nov 24, 2025Nov 25, 20251d$663.15$668.16$6,765+0.76%0.562Closed
41Nov 26, 2025Dec 4, 20258d$678.10$684.82$8,939+0.99%0.558Closed
42Dec 5, 2025Dec 11, 20256d$685.95$684.66-$1,713-0.19%0.503Closed
43Dec 15, 2025Dec 29, 202514d$686.22$687.06$1,112+0.12%0.550Closed
44Dec 30, 2025Jan 5, 20266d$687.93$686.06-$2,479-0.27%0.520Closed
45Jan 8, 2026Jan 13, 20265d$689.30$695.00$7,514+0.83%0.547Closed
46Jan 14, 2026Feb 9, 202626d$691.48$688.94-$3,373-0.37%0.521Closed
47Feb 10, 2026Feb 11, 20261d$695.44$695.90$612+0.07%0.576Closed
48Feb 12, 2026Feb 26, 202614d$694.73$692.79-$2,539-0.28%0.554Closed
49Feb 27, 2026Mar 3, 20264d$683.57$674.59-$11,964-1.31%0.506Closed
50Mar 4, 2026Mar 9, 20265d$682.11$665.92-$21,323-2.37%0.547Closed
51Mar 10, 2026Mar 23, 202613d$678.19$657.61-$26,631-3.04%0.531Closed
52Mar 24, 2026Apr 1, 20268d$651.78$653.44$2,175+0.26%0.532Closed
53Apr 2, 2026Apr 21, 202619d$646.87$709.78$82,950+9.73%0.617Closed
54Apr 22, 2026Apr 23, 20261d$709.65$709.00-$848-0.09%0.561Closed
55Apr 29, 2026Apr 30, 20261d$711.50$714.13$3,459+0.37%0.536Closed
56May 5, 2026May 11, 20266d$722.28$735.93$17,748+1.89%0.535Closed
57May 13, 2026May 14, 20261d$738.99$743.13$5,360+0.56%0.584Closed
58May 18, 2026May 27, 20269d$740.35$750.35$12,997+1.35%0.617Closed
59May 28, 2026May 29, 20261d$750.78$755.37$5,966+0.61%0.594Closed
60Jun 1, 2026Jun 3, 20262d$755.89$757.62$2,245+0.23%0.561Closed
61Jun 4, 2026Jun 5, 20261d$752.63$751.78-$1,101-0.11%0.522Closed
62Jun 8, 2026Jun 10, 20262d$743.88$732.88-$14,522-1.48%0.505Closed
63Jun 11, 2026Jul 31, 202650d$729.27$744.16$19,746+2.04%0.599Closed
64Aug 4, 2026——$761.16———0.599Open

Round-trips pair each SELL with the prior unclosed BUY. Prices include transaction costs and slippage. P&L is mark-to-fill for closed positions only.

7. Results

MetricML strategySPY buy & hold
Ending value$987,730$1,383,582
Total return-1.23%+38.27%
Sharpe0.0261.068
Max drawdown-32.44%-19.00%
Ann. volatility14.0%16.6%
Exposure76.8%100%

Simulation directional accuracy: 52.2%. Relative return vs benchmark: -39.49%.

8. Limitations & lessons

  • Daily equity direction is noisy; majority baselines are strong in uptrends.
  • Small accuracy differences can disappear after costs and next-open execution.
  • Leakage prevention and chronology matter more than flashy accuracy claims.
  • Yahoo Finance is convenient, not institutional-grade.
  • An attractive backtest does not prove future profitability.
← Return to overview