Selected work

Financial forecasting · MSc project, 2025

Exchange-rate forecasting

An out-of-sample comparison of random-walk, ARIMA, GARCH and structural exchange-rate models across multiple forecast horizons.

  • Python
  • ARIMA
  • GARCH
  • Monte Carlo

Challenge

Exchange rates are noisy, regime-sensitive and notoriously difficult to forecast. The central question was not which model best fits history, but whether added complexity produces reliable gains beyond a random-walk benchmark.

My role

I designed the empirical framework, implemented the models and simulations, and compared performance across three currency pairs and several forecast horizons.

Outcome

Random walks remained difficult to beat at one month. At longer horizons, structural hybrid models improved forecasts for EUR/USD and PEN/USD, while ZAR/USD produced no reliable signal.

At a glance

3currency pairs
1,000simulated paths per model
4forecast horizons

System view

The workflow.

A simplified view of the stages and boundaries that shape the project.

  1. 01Market data
  2. 02Stationarity checks
  3. 03Model estimation
  4. 04Simulation
  5. 05Forecasts
  6. 06Error analysis

Approach

Decisions that shaped the work.

01

Start with a hard benchmark

Random-walk forecasts provide the baseline that more complex time-series and structural models must beat.

02

Evaluate across horizons

Short-, medium- and longer-horizon results are kept separate because aggregate metrics can hide materially different behaviour.

03

Use simulation to inspect uncertainty

Monte Carlo analysis complements point estimates and helps distinguish a repeatable signal from a favourable sample.

Findings

What the evidence says.

  • At the one-month horizon, the random-walk benchmark was best or statistically tied across all three pairs.
  • Structural models with dynamic errors improved longer-horizon forecasts for EUR/USD and PEN/USD in the submitted evaluation.
  • ZAR/USD remained consistent with a random walk across the tested horizons, showing why conclusions must remain pair-specific.

Engineering reflection

Before treating the repository as production-ready, I would package the code, remove generated artefacts and enforce rolling-origin validation with a final untouched test window. That improvement is now part of the repository roadmap.