{"spec_id":"frontier-efficient","library":"makie","language":"julia","code":"# anyplot.ai\n# frontier-efficient: Efficient Frontier for Portfolio Optimization\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 91/100 | Created: 2026-09-02\n\nusing CairoMakie\nusing Colors\nusing Random\nusing LinearAlgebra\n\nRandom.seed!(42)\n\n# --- Theme tokens -----------------------------------------------------------\nconst THEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst INK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\nconst BRAND = IMPRINT_PALETTE[1]\nconst ANYPLOT_SEQ = cgrad([colorant\"#009E73\", colorant\"#4467A3\"])\n\n# --- Asset universe (6-asset allocation, annualized figures) ---------------\nassets = [\"US Equities\", \"Intl Equities\", \"Corp Bonds\", \"Real Estate\", \"Commodities\", \"Cash\"]\nn_assets = length(assets)\n\nexpected_return = [0.10, 0.085, 0.04, 0.075, 0.055, 0.02]\nvolatility       = [0.18, 0.20, 0.06, 0.16, 0.22, 0.01]\nrisk_free_rate   = 0.02\n\n# Single-factor correlation model: rho_ij = beta_i * beta_j (i != j), 1 on\n# the diagonal. Guarantees a valid positive-definite correlation matrix as\n# long as every |beta| < 1.\nmarket_beta = [0.75, 0.70, -0.10, 0.60, 0.35, 0.0]\ncorrelation = market_beta * market_beta' + Diagonal(1 .- market_beta .^ 2)\ncovariance = Diagonal(volatility) * correlation * Diagonal(volatility)\n\n# --- Random simulated portfolios (long-only, weights sum to 1) --------------\nn_portfolios = 400\nsim_risk = zeros(n_portfolios)\nsim_return = zeros(n_portfolios)\nsim_sharpe = zeros(n_portfolios)\n\nfor i in 1:n_portfolios\n    raw = -log.(rand(n_assets))          # exponential draws\n    w = raw ./ sum(raw)                  # uniform on the simplex\n    port_return = dot(w, expected_return)\n    port_var = w' * covariance * w\n    port_risk = sqrt(port_var)\n    sim_return[i] = port_return\n    sim_risk[i] = port_risk\n    sim_sharpe[i] = (port_return - risk_free_rate) / port_risk\nend\n\n# --- Analytic efficient frontier (unconstrained mean-variance, closed form) -\ncov_inv = inv(covariance)\nones_vec = ones(n_assets)\nA = ones_vec' * cov_inv * ones_vec\nB = ones_vec' * cov_inv * expected_return\nC = expected_return' * cov_inv * expected_return\nD = A * C - B^2\n\nmin_var_return = B / A\nmin_var_risk = sqrt(1 / A)\n\nfrontier_return = range(min_var_return, maximum(expected_return) * 1.08; length = 200)\nfrontier_variance = (A .* frontier_return .^ 2 .- 2 .* B .* frontier_return .+ C) ./ D\nfrontier_risk = sqrt.(frontier_variance)\n\n# Tangency (maximum Sharpe ratio) portfolio\ntangency_raw = cov_inv * (expected_return .- risk_free_rate)\ntangency_weights = tangency_raw ./ sum(tangency_raw)\ntangency_return = dot(tangency_weights, expected_return)\ntangency_risk = sqrt(tangency_weights' * covariance * tangency_weights)\n\n# Capital market line: from the risk-free rate through the tangency portfolio\nmax_risk_axis = max(maximum(sim_risk), maximum(frontier_risk)) * 1.05\ncml_risk = [0.0, max_risk_axis]\ncml_return = risk_free_rate .+ (tangency_return - risk_free_rate) / tangency_risk .* cml_risk\n\n# --- Plot --------------------------------------------------------------------\npct_format(values) = [string(round(Int, v * 100), \"%\") for v in values]\n\n# Explicit round-number tick steps (2 pp) so labels land on clean integers\n# instead of rounding arbitrary auto-ticks to the nearest percent.\nxtick_step = 0.02\nytick_step = 0.02\nxtick_vals = 0:xtick_step:(ceil(max_risk_axis / xtick_step) * xtick_step)\nytick_lo = floor(min_var_return / ytick_step) * ytick_step\nytick_hi = ceil(maximum(frontier_return) / ytick_step) * ytick_step\nytick_vals = ytick_lo:ytick_step:ytick_hi\n\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"frontier-efficient · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Risk (Annualized Std. Dev.)\",\n    ylabel             = \"Expected Return (Annualized)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    xticks             = xtick_vals,\n    yticks             = ytick_vals,\n    xtickformat        = pct_format,\n    ytickformat        = pct_format,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    xminorgridvisible  = false,\n    yminorgridvisible  = false,\n)\nxlims!(ax, 0, max_risk_axis)\n\nscatter!(\n    ax, sim_risk, sim_return;\n    color = sim_sharpe, colormap = ANYPLOT_SEQ,\n    colorrange = (minimum(sim_sharpe), maximum(sim_sharpe)),\n    markersize = 11, alpha = 0.6, strokewidth = 0,\n)\n\nlines!(ax, cml_risk, cml_return; color = INK_SOFT, linewidth = 2, linestyle = :dash, label = \"Capital market line\")\nlines!(ax, frontier_risk, collect(frontier_return); color = BRAND, linewidth = 4.5, label = \"Efficient frontier\")\n\nscatter!(\n    ax, [min_var_risk], [min_var_return];\n    color = IMPRINT_PALETTE[2], marker = :diamond, markersize = 24,\n    strokewidth = 1.5, strokecolor = PAGE_BG, label = \"Minimum-variance portfolio\",\n)\nscatter!(\n    ax, [tangency_risk], [tangency_return];\n    color = IMPRINT_PALETTE[3], marker = :star5, markersize = 26,\n    strokewidth = 1.5, strokecolor = PAGE_BG, label = \"Max Sharpe (tangency) portfolio\",\n)\n\n# Small callouts so the two key portfolios' return/risk are legible at a glance\ncallout(v) = string(round(v * 100, digits = 1), \"%\")\ntext!(\n    ax, min_var_risk, min_var_return;\n    text = \"Min variance\\n$(callout(min_var_return)) / $(callout(min_var_risk))\",\n    color = INK_SOFT, fontsize = 11, align = (:left, :top), offset = (10, -10),\n)\ntext!(\n    ax, tangency_risk, tangency_return;\n    text = \"Tangency\\n$(callout(tangency_return)) / $(callout(tangency_risk))\",\n    color = INK_SOFT, fontsize = 11, align = (:left, :bottom), offset = (10, 10),\n)\n\nColorbar(\n    fig[1, 2];\n    limits = (minimum(sim_sharpe), maximum(sim_sharpe)),\n    colormap = ANYPLOT_SEQ,\n    label = \"Sharpe ratio\",\n    labelcolor = INK,\n    ticklabelcolor = INK_SOFT,\n    tickcolor = INK_SOFT,\n    width = 22,\n)\n\naxislegend(\n    ax; position = :rb, framevisible = true,\n    backgroundcolor = ELEVATED_BG, framecolor = INK_SOFT,\n    labelcolor = INK, labelsize = 12, patchsize = (24, 12),\n)\n\ncolsize!(fig.layout, 1, Relative(0.92))\n\n# --- Save ---------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}