Use Python to Calculate the Sharpe Ratio of Indian Stock using Python

The Sharpe Ratio, named after William F. Sharpe, is a popular risk-adjusted measure used by investors to understand the return of an investment compared to its risk. The ratio is the average return earned in excess of the risk-free rate per unit of volatility or total risk. Volatility is a measure of the price fluctuations of an asset or portfolio.

Formula of Sharpe Ratio

The formula for calculating the Sharpe Ratio is: \[ \text{Sharpe Ratio} = \frac{ (\text{Expected return of the investment} – \text{Risk-free rate})}{\text{Standard deviation of the investment’s returns}} \] Where,
  • Expected return of the investment is the mean return of the investment.
  • Risk-free rate is the return of a risk-free investment, like a government bond.
  • Standard deviation of the investment’s returns is a measure of the investment’s volatility.


Let’s compute the Sharpe Ratio of SBIN (State Bank of India) stock using the nsepython library, which provides historical price data of stocks listed on the National Stock Exchange (NSE) of India.

This python code patch is written for NSEPython Library first time. 

Step 1: Import Necessary Libraries

  • Importing necessary libraries is crucial as they provide the functions and structures needed for the computation.
  • In this case, we import pandas for data handling, nsepython for fetching stock data, and numpy for numerical operations.
					import datetime
from nsepython import *


Step 2: Get Historical Price Data

  • Fetching historical data is essential to calculate past returns which will be used to estimate future returns.
  • We use the equity_history function from nsepython to get the historical closing prices of SBIN for a specific date range. 
					# Define the date range for the past one year
today ='%d-%m-%Y')
one_year_ago = ( - datetime.timedelta(days=365)).strftime('%d-%m-%Y')

# Get the historical data for SBIN
sbin_data = equity_history("SBIN", "EQ", one_year_ago, today)


Step 3: Calculate Daily Returns

  • Daily returns provide insight into the asset’s performance on a day-to-day basis which is crucial for risk and return assessment.
  • We calculate daily returns by finding the percentage change in closing prices from one day to the next using the pct_change() method.
					# Calculate the daily returns from the closing prices
sbin_daily_returns = sbin_data['CH_CLOSING_PRICE'].pct_change().dropna()


Step 4: Calculate Standard Deviation of Returns

  • The average annual return gives an average rate of how much the investment grows each year, crucial for comparing different investments.
  • We calculate it by finding the mean of daily returns and annualizing it.
					# Annualize the standard deviation of daily returns
sbin_std_dev = sbin_daily_returns.std() * (252**0.5)


Step 5: Calculate Expected Return

  • Standard deviation measures the amount of variation in the returns, which is vital for understanding the investment’s risk profile.
  • We annualize the standard deviation to get a yearly measure which is more interpretable.
					# Calculate the mean of daily returns and annualize it
historical_return = sbin_daily_returns.mean() * 252


Step 6: Assume a Risk-Free Rate

  • The risk-free rate is a hypothetical rate of return with zero risk, essential for assessing the performance of risky assets.
  • In this example, we assume a risk-free rate of 10%, but it’s typically based on government bond yields.
					# Assuming a 10% risk-free rate
risk_free_rate = 10


Step 7: Calculate the Sharpe Ratio

  • The Sharpe Ratio provides a measure of the performance of the investment compared to the risk taken, which is crucial for informed investment decisions.
  • We calculate the Sharpe Ratio using the formula, which involves dividing the difference between the expected return and the risk-free rate by the standard deviation of the returns.
					# Substitute the values into the Sharpe Ratio formula
sharpe_ratio = (historical_return - risk_free_rate) / sbin_std_dev
print(f"Sharpe Ratio: {sharpe_ratio}")



					Sharpe Ratio: -27.062212583162538


A higher Sharpe Ratio indicates that the investment’s returns are more resilient to volatility, and hence, might be considered better on a risk-adjusted basis.

A Sharpe Ratio of -27.06 for SBIN indicates a significantly unfavorable risk-adjusted performance over the past year. Here’s what this entails:

  1. Negative Sharpe Ratio: A negative Sharpe Ratio suggests that the investment’s returns were less than the risk-free rate during the specified time period. In simpler terms, the investment failed to compensate for the risks undertaken, as even a risk-free asset like a government bond would have yielded better returns.

  2. High Risk or Low Return: The negative value could arise from either high volatility (risk) or low expected return, or a combination of both. In this case, despite the high risks associated with the investment, the returns were not sufficient to justify those risks, leading to a negative Sharpe Ratio.

  3. Risk-Adjusted Performance: Sharpe Ratio is a tool for investors to understand how much excess return they are receiving for the extra volatility endured while holding a riskier asset. A negative value indicates a poor risk-adjusted performance, where the investment’s returns did not justify the level of risk involved.

The unfavorable Sharpe Ratio suggests that investors would have been better off by investing in a risk-free asset rather than in SBIN, given the level of risk associated with SBIN over the analyzed period. This scenario underscores the importance of not only looking at the returns but also considering the risk involved to achieve those returns.

Wrapping Up

Here goes the final version of the sharpe_ratio() function. 

					def sharpe_ratio(symbol, series, risk_free_rate, start_date=None, end_date=None):
    Calculate the Sharpe Ratio of a given equity.
        symbol (str): The ticker symbol of the equity (e.g., "SBIN").
        series (str): The series code (e.g., "EQ").
        risk_free_rate (float): The annual risk-free rate as a percentage (e.g., 10 for 10%).
        start_date (str, optional): The start date for historical data in 'dd-mm-yyyy' format.
        end_date (str, optional): The end date for historical data in 'dd-mm-yyyy' format.
        float: The Sharpe Ratio of the equity.
    # Set default values for start_date and end_date to cover a one-year period if not provided
    if not end_date:
        end_date ='%d-%m-%Y')
    if not start_date:
        start_date = ( - datetime.timedelta(days=365)).strftime('%d-%m-%Y')
    # Get the historical data for the specified equity
    equity_data = equity_history(symbol, series, start_date, end_date)
    # Calculate the daily returns
    daily_returns = equity_data['CH_CLOSING_PRICE'].pct_change().dropna()
    # Calculate the annualized standard deviation of daily returns
    annualized_std_dev = daily_returns.std() * (252**0.5)
    # Calculate the historical annual return from the daily returns
    historical_annual_return = (daily_returns.mean() + 1)**252 - 1
    # Calculate and return the Sharpe Ratio
    return (historical_annual_return - risk_free_rate) / annualized_std_dev

# Example usage:
sbin_sharpe_ratio = sharpe_ratio("SBIN", "EQ", 10)
print(f"Sharpe Ratio: {sbin_sharpe_ratio}")


					Sharpe Ratio: -27.062212583162538


Does this indicate a higher likelihood of mean reversion?

The Sharpe Ratio primarily informs about the risk-adjusted performance of an investment or a portfolio. It doesn’t provide direct insights into the likelihood of mean reversion. However, here’s a nuanced way to interpret it in the context of mean reversion:

  1. Negative Sharpe Ratio: A negative Sharpe Ratio, as in the case of SBIN in your calculations, indicates that the investment has performed worse than a risk-free asset, even after adjusting for volatility. This underperformance could possibly be a sign of mean reversion if the asset has historically had higher returns. However, this is speculative and would require further analysis.

  2. Low Sharpe Ratio: A low or negative Sharpe Ratio could potentially indicate a scenario where mean reversion might occur, especially if the asset has deviated significantly from its historical average return. However, it’s crucial to note that mean reversion isn’t guaranteed and other factors could prevent the asset from reverting to its mean.

  3. Additional Analysis: To better understand the likelihood of mean reversion, investors often look at other statistical measures and analyses such as examining the asset’s historical return distribution, using statistical tests for mean reversion (e.g., Augmented Dickey-Fuller test), or employing technical indicators.

It’s important to conduct a more thorough analysis to understand the likelihood of mean reversion, as the Sharpe Ratio alone doesn’t provide conclusive evidence in this regard.

Join The Conversation?

Post a comment

Leave a Comment

Your email address will not be published. Required fields are marked *