← Research

Research Note

From Sharpe Ratios to Portfolio Weights: A Quantitative Guide in R

Open in an AI assistant with a suggested prompt
Preview prompt
Summarize the Ionitsa research note titled "From Sharpe Ratios to Portfolio Weights: A Quantitative Guide in R" for a technical reader.
Cover the problem or research question, implementation or method, evidence or results, and limitations.
Separate facts stated on the page from your own assessment, note anything unclear or unverified, and avoid promotional language.

Primary source: https://ionitsa.com/research/portfolio-sharpe-quantitative-guide.md
Canonical page: https://ionitsa.com/research/portfolio-sharpe-quantitative-guide/

A practical explanation of how an equity portfolio moves from adjusted prices and risk-adjusted stock selection to covariance-aware allocation, rebalancing and transaction-cost control.

Markets · Published 3 August 2026 · Updated 3 August 2026 · 13 min read

Portfolio OptimisationSharpe RatioModern Portfolio TheoryBacktestingRRisk Management

How does a quantitative investor move from a table of share prices to an actual portfolio?

The difficult part is not finding stocks that went up. It is deciding whether their returns were attractive relative to risk, understanding how their risks interact, converting noisy estimates into portfolio weights, and testing the result without allowing future information into the decision.

This article uses my PortfolioSharpe implementation as a worked example. It is one of my oldest surviving code projects and one of my first projects in financial markets, but the purpose here is not to revisit its age. It is to explain the quantitative ideas inside it and show how the same research problem should be approached with institutional discipline.

The implementation was written in R Markdown, combining explanatory text with executable R. It uses quantmod for market prices and periodic returns, tidyquant for the equity universe, timeSeries for return data structures and fPortfolio for the efficient frontier.

The central lesson: stock selection and portfolio construction are different problems. A ranking asks which securities look attractive on their own. A portfolio model asks which combination of those securities produces the most useful total risk.

The portfolio engine in one pass

The original program implements a recognisable systematic-investment process:

  1. obtain a universe of large US equities;
  2. download adjusted daily closing prices;
  3. convert prices into daily returns;
  4. estimate an annualised Sharpe ratio for every stock;
  5. retain the ten highest-ranked stocks;
  6. estimate their expected returns, volatilities and covariances;
  7. construct a long-only mean-variance efficient frontier;
  8. choose the frontier portfolio with the highest estimated Sharpe ratio;
  9. hold it for the next month or quarter;
  10. rebalance and charge transaction costs only on the capital that changes.

That sequence contains four distinct models:

LayerQuestion
SignalWhich stocks appear attractive?
RiskHow do those stocks behave together?
PortfolioWhat weights convert the signal into a controlled position?
ExecutionHow much of the theoretical return survives trading?

Many weak backtests collapse these layers into one number. Keeping them separate makes the assumptions visible and lets each part be tested.

From prices to returns

The notebooks download the adjusted-close column returned by Yahoo Finance. If Pi,tP_{i,t} is the adjusted price of stock ii on day tt, its arithmetic return is

ri,t=Pi,tPi,t11.r_{i,t}=\frac{P_{i,t}}{P_{i,t-1}}-1.

Adjusted prices are important because a stock split should not appear as a large economic loss. Distributions and other corporate actions also need to be represented consistently if the return series is meant to approximate investor wealth.

An institutional data pipeline would not trust the word “adjusted” without checking it. It would document the vendor methodology, test split and dividend dates, preserve the original observations and record every later revision. In portfolio research, a clean total-return series is an input control, not a minor data-cleaning detail.

The code aligns prices into a matrix: dates down the rows and securities across the columns. From that matrix it estimates each stock’s daily mean return and standard deviation.

This is where the first quiet modelling choice appears. Prices may be observed, but expected returns are not. A historical mean is only an estimate of what may happen next.

Sharpe ratio as a selection signal

The Sharpe ratio measures expected excess return per unit of total volatility. For stock ii,

SRi=E[rirf]σi.SR_i=\frac{\mathbb{E}[r_i-r_f]}{\sigma_i}.

The implementation assumes a zero risk-free rate and annualises daily sample statistics using 252 trading days:

SR^i=252rˉi252si=252rˉisi.\widehat{SR}_i =\frac{252\,\bar r_i}{\sqrt{252}\,s_i} =\sqrt{252}\frac{\bar r_i}{s_i}.

The stocks are sorted by this estimate and the highest ten are passed to the portfolio optimiser.

This is more informative than ranking by return alone. A stock that gained 8% through small, consistent moves is different from one that gained 8% through a single jump surrounded by large reversals. The Sharpe ratio gives the second path a larger risk denominator.

But a sample Sharpe ratio is not a permanent property of a company. It is a noisy statistic calculated over a chosen window. A high estimate can mean:

This creates the winner’s curse of ranking. If 100 equally unskilled stocks are ranked on a short history, some will show excellent Sharpe ratios by chance. Selecting the maximum selects both possible skill and maximum estimation noise.

For that reason, a professional implementation would treat the ranking as a signal rather than a fact. It might use a longer window, shrink extreme values, combine multiple horizons, require liquidity, control sector exposures and test whether the ranking has historically predicted future returns.

Annualisation also carries assumptions. Multiplying the mean by 252 and the standard deviation by 252\sqrt{252} is most defensible when daily returns are reasonably stationary and serial dependence is limited. Strong autocorrelation, volatility clustering or stale prices can make the annualised ratio look more precise than it is.

Why ten attractive stocks do not make a portfolio

Suppose two stocks each have 20% annual volatility. A 50/50 combination does not necessarily have 20% volatility. Its risk depends on how the two stocks move together.

For weights w\boldsymbol{w} and covariance matrix Σ\boldsymbol{\Sigma}, portfolio variance is

σp2=wTΣw.\sigma_p^2 =\boldsymbol{w}^{\mathsf T}\boldsymbol{\Sigma}\boldsymbol{w}.

For two stocks this expands to

σp2=w12σ12+w22σ22+2w1w2ρ12σ1σ2.\sigma_p^2 =w_1^2\sigma_1^2+w_2^2\sigma_2^2 +2w_1w_2\rho_{12}\sigma_1\sigma_2.

The correlation ρ12\rho_{12} determines the diversification benefit. Two low- volatility banks can still create a concentrated portfolio if they respond to the same rates, credit and funding shocks. A bank and a defensive healthcare company may diversify each other even if each is individually more volatile.

This leads to a useful quantitative definition:

Diversification is not the number of ticker symbols. It is the number and balance of genuinely different risk exposures.

The original code captures this idea by estimating the full covariance matrix of the selected stocks rather than allocating solely from their individual Sharpe ratios.

The mean-variance optimiser

Let μ^\boldsymbol{\hat\mu} be the vector of estimated expected returns. The portfolio’s expected return is

μ^p=wTμ^.\widehat{\mu}_p =\boldsymbol{w}^{\mathsf T}\boldsymbol{\hat\mu}.

For a chosen target return μ\mu^*, a long-only minimum-variance portfolio solves

minwwTΣ^wsubject towTμ^=μ,1Tw=1,wi0.\begin{aligned} \min_{\boldsymbol{w}}\quad &\boldsymbol{w}^{\mathsf T}\boldsymbol{\hat\Sigma}\boldsymbol{w}\\ \text{subject to}\quad &\boldsymbol{w}^{\mathsf T}\boldsymbol{\hat\mu}=\mu^*,\\ &\mathbf{1}^{\mathsf T}\boldsymbol{w}=1,\\ &w_i\geq 0. \end{aligned}

Repeating that optimisation across a range of target returns produces the efficient frontier: portfolios offering the lowest estimated volatility for each level of estimated return.

The R code calls portfolioFrontier(returns), extracts the frontier’s risk and return points, annualises them and calculates

SR^p=μ^prfσ^p.\widehat{SR}_p =\frac{\widehat{\mu}_p-r_f}{\widehat{\sigma}_p}.

It then chooses the frontier point with the largest ratio. Geometrically, this is the portfolio where a line beginning at the risk-free rate is tangent to the efficient frontier. It is commonly called the tangency portfolio or maximum- Sharpe portfolio.

Why optimisers produce surprising weights

An optimiser does not know that its inputs are estimates. If two stocks have almost identical histories but one has a slightly higher estimated return, the model may allocate heavily to that tiny difference. Small input changes can therefore create large weight changes.

This is why mean-variance optimisation is sometimes described as an “error maximiser”: it searches most aggressively in the direction where the estimated opportunity looks best, which may also be where estimation error is largest.

The practical response is not to abandon optimisation. It is to constrain it:

If an elaborate optimiser cannot beat a simple allocation after costs, the complexity is not earning its place.

Rebalancing turns a model into a strategy

A portfolio weight is only valid for a point in time. Prices move, volatility changes, correlations change and the selected stocks change. The notebooks therefore explore monthly and quarterly rebalancing.

The trade-off is fundamental:

Monthly rebalancingQuarterly rebalancing
reacts faster to new informationignores more short-term noise
keeps the portfolio closer to targetpermits larger weight drift
captures shorter-lived signalsmay miss fast signal decay
usually creates more turnoverusually costs less to trade

There is no universally correct frequency. It should follow from signal decay, liquidity, transaction costs and risk tolerance. A signal whose predictive power disappears within ten days cannot sensibly be traded quarterly. A slow quality signal may be damaged by monthly trading.

The information boundary

At a rebalance date tt, the strategy may use only information available by tt. If weights are calculated after the closing price is known, the earliest honest execution is normally the next tradable observation, subject to the chosen execution convention.

A clean walk-forward sequence is:

lookback datasignal cutofftarget weightsexecutionfuture holding-period return.\text{lookback data} \longrightarrow \text{signal cutoff} \longrightarrow \text{target weights} \longrightarrow \text{execution} \longrightarrow \text{future holding-period return}.

This separation prevents look-ahead bias. The implementation should use actual exchange dates rather than assuming every month contains 21 sessions. A window defined by row numbers can cross month boundaries, mishandle holidays and silently associate a return with the wrong portfolio.

That is not clerical housekeeping. In systematic research, time alignment is part of the economic model.

Measuring turnover and transaction costs

The project includes a useful piece of portfolio accounting. Let wi,t1w_{i,t-1} be the old target weight and wi,tw_{i,t} the new weight. For long-only, fully invested portfolios, the capital retained without trading is

Kt=imin(wi,t1,wi,t).K_t=\sum_i\min(w_{i,t-1},w_{i,t}).

The one-way turnover is therefore

Tt=1Kt=12iwi,twi,t1.T_t=1-K_t =\frac{1}{2}\sum_i|w_{i,t}-w_{i,t-1}|.

If a stock remains at a 6% weight, that 6% is retained. If its weight falls from 6% to 2%, 2% is retained and 4% must be sold. A new name begins with zero old weight, so its entire allocation must be purchased.

The notebooks charge a fixed 0.89% rate to the portion being reallocated. In compact form, the wealth deduction is

Wtafter cost=Wtbefore cost(1cTt),W_t^{after\ cost}=W_t^{before\ cost}(1-cT_t),

where c=0.0089c=0.0089 in the original assumption.

The structure is more important than the particular number. A real trading-cost model would separate commissions, bid/ask spread, market impact and taxes. Cost would depend on liquidity, order size and volatility; it would not be identical for every stock.

Turnover is also not merely a cost statistic. Large month-to-month changes can reveal that the signal or optimiser is unstable. A portfolio that constantly replaces its holdings may be trading estimation noise rather than economic information.

How a quant should backtest the idea

The correct test is a sequence of simulated historical decisions, not one optimisation performed with the whole dataset.

For each rebalance date:

  1. load the point-in-time investable universe;
  2. use only prices observable before the signal cutoff;
  3. enforce a minimum history and liquidity rule;
  4. estimate each stock’s selection signal;
  5. select the candidates;
  6. estimate or shrink their covariance matrix;
  7. calculate constrained target weights;
  8. compare targets with current holdings and generate trades;
  9. apply realistic costs at the next executable price;
  10. record the subsequent portfolio and benchmark returns.

The output should be a rebalance ledger, not just a final wealth number:

FieldWhat it proves
signal_cutoffno future market data entered the decision
universe_snapshotconstituent selection was point in time
selected_symbolsthe ranking can be audited
target_weightsconstraints and concentration can be inspected
pre_trade_weightsturnover can be reconstructed
execution_pricethe return does not begin before the trade
transaction_costgross and net performance remain separate
holding_returnthe measured result is genuinely out of sample

Point-in-time membership matters because today’s S&P 500 constituents are not the historical S&P 500. Using the current list in an old backtest systematically favours companies that survived and remained important enough to be included. Delistings, acquisitions and ticker changes are not data nuisances; they are part of the return distribution.

How an institutional portfolio would strengthen the model

The educational implementation selects recent high-Sharpe stocks and combines them through a long-only efficient frontier. A hedge-fund or asset-management research process would ask several additional questions.

Is the signal distinct from common factors?

A high recent Sharpe ratio may simply identify momentum, low volatility, sector leadership or market beta. Factor attribution can show whether the portfolio is earning a stock-selection return or repackaging a known exposure.

Where is the concentration?

Ten ticker symbols can hide one macro trade. Sector caps, beta limits and factor exposure constraints prevent an optimiser from placing the entire risk budget behind one economic scenario.

Is the covariance estimate robust?

Short samples produce unstable correlations. Covariance shrinkage, factor risk models and stress matrices can produce weights that respond less violently to small changes in the data.

Can the portfolio actually be traded?

Average daily volume, bid/ask spreads, borrow availability, corporate actions and capacity should be known before a signal enters the optimiser. A theoretical allocation is not an investable portfolio if its expected edge disappears in the spread.

Is performance genuinely active?

The strategy should be compared with an investable total-return benchmark over identical dates. Useful diagnostics include CAGR, volatility, Sharpe ratio, maximum drawdown, beta, tracking error, information ratio, turnover and factor attribution. “Final wealth was higher” does not explain where the return came from or whether it compensated the investor for risk.

Does the result survive alternative choices?

A credible effect should not depend on one exact lookback or rebalance date. Researchers should vary the estimation window, portfolio size, cost assumption, weight caps and rebalance frequency. This is not an invitation to search until something works. It is a stability test: nearby reasonable specifications should tell a coherent economic story.

What this implementation teaches

The project is a compact introduction to the architecture of systematic equity investing. It demonstrates that a quantitative portfolio is not produced by one formula. It emerges from a chain:

datareturnssignalrisk modelweightstradesnet performance.\text{data} \rightarrow \text{returns} \rightarrow \text{signal} \rightarrow \text{risk model} \rightarrow \text{weights} \rightarrow \text{trades} \rightarrow \text{net performance}.

Every arrow is capable of changing the result. Poor constituent history can invalidate the universe. A noisy lookback can destabilise the signal. A weak covariance estimate can create concentrated weights. Incorrect calendar logic can move future returns into the past. Excess turnover can consume an otherwise real edge.

The original R Markdown notebooks make that chain visible, which is why the project remains useful as a teaching example. The strategy itself is simple; the deeper lesson is how much research discipline is required before a simple idea becomes credible quantitative evidence.

Research disclosure: This article explains portfolio-construction and backtesting concepts using an educational implementation. It is not investment advice and does not present the original backtest as verified performance.