Matlab Optimize Portfolio
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Business and productivity
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured approach to portfolio optimization using the MATLAB Financial Toolbox. It guides users to leverage the Portfolio object for tasks such as mean-variance analysis, efficient frontier computation, and maximizing the Sharpe ratio. By using built-in methods, users avoid the pitfalls of manual solver configuration and ensure robust, mathematically sound results for asset allocation problems.
What it does
- Formulates mean-variance portfolio optimization problems.
- Computes efficient frontiers and target-return portfolios.
- Calculates the maximum Sharpe ratio (tangency) portfolio.
- Manages complex constraints like cardinality and semicontinuous bounds.
- Provides built-in visualization for efficient frontiers and optimal portfolios.
- Calculates portfolio risk and return metrics automatically.
When to use it
- When you need to perform mean-variance or Markowitz portfolio optimization.
- When you want to find the tangency portfolio or maximize the Sharpe ratio.
- When you need to trace an efficient frontier for a set of assets.
- When you are struggling with manual solver implementations like fmincon or quadprog for asset allocation.
- When you need to apply specific constraints such as turnover, groups, or cardinality to a portfolio.
Advantages
- Reduces code complexity by using high-level object methods.
- Ensures global optima by using specialized internal solver configurations.
- Simplifies constraint management through dedicated API methods.
- Provides reliable, built-in functions for risk and return analysis.
- Prevents common errors associated with manual nonlinear objective function definitions.
Usage examples
- “How do I find the minimum variance portfolio in MATLAB?”
- The agent will show how to create a Portfolio object, set default constraints, and use estimateFrontierLimits(p, 'Min') to compute the minimum variance weights.
- “I want to maximize my Sharpe ratio, but my manual fmincon code is failing.”
- The agent will explain why the Portfolio object is preferred, show how to set the RiskFreeRate, and demonstrate the use of estimateMaxSharpeRatio(p).
- “How can I plot the efficient frontier for my asset returns?”
- The agent will provide a workflow to set asset moments, define constraints, compute the frontier using estimateFrontier(p, 20), and visualize it with plotFrontier(p, w).
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/matlab/matlab-optimize-portfolio/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-optimize-portfolio.zip -d .agents/skills
Documentation by MathWorks
Portfolio Optimization with Financial Toolbox
You are helping a user formulate and solve a portfolio optimization problem using MATLAB's Financial Toolbox Portfolio object.
When to Use
User wants to optimize a portfolio (minimize variance, maximize Sharpe ratio, trace efficient frontier)
User asks about Markowitz, mean-variance, minimum-variance, or tangency portfolios
User asks about the efficient frontier or target-return portfolios
User is trying to use fmincon, quadprog, ga, or problem-based optimize for portfolio optimization (redirect to Portfolio object)
User asks how to set up constraints for portfolio optimization (bounds, groups, turnover, one-way turnover, cardinality, semicontinuous)
User asks about mean-variance with cardinality or semi-continuous constraints
User gets errors from Portfolio, estimateMaxSharpeRatio, estimateFrontier, or related methods
When NOT to Use
User has a general optimization problem (QP, NLP, MILP) that is NOT financial asset allocation (e.g., filter design, resource allocation, mixture proportions) — use
matlab-solve-optimizationUser needs to retrieve market data from Bloomberg, FRED, or Haver Analytics — use
matlab-access-datafeedUser wants to predict returns or portfolio weights using neural networks or ML — use
matlab-train-networkUser only wants to clean, explore, or summarize a returns table without optimization — use
matlab-analyze-dataUser wants Experiment Manager parameter sweeps (not portfolio frontier) — use
matlab-use-experiment-managerUser wants CVaR, MAD, or other non-mean-variance risk measures — use
PortfolioCVaRorPortfolioMADclasses (not covered by this skill)
Key Principle
Always use the Portfolio class — never let users manually code the optimization with fmincon or quadprog. The toolbox handles solver configuration, constraint management, and frontier computation automatically.
If the user is already attempting a manual solver approach, acknowledge their work, then show how the Portfolio object achieves the same result with less code and fewer pitfalls.
Step 1: Identify the Formulation
Determine which problem the user is trying to solve:
| User wants to... | Formulation | Reference |
|---|---|---|
| Minimize portfolio risk (no return target) | Mean-variance (min-variance) | formulation-mean-variance.md |
| Minimize risk for a given target return | Mean-variance (target-return) | formulation-mean-variance.md |
| Trace the efficient frontier | Mean-variance (frontier) | formulation-mean-variance.md |
| Maximize risk-adjusted return (Sharpe ratio) | Max Sharpe / tangency | formulation-max-sharpe.md |
Consult the relevant formulation file for problem-specific guidance and methods.
Step 2: Determine What Data the User Has
Ask (if not clear) whether they have:
A matrix of historical asset returns (or prices that need converting)
Pre-computed mean returns (mu) and covariance matrix (Sigma)
A risk-free rate (relevant for Sharpe ratio; defaults to 0 if unspecified)
Step 3: Create the Portfolio Object
See reference-core.md for all creation patterns. The most common:
From return statistics:
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);From historical returns:
p = Portfolio;
p = setAssetMoments(p, mean(returns)', cov(returns));Step 4: Set Constraints
Always set constraints. At minimum, use default constraints (fully invested, long-only):
p = setDefaultConstraints(p);For other constraint types (bounds, groups, turnover, one-way turnover, cardinality), see reference-core.md.
Step 5: Solve
Use the method appropriate to the formulation (see the formulation file). Common patterns:
wMinVar = estimateFrontierLimits(p, 'Min'); % minimum-variance
wTarget = estimateFrontierByReturn(p, targetRet); % target-return
wSharpe = estimateMaxSharpeRatio(p); % max Sharpe ratio
wFrontier = estimateFrontier(p, 20); % efficient frontierStep 6: Analyze and Visualize
Use built-in methods for portfolio statistics — never compute them manually:
portRisk = estimatePortRisk(p, w);
portRet = estimatePortReturn(p, w);
[risk, ret] = estimatePortMoments(p, w);Always use plotFrontier as the primary frontier visualization — add custom annotations (special portfolios, CAL line) with hold on/hold off afterward:
wFrontier = estimateFrontier(p, 20);
plotFrontier(p, wFrontier);
hold on
[risk, ret] = estimatePortMoments(p, wSpecial);
plot(risk, ret, 'r*', 'MarkerSize', 12);
hold offCommon Pitfalls
Manual solver usage — quadprog/fmincon for portfolio problems is error-prone; Portfolio handles it.
Missing constraints — A Portfolio without constraints is underdetermined.
Redundant solves — Pass weights to
plotFrontier, not a number of portfolios, if you already solved.Manual risk/return formulas — Use
estimatePortRisk,estimatePortReturn,estimatePortMoments.Cardinality/semicontinuous constraints — When calling
estimateMaxSharpeRatio, specify'Method','iterative'(MATLAB auto-selects with a warning if omitted, but explicit is cleaner). Frontier methods (estimateFrontier,estimateFrontierLimits,estimateFrontierByReturn) auto-detect these constraints and select the mixed-integer solver internally — do NOT pass'Method','iterative'to them.
Tone
Be direct and practical. Show working MATLAB code. If the user provides data, use their actual data. If not, use a small illustrative example so they can see the pattern and adapt.
Reference Materials
reference-core.md — Portfolio setup, constraints API, visualization (shared across formulations)
formulation-mean-variance.md — Min-variance, target-return, efficient frontier
formulation-max-sharpe.md — Max Sharpe ratio / tangency portfolio
examples.md — Complete runnable examples for all formulations
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.0 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md6.9 KiB
- manifest.yaml483 B
- references/examples.md8.7 KiB
- references/formulation-max-sharpe.md3.6 KiB
- references/formulation-mean-variance.md3.5 KiB
- references/reference-core.md6.8 KiB
references/examples.md
Portfolio Optimization — Complete Examples
Mean-Variance Examples
Example MV1: Minimum-Variance Portfolio (basic)
% Asset statistics (5 assets)
mu = [0.08; 0.06; 0.12; 0.05; 0.10];
Sigma = [0.040 0.010 0.015 0.005 0.008;
0.010 0.025 0.008 0.003 0.006;
0.015 0.008 0.070 0.010 0.020;
0.005 0.003 0.010 0.020 0.004;
0.008 0.006 0.020 0.004 0.035];
% Create portfolio, set default constraints
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);
p = setDefaultConstraints(p);
% Minimum-variance portfolio
wMinVar = estimateFrontierLimits(p, 'Min');
% Analyze using built-in methods
portRisk = estimatePortRisk(p, wMinVar);
portRet = estimatePortReturn(p, wMinVar);
fprintf('Min-Variance Portfolio:\n');
fprintf(' Risk (Std Dev): %.4f\n', portRisk);
fprintf(' Return: %.4f\n', portRet);
fprintf(' Weights: %s\n', mat2str(wMinVar', 4));Example MV2: Minimum-Variance with Upper Bounds
mu = [0.08; 0.06; 0.12; 0.05; 0.10; 0.07; 0.09; 0.11; 0.06; 0.08];
Sigma = 0.01*eye(10) + 0.005*ones(10);
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);
p = setDefaultConstraints(p);
p = setBounds(p, 0, 0.15); % max 15% per asset
wMinVar = estimateFrontierLimits(p, 'Min');
fprintf('Min-Variance Std Dev: %.4f\n', estimatePortRisk(p, wMinVar));Example MV3: Target-Return Portfolio
mu = [0.08; 0.06; 0.12; 0.05; 0.10];
Sigma = [0.040 0.010 0.015 0.005 0.008;
0.010 0.025 0.008 0.003 0.006;
0.015 0.008 0.070 0.010 0.020;
0.005 0.003 0.010 0.020 0.004;
0.008 0.006 0.020 0.004 0.035];
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);
p = setDefaultConstraints(p);
% Check feasible return range
wLimits = estimateFrontierLimits(p);
muRange = estimatePortReturn(p, wLimits);
fprintf('Feasible return range: [%.4f, %.4f]\n', muRange(1), muRange(2));
% Solve for a target return within the feasible range
targetRet = 0.09;
wTarget = estimateFrontierByReturn(p, targetRet);
fprintf('Target-Return Portfolio (target=%.2f%%):\n', targetRet*100);
fprintf(' Achieved Return: %.4f\n', estimatePortReturn(p, wTarget));
fprintf(' Risk: %.4f\n', estimatePortRisk(p, wTarget));Example MV4: Efficient Frontier with Visualization
mu = [0.08; 0.06; 0.12; 0.05; 0.10];
Sigma = [0.040 0.010 0.015 0.005 0.008;
0.010 0.025 0.008 0.003 0.006;
0.015 0.008 0.070 0.010 0.020;
0.005 0.003 0.010 0.020 0.004;
0.008 0.006 0.020 0.004 0.035];
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma, ...
'AssetList', ["Equities","Bonds","Growth","Defensive","Balanced"]);
p = setDefaultConstraints(p);
% Compute frontier and plot (pass weights to avoid redundant solves)
wFrontier = estimateFrontier(p, 20);
figure;
plotFrontier(p, wFrontier);
title('Mean-Variance Efficient Frontier');
% Annotate min-variance and max-return endpoints
wMinVar = estimateFrontierLimits(p, 'Min');
wMaxRet = estimateFrontierLimits(p, 'Max');
hold on
[rMin, retMin] = estimatePortMoments(p, wMinVar);
[rMax, retMax] = estimatePortMoments(p, wMaxRet);
plot(rMin, retMin, 'gs', 'MarkerSize', 12, 'MarkerFaceColor', 'g');
plot(rMax, retMax, 'r^', 'MarkerSize', 12, 'MarkerFaceColor', 'r');
legend('Efficient Frontier', 'Min-Variance', 'Max-Return');
hold offExample MV5: From Historical Returns
rng(42);
nAssets = 10;
nObs = 252;
assetReturns = 0.0004 + 0.02 * randn(nObs, nAssets);
p = Portfolio('AssetList', compose("Asset%d", 1:nAssets));
p = setAssetMoments(p, mean(assetReturns)', cov(assetReturns));
p = setDefaultConstraints(p);
p = setBounds(p, 0, 0.30);
% Minimum-variance
wMinVar = estimateFrontierLimits(p, 'Min');
fprintf('Min-Variance Std Dev: %.4f%%\n', 100*estimatePortRisk(p, wMinVar));
% Target-return at midpoint
wLimits = estimateFrontierLimits(p);
muRange = estimatePortReturn(p, wLimits);
targetRet = mean(muRange);
wTarget = estimateFrontierByReturn(p, targetRet);
fprintf('Target Return: %.4f%%, Std Dev: %.4f%%\n', ...
100*targetRet, 100*estimatePortRisk(p, wTarget));
% Frontier
wFrontier = estimateFrontier(p, 20);
figure;
plotFrontier(p, wFrontier);
title('Mean-Variance Efficient Frontier');Max Sharpe Ratio Examples
Example SR1: Basic — From Known Mean and Covariance
mu = [0.3; 0.1; 0.5];
Sigma = [0.01 -0.010 0.004;
-0.010 0.040 -0.002;
0.004 -0.002 0.023];
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);
p = setDefaultConstraints(p);
weights = estimateMaxSharpeRatio(p);
% Display
fprintf('Max Sharpe Weights: %s\n', mat2str(weights', 4));
sharpe = estimatePortSharpeRatio(p, weights);
fprintf('Sharpe Ratio: %.4f\n', sharpe);
% Visualize
wFrontier = estimateFrontier(p, 20);
figure;
plotFrontier(p, wFrontier);
[risk, ret] = estimatePortMoments(p, weights);
hold on
plot(risk, ret, 'r*', 'MarkerSize', 12);
legend('Efficient Frontier', 'Max Sharpe Portfolio', 'Location', 'southeast');
hold offExample SR2: From Historical Returns with Risk-Free Rate
rng(42);
T = 252; N = 5;
returns = mvnrnd([0.0004 0.0003 0.0006 0.0002 0.0005], ...
gallery('randcorr',5)*0.0004, T);
p = Portfolio;
p = estimateAssetMoments(p, returns);
p = setDefaultConstraints(p);
p.RiskFreeRate = 0.02/252; % annualized 2%, converted to daily
weights = estimateMaxSharpeRatio(p);
[risk, ret] = estimatePortMoments(p, weights);
annualizedReturn = ret * 252;
annualizedRisk = risk * sqrt(252);
annualizedSharpe = (annualizedReturn - 0.02) / annualizedRisk;
fprintf('Annualized Return: %.2f%%\n', annualizedReturn*100);
fprintf('Annualized Risk: %.2f%%\n', annualizedRisk*100);
fprintf('Sharpe Ratio: %.4f\n', annualizedSharpe);Example SR3: With Sector Constraints
mu = [0.10; 0.08; 0.14; 0.07; 0.12; 0.09];
Sigma = 0.01 * eye(6) + 0.005 * ones(6);
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma, 'RiskFreeRate', 0.02);
p = setDefaultConstraints(p);
% Tech (assets 1-3): 20%-60%, Finance (assets 4-6): 30%-70%
GroupMatrix = [1 1 1 0 0 0;
0 0 0 1 1 1];
p = setGroups(p, GroupMatrix, [0.20; 0.30], [0.60; 0.70]);
weights = estimateMaxSharpeRatio(p);
fprintf('Tech allocation: %.1f%%\n', sum(weights(1:3))*100);
fprintf('Finance allocation: %.1f%%\n', sum(weights(4:6))*100);
fprintf('Sharpe Ratio: %.4f\n', estimatePortSharpeRatio(p, weights));Example SR4: Cardinality Constraints (hold exactly K assets)
mu = [0.0101; 0.0044; 0.0137; 0.0089; 0.0062];
Sigma = [0.0032 0.0002 0.0042 0.0010 0.0005;
0.0002 0.0005 0.0002 0.0001 0.0001;
0.0042 0.0002 0.0076 0.0015 0.0008;
0.0010 0.0001 0.0015 0.0030 0.0003;
0.0005 0.0001 0.0008 0.0003 0.0020];
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma);
p = setDefaultConstraints(p);
p = setMinMaxNumAssets(p, 3, 3); % exactly 3 assets
p = setBounds(p, 0.05, 1, 'BoundType', 'Conditional'); % min 5% if held (prevents near-zero allocations)
% Must use iterative method for cardinality constraints
weights = estimateMaxSharpeRatio(p, 'Method', 'iterative');
fprintf('Assets held: %d\n', sum(weights > 1e-6));
fprintf('Weights: %s\n', mat2str(weights', 4));Example SR5: Full Workflow with CML Visualization
mu = [0.12; 0.10; 0.18; 0.08; 0.14];
Sigma = [0.040 0.010 0.015 0.005 0.008;
0.010 0.025 0.008 0.003 0.006;
0.015 0.008 0.070 0.010 0.020;
0.005 0.003 0.010 0.020 0.004;
0.008 0.006 0.020 0.004 0.035];
rf = 0.03;
assetNames = {'Equities','Bonds','Growth','Defensive','Balanced'};
p = Portfolio('AssetMean', mu, 'AssetCovar', Sigma, ...
'RiskFreeRate', rf, 'AssetList', assetNames);
p = setDefaultConstraints(p);
% Solve
weights = estimateMaxSharpeRatio(p);
[optRisk, optRet] = estimatePortMoments(p, weights);
optSharpe = estimatePortSharpeRatio(p, weights);
% Frontier
wFrontier = estimateFrontier(p, 50);
% Visualization
figure('Position', [100 100 1000 400])
tiledlayout(1, 2)
nexttile
plotFrontier(p, wFrontier); hold on
plot(optRisk, optRet, 'r*', 'MarkerSize', 12, 'LineWidth', 2);
% Capital Market Line
[maxRisk, ~] = estimatePortMoments(p, wFrontier(:,end));
cmlX = linspace(0, maxRisk*1.1, 100);
cmlY = rf + optSharpe * cmlX;
plot(cmlX, cmlY, 'r--', 'LineWidth', 1);
plot(0, rf, 'ko', 'MarkerSize', 8, 'MarkerFaceColor', 'k');
title('Efficient Frontier & Capital Market Line');
legend('Efficient Frontier', 'Max Sharpe Portfolio', 'CML', 'Risk-Free Rate', ...
'Location', 'southeast');
hold off
nexttile
bar(weights);
set(gca, 'XTickLabel', assetNames, 'XTickLabelRotation', 45);
ylabel('Weight'); title(sprintf('Max Sharpe Portfolio (SR = %.3f)', optSharpe));
ylim([0 max(weights)*1.2]); grid on
fprintf('\nSharpe Ratio: %.4f\n', optSharpe);
fprintf('Expected Return: %.2f%%\n', optRet*100);
fprintf('Risk (Std Dev): %.2f%%\n', optRisk*100);Copyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/computational-finance/matlab-optimize-portfolio · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-optimize-portfolio.zip