100% FreeNo Signup Required

Max Sharpe Ratio Portfolio Calculator

The portfolio that maximises (wᵀμ − rf) ⁄ √(wᵀΣw) has a closed form — no optimiser required. Enter expected returns, volatilities and correlations for up to five assets to get the tangency weights and the Sharpe ratio they achieve.

The solution

w ∝ Σ−1(μ − rf·1)

Compute Σ−1(μ − rf·1), then divide by the sum of its elements so the weights add to 1. The proportionality is the point: any positive rescaling of the excess returns leaves the direction unchanged, and normalising removes the scale, so the tangency portfolio depends on the excess returns only through their direction under Σ−1.

Assumptions

AssetReturn %Volatility %
Asset 1
Asset 2
Asset 3

Correlation matrix

Asset 1
Asset 2
Asset 3

Symmetric — editing a cell updates its mirror. The diagonal is fixed at 1.

Tangency portfolio

Sharpe ratio
0.8094
(9.20%2.00%) ÷ 8.89%
AssetWeight
Asset 129.24%
Asset 215.35%
Asset 355.41%
Total100.00%
9.20%
Expected return
8.89%
Volatility

Where the formula comes from

The Sharpe ratio of a portfolio is unchanged if every weight is multiplied by the same positive number: both the excess return in the numerator and the volatility in the denominator scale linearly. That homogeneity is what makes a closed form possible. The budget constraint can be dropped while optimising, the unconstrained problem solved, and the constraint restored at the end by normalising.

Differentiating (wᵀμ − rf) ⁄ √(wᵀΣw) with respect to w and setting the result to zero gives, after cancelling the scalar factors that the homogeneity makes irrelevant, Σw ∝ (μ − rf·1). Multiplying both sides by Σ−1 gives the result above. The one requirement is that Σ be invertible.

Reading Σ−1 intuitively: it discounts each asset by how much of its risk is already carried by the others. An asset with a high expected return that is highly correlated with the rest of the portfolio adds little that is new, and the inverse covariance matrix reduces its weight accordingly — sometimes below zero.

Worked example

Three assets with expected returns of 10%, 12% and 8%; volatilities of 15%, 20% and 10%; correlations of 0.30 between assets 1 and 2, 0.10 between 1 and 3, and 0.20 between 2 and 3; a risk-free rate of 2%. These are the calculator's defaults, so the figures below are what it shows on load.

Asset 1 weight29.24%
Asset 2 weight15.35%
Asset 3 weight55.41%
Expected return9.20%
Volatility8.89%
Sharpe ratio0.8094

Note that the lowest-return asset takes the largest weight. That is Σ−1 at work: asset 3 has half the volatility of asset 1 and the weakest correlations to the others, so it contributes the most Sharpe ratio per unit of risk despite the lowest expected return. Ranking by expected return alone would get this backwards.

These figures were cross-checked two ways before publication: against an independent NumPy implementation, which reproduces the weights to six decimal places; and against a brute-force search over 200,000 random long-only portfolios drawn from the same inputs, whose best Sharpe ratio was 0.809371 — just under the 0.809373 the closed form returns, as it must be if the closed form is really the optimum.

The same thing in Python

import numpy as np

mu   = np.array([0.10, 0.12, 0.08])      # expected returns
vol  = np.array([0.15, 0.20, 0.10])      # volatilities
corr = np.array([[1.0, 0.3, 0.1],
                 [0.3, 1.0, 0.2],
                 [0.1, 0.2, 1.0]])
rf   = 0.02

sigma = np.outer(vol, vol) * corr        # covariance from vol + correlation
raw   = np.linalg.solve(sigma, mu - rf)  # solve, don't invert: faster and better conditioned
w     = raw / raw.sum()                  # normalise to sum to 1

ret    = w @ mu
sd     = np.sqrt(w @ sigma @ w)
sharpe = (ret - rf) / sd
# w -> [0.292376 0.153539 0.554085],  sharpe -> 0.809373

Use np.linalg.solve(sigma, mu - rf) rather than np.linalg.inv(sigma) @ (mu - rf). Both give the same answer here, but forming the explicit inverse is slower and numerically worse conditioned, which matters once the covariance matrix is large or near-singular — exactly the case where portfolio optimisation is already fragile.

What this does not do

It treats μ and Σ as given. In practice they are estimated, expected returns are estimated very badly, and Σ−1 magnifies estimation error — which is why a maximum-Sharpe portfolio built from historical estimates frequently underperforms equal weighting out of sample. The algebra on this page is exact; the inputs it operates on usually are not. Shrinkage estimators and weight constraints exist to address that, and neither is applied here.

Frequently asked questions

What are the maximum-Sharpe portfolio weights?+

They are w ∝ Σ⁻¹(μ − rf·1), normalised so the weights sum to 1 — where Σ is the covariance matrix, μ the vector of expected returns, and rf the risk-free rate. This portfolio is called the tangency portfolio because it is the point where a line drawn from the risk-free rate touches the efficient frontier. The proportionality is the whole result: scaling the excess-return vector by any positive constant scales w by the same constant, and normalising removes it, so only the direction of Σ⁻¹(μ − rf·1) matters.

Why does the solution involve the inverse covariance matrix?+

Maximising (wᵀμ − rf)/√(wᵀΣw) is scale-invariant in w, so the constraint can be dropped, the objective differentiated, and the first-order condition rearranged. Doing that gives Σw ∝ (μ − rf·1), and hence w ∝ Σ⁻¹(μ − rf·1). Intuitively Σ⁻¹ penalises assets that duplicate risk already held: two highly correlated assets split the allocation one of them would get alone.

Why are some weights negative?+

The closed form is unconstrained apart from the budget constraint that weights sum to 1, so short positions are allowed and frequently appear — typically in an asset whose expected return is low relative to what its correlations imply it should offer. Clipping negatives to zero and renormalising produces a valid long-only portfolio, but not the maximum-Sharpe one; there is no closed form under a no-shorting constraint, and it requires quadratic programming.

Why does the calculator sometimes refuse to return an answer?+

When the covariance matrix is singular, Σ⁻¹ does not exist. The common cause is two assets with a correlation of exactly 1 or −1, or a zero volatility, which makes one row of the matrix a combination of the others. In that case infinitely many weight vectors achieve the same Sharpe ratio, so there is no unique answer and none is shown. A pseudo-inverse would silently return one of the infinitely many.

Is the Sharpe ratio here annualised?+

It is in whatever units you enter. If the expected returns, volatilities and risk-free rate are annual figures, the resulting Sharpe ratio is annual. Mixing units — say monthly returns with annual volatilities — gives a meaningless number, and the calculator has no way to detect that.

Can I use historical estimates for the inputs?+

You can, but this is where portfolio optimisation is most often misused. The formula treats μ and Σ as known, while sample estimates of expected returns are extremely noisy, and Σ⁻¹ amplifies that noise — which is why the maximum-Sharpe portfolio computed from a sample often performs worse out of sample than equal weighting. That is a property of the estimates, not of the algebra, and no calculator can fix it. Shrinkage estimators (Ledoit–Wolf) and constraints exist to mitigate it.

Related tools

This calculator performs and displays arithmetic on the inputs you provide. It is not investment advice, does not recommend an allocation, and makes no claim that the expected returns or correlations you enter will be realised.