{"spec_id":"frontier-efficient","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nfrontier-efficient: Efficient Frontier for Portfolio Optimization\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 85/100 | Updated: 2026-05-17\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import (\n    LetsPlot,\n    aes,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_line,\n    geom_point,\n    ggplot,\n    ggsave,\n    ggsize,\n    labs,\n    scale_color_viridis,\n    theme,\n    theme_minimal,\n)\n\n\nLetsPlot.setup_html()\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nRULE = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Okabe-Ito palette\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\"]\n\n# Generate simulated asset data\nnp.random.seed(42)\nn_assets = 6\nn_portfolios = 300\nrisk_free_rate = 0.03\n\n# Asset expected returns and volatilities\nasset_returns = np.array([0.08, 0.10, 0.12, 0.15, 0.07, 0.18])\nasset_volatility = np.array([0.12, 0.15, 0.18, 0.25, 0.10, 0.30])\n\n# Correlation matrix\ncorr_matrix = np.array(\n    [\n        [1.00, 0.30, 0.25, 0.20, 0.50, 0.15],\n        [0.30, 1.00, 0.40, 0.35, 0.25, 0.30],\n        [0.25, 0.40, 1.00, 0.50, 0.20, 0.45],\n        [0.20, 0.35, 0.50, 1.00, 0.15, 0.60],\n        [0.50, 0.25, 0.20, 0.15, 1.00, 0.10],\n        [0.15, 0.30, 0.45, 0.60, 0.10, 1.00],\n    ]\n)\ncov_matrix = np.outer(asset_volatility, asset_volatility) * corr_matrix\n\n# Generate random portfolios\nportfolio_returns = []\nportfolio_risks = []\nsharpe_ratios = []\n\nfor _ in range(n_portfolios):\n    weights = np.random.random(n_assets)\n    weights /= np.sum(weights)\n    port_return = np.sum(weights * asset_returns)\n    port_vol = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))\n    portfolio_returns.append(port_return)\n    portfolio_risks.append(port_vol)\n    sharpe_ratios.append((port_return - risk_free_rate) / port_vol)\n\n# Generate efficient frontier\ntarget_returns = np.linspace(0.07, 0.18, 50)\nfrontier_risks = []\nfrontier_returns = []\n\nfor target in target_returns:\n    best_risk = float(\"inf\")\n    for _ in range(2000):\n        weights = np.random.random(n_assets)\n        weights /= np.sum(weights)\n        port_return = np.sum(weights * asset_returns)\n        port_vol = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))\n        if abs(port_return - target) < 0.003 and port_vol < best_risk:\n            best_risk = port_vol\n    if best_risk < float(\"inf\"):\n        frontier_risks.append(best_risk)\n        frontier_returns.append(target)\n\n# Find special portfolios\nmin_var_idx = np.argmin(frontier_risks)\nmin_var_risk = frontier_risks[min_var_idx]\nmin_var_return = frontier_returns[min_var_idx]\n\nsharpe_frontier = [(r - risk_free_rate) / s for r, s in zip(frontier_returns, frontier_risks, strict=False)]\nmax_sharpe_idx = np.argmax(sharpe_frontier)\ntangency_risk = frontier_risks[max_sharpe_idx]\ntangency_return = frontier_returns[max_sharpe_idx]\n\n# DataFrames\ndf_portfolios = pd.DataFrame({\"risk\": portfolio_risks, \"return\": portfolio_returns, \"sharpe\": sharpe_ratios})\ndf_frontier = pd.DataFrame({\"risk\": frontier_risks, \"return\": frontier_returns})\ndf_special = pd.DataFrame(\n    {\n        \"risk\": [min_var_risk, tangency_risk],\n        \"return\": [min_var_return, tangency_return],\n        \"label\": [\"Min Variance\", \"Max Sharpe\"],\n    }\n)\n\n# Capital Market Line\ncml_risks = np.array([0, tangency_risk * 1.8])\ncml_returns = risk_free_rate + (tangency_return - risk_free_rate) / tangency_risk * cml_risks\ndf_cml = pd.DataFrame({\"risk\": cml_risks, \"return\": cml_returns})\n\n# Custom theme\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG),\n    panel_grid_major_x=element_line(color=RULE, size=0.3),\n    panel_grid_major_y=element_line(color=RULE, size=0.3),\n    panel_grid_minor=element_blank(),\n    axis_title=element_text(size=20, color=INK),\n    axis_text=element_text(size=16, color=INK_SOFT),\n    axis_line=element_line(color=INK_SOFT, size=0.5),\n    plot_title=element_text(size=24, color=INK),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(size=16, color=INK_SOFT),\n    legend_title=element_text(size=18, color=INK),\n)\n\n# Plot\nplot = (\n    ggplot()\n    + geom_point(data=df_portfolios, mapping=aes(x=\"risk\", y=\"return\", color=\"sharpe\"), size=4, alpha=0.6)\n    + geom_line(data=df_frontier, mapping=aes(x=\"risk\", y=\"return\"), color=IMPRINT[2], size=3)\n    + geom_line(data=df_cml, mapping=aes(x=\"risk\", y=\"return\"), color=INK_SOFT, size=1.5, linetype=\"dashed\")\n    + geom_point(data=df_special, mapping=aes(x=\"risk\", y=\"return\"), color=IMPRINT[1], size=10, shape=18)\n    + labs(\n        x=\"Risk (Standard Deviation)\",\n        y=\"Expected Return\",\n        title=\"frontier-efficient · letsplot · anyplot.ai\",\n        color=\"Sharpe Ratio\",\n    )\n    + scale_color_viridis()\n    + ggsize(1600, 900)\n    + theme_minimal()\n    + anyplot_theme\n)\n\n# Save\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=3)\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}