Returns
Daily return = today's price divided by yesterday's price, minus 1
Technical notationr_t = P_t / P_(t-1) - 1Turns price history into comparable percentage movements.
A reproducible ETF research workflow built around SQL market data, Python and pandas analytics, constrained portfolio optimization, MATLAB model comparison, walk-forward testing, and documented financial calculations.
The project asks whether a constrained ETF portfolio can improve risk-adjusted performance without using future data.
That is a credible outcome, not a weakness. The objective was risk-adjusted return under constraints, not manufacturing an unrealistic backtest.
In the published sample, the optimized portfolio had lower volatility, lower drawdown, lower daily VaR, and a higher Sharpe ratio than the benchmark.
The report is generated from a repeatable pipeline rather than one-off spreadsheet analysis.
Frozen adjusted prices are loaded and checked before calculations begin.
Queries use grouping, window functions, and validation checks around ticker/date records.
Pandas and NumPy calculate returns, covariance, volatility, drawdown, Sharpe, and VaR.
Constrained weights feed a walk-forward backtest, cost model, charts, and documented results.
At each rebalance, the optimizer only sees the previous 36 months. The chosen weights are then frozen for the next quarter.
Estimate expected returns and covariance using past data.
Hold the calculated weights out of sample.
Roll the estimation window forward by one quarter.
Evaluate the next period without exposing future observations.
Weights are estimated from the previous 36 months, then held until the next quarterly rebalance. Costs are charged when allocations change.
The strategy caps every asset at 30% and remains fully invested without leverage or short positions.
Selected rebalance snapshots show whether the optimizer is stable, dynamic, or repeatedly hitting the 30% asset cap.
Daily return correlations are estimated from the frozen research dataset.
| Strategy | Return | Volatility | Sharpe | Max drawdown | Daily VaR |
|---|---|---|---|---|---|
| Optimized portfolio | 12.2% | 11.7% | 0.79 | -18.3% | 1.1% |
| Benchmark (SPY) | 14.9% | 17.1% | 0.69 | -24.5% | 1.7% |
The main page keeps the math compact. The notebook contains the full implementation and outputs.
Daily return = today's price divided by yesterday's price, minus 1
Technical notationr_t = P_t / P_(t-1) - 1Turns price history into comparable percentage movements.
Portfolio risk depends on weights, asset volatility, and how assets move together
Technical notationportfolio variance = weights transposed x covariance matrix x weightsCaptures diversification effects that are not visible from single assets alone.
Sharpe ratio = return above the risk-free rate divided by portfolio volatility
Technical notationSharpe = (portfolio return - risk-free rate) / portfolio riskCompares return against the amount of risk required to earn it.
Find the best constrained asset mix for the selected objective
Technical notationmaximize Sharpe or minimize variance, with weights adding to 100% and each asset capped at 30%Keeps the allocation fully invested, long-only, and bounded.
The project emphasizes reviewable calculations, not just attractive charts.
Return calculations, weight normalization, asset caps, drawdowns, transaction costs, and backtest chronology are tested.
The minimum-variance optimization is reproduced in MATLAB and compared against Python within numerical tolerance.
Lookback period, rebalance frequency, maximum asset weight, risk-free rate, transaction cost, and benchmark are controlled from one research configuration.