Built for Quantitative Finance course. Rebalances monthly across 30 randomly selected S&P 500 stocks.
- Assets: 30 randomly selected S&P 500 stocks (complete data since 2015)
- Period: 2015-2024
- Strategies: Equal-Weighted (EW), Value-Weighted (VW)
- Metrics: Sharpe Ratio, Information Ratio, Turnover vs S&P 500 benchmark
- Initial Capital: $1,000,000
10-Year Performance:
- Equal-Weighted: Higher volatility, potential outperformance
- Value-Weighted: Lower turnover, benchmark-aligned
- S&P 500: Market benchmark
- Risk-Free (2.5%): Conservative baseline
Key Statistics:
- Equal-Weighted Sharpe (Annual): ~0.74 | Turnover (Monthly): ~30.48%
- Value-Weighted Sharpe (Annual): ~0.38 | Turnover (Monthly): ~5.26%
# Filter stocks with complete data since 2015
df_prices_2015 = df_prices[df_prices['Dates'] >= "2015-01-01"]
stocks_with_complete_data = [col for col in df_prices_2015.columns
if df_prices_2015[col].notna().sum() / len(df_prices_2015) >= 0.95]
# Random selection with seed for reproducibility
np.random.seed(42)
stocks = np.random.choice(stocks_with_complete_data, 30, replace=False)# Monthly rebalancing to equal weights
target_weights = np.ones(n_assets) / n_assets
target_dollar_amounts = target_weights * total_value_before
new_shares = target_dollar_amounts / current_prices# Risk-adjusted return
annualized_return = (1 + avg_monthly_return) ** 12 - 1
annualized_std = monthly_std * np.sqrt(12)
sharpe_ratio = (annualized_return - 0.025) / annualized_stdWhat Worked:
- Equal-weighting provides diversification benefits across 30 stocks
- Monthly rebalancing captures mean-reversion opportunities
- Outperforms in bull markets with small-cap tilt
Next Steps:
- Add momentum factor to improve trend-following performance
- Test quarterly rebalancing to reduce transaction costs
- Implement stop-loss for tail risk protection
- Explore risk parity weighting scheme
