Click to Download Workbook: Sortino Ratio
Before we delve into an explanation of how the Sortino Ratio is calculated, you should probably understand an extremely popular risk-adjusted measure: the Sharpe Ratio.
The Sharpe ratio is a very popular risk-adjusted measure. With the Sharpe ratio, we are looking at volatility or the standard deviation of a portfolio or fund. The ratio is calculated as:
Sharpe Ratio = (Return on Portfolio – Risk Free Rate) / Portfolio Standard Deviation
A value of 1 is considered acceptable, while a value above 2 is considered exceptional.
The Sortino Ratio is quite similar but far less popular. Instead of standard deviation, the Sortino Ratio uses downside deviation within the denominator of the calculation. Downside Deviation is essentially the standard deviation of all negative returns of the portfolio. We also selected a minimum acceptable return as well. This will be explained within the Excel calculation.
The idea with the Sortino Ratio is that examining positive returns or upside volatility is irrelevant, as investors theoretically should be concerned more with downside deviation
This concept is better explained in Excel, although we examine how this can be done in R with the PerformanceAnalytics package also.
Concept Within Excel:
First, we need to generate portfolio returns. I did this in R for a variety of assets in monthly terms. The key with the Sortino Ratio is that we have to choose a minimum acceptable return. The idea of choosing a minimum acceptable return (MAR) is that any return above the MAR is not included for the purpose of calculating the risk-adjusted measure. In many cases, the MAR is set to 0% as a default.
1.) We can first calculate the excess returns which are are the portfolio returns for each month subtracted from the MAR.
2.) We can then select only negative excess returns from the series with a simple if statement.
3.) Calculate Downside Deviation and the Average Excess Return.
-Square each negative excess return and sum them together
-Sum the squares of the excess returns together and divide by the number of periods (in this case the count of all of the months = 22)
-Take the square root of this number and you will arrive at the Downside Deviation metric.
Average Excess Return:
-Take the mean of the entire excess returns range including those > 0.
4.) Compute the Sortino Ratio by dividing the Average of the Excess Returns over the Downside Deviation.
Note we can drastically simplify the Downside Deviation Calculation by using the SUMSQ function, which takes the sum of the squares of a series. We can also express the Downside Deviation and Average Excess Return in annual terms as well.
Now that we have an idea of how the Sortino Ratio is calculated, let’s make it simple with R and PerformanceAnalytics.
First, we need to obtain the data and return a series of aggregate portfolio returns. I am assuming a portfolio of 10 assets all with equal weights.
#----------------------Getting the Data----------------------#
#Create Vector of Tickers
tickers <- c("HD", "IBKR", "CCL", "T", "BK","GE", "V", "ORBK", "ZTS", "SNA")
#Get Prices (can be monthly or weekly)
portfolioPrices <- NULL
for (Ticker in tickers)
portfolioPrices <- cbind(portfolioPrices,
getSymbols.yahoo(Ticker, from="2016-01-03", periodicity = "monthly", auto.assign=FALSE)[,4])
#Delete all dates with no prices
portfolioPrices <- portfolioPrices[apply(portfolioPrices,1,function(x) all(!is.na(x))),]
colnames(portfolioPrices) <- tickers
#Calculate Returns for Assets: Daily RoC
portfolioReturns <- na.omit(ROC(portfolioPrices, type="discrete"))
#Calculate Aggregate Returns for Portfolio (Equal Weight)
#Calculate Aggregate Returns For Portfolio
combined_rets <- Return.portfolio(portfolioReturns, weights = weights, geometric = TRUE)
names(combined_rets) <- "Portfolio"
Next, we can calculate each ratio quite easily with built-in PerformanceAnalytics functions. Note for the risk-free, I am obtaining data for a 6-month treasury bill over the last year and taking the arithmetic mean as my risk-free rate. I am also setting the MAR for the Sortino as 1%. The output of the calculation is displayed below with the source code beneath it. Note for the Sharpe ratio we are asked to input a confidence interval as well. In the output, we receive three Sharpe ratios all using different risk metrics. Focus on the StdDev Sharpe which is most commonly used. However, the VaR (Value at Risk) Sharpe and ES (Conditional Value at Risk) are great additions to the output of the SharpeRatio function. Explaining each of those ratios is outside the scope of this post.
#----------------------Calculate Sortino Ration (And Sharpe)----------------------#
SortinoRatio(combined_rets, MAR = .01, weights = NULL)
#Risk Free Data For Sharpe
rf_data = Quandl("USTREASURY/YIELD",start_date="2016-11-13")
rf <- data.frame(rf_data)
rf <- colMeans(rf[sapply(rf, is.numeric)])
rf = rf/100
SharpeRatio(combined_rets, Rf = rf, p = 0.95,
weights = NULL)