How to find the beta of Indian stocks using Python?

Beta is a coefficient is a measure of its volatility over time compared to a market benchmark. Market benchmark has a beta of 1. Shortly, if volatility is 1.5 it means it is 50% more volatile than the market.

  • A stock that swings more than the market over time has a beta greater than 1.0.
  • If a stock moves less than the market, the stock’s beta is less than 1.0.

Finding beta of a stock using formula

  • Get the Historical Price of the Stock or Index.
  • Get the Historical Price of the other Stock or Index against which You are trying to benchmark.
  • Calculate the Percentage Change for the same period for both the stock/index and the benchmark.
  • Calculate the covariance of the stock/index to the benchmark.
  • Calculate the Variance of the benchmark.

Now,

Beta = Covariance/Variance

In simple terms, 

  • Covariance is the measure of a stock/index’s return relative to the market.
  • Variance is the measure of how the market moves relative to its mean.

Python Code

This python code patch is written for NSEPython Library first time.  We shall use Daily as period and NIFTY 50 as default benchmark.

Part 1 - Get the Historical Price of the Stock or Index

We are using the equity_history() function. We are building Pandas Dataframe over last 10 days’ data of SBIN

				
					symbol = "SBIN"
days = 10
end_date = datetime.datetime.now().strftime("%d-%m-%Y")
end_date = str(end_date)

start_date = (datetime.datetime.now()- datetime.timedelta(days=days)).strftime("%d-%m-%Y")
start_date = str(start_date)

df = equity_history(symbol,"EQ",start_date,end_date)

df["daily_change"]=df["CH_CLOSING_PRICE"].pct_change()
df=df[['CH_TIMESTAMP','daily_change']]
df = df.iloc[1: , :] #thispointer.com/drop-first-row-of-pandas-dataframe-3-ways/
print(df)

				
			

Part 2 - Get the Historical Price of the Benchmark

We are using the index_history() function. We are building Pandas Dataframe over the last 10 days’ data of NIFTY 50 similarly as We did for SBIN

				
					symbol = "NIFTY 50"
days = 10
end_date = datetime.datetime.now().strftime("%d-%b-%Y")
end_date = str(end_date)

start_date = (datetime.datetime.now()- datetime.timedelta(days=days)).strftime("%d-%b-%Y")
start_date = str(start_date)

df2=index_history("NIFTY 50",start_date,end_date)
df2["daily_change"]=df2["CLOSE"].astype(float).pct_change()
df2=df2[['HistoricalDate','daily_change']]
df2 = df2.iloc[1: , :]
print(df2)
				
			

Output of Part 1

				
					  CH_TIMESTAMP  daily_change
1   2021-06-11     -0.001743
2   2021-06-10      0.006169
3   2021-06-09     -0.024986
4   2021-06-08      0.013643
5   2021-06-07      0.011821
				
			

Output of Part 2

				
					  HistoricalDate  daily_change
1    11 Jun 2021     -0.000791
2    10 Jun 2021     -0.003899
3    09 Jun 2021     -0.006507
4    08 Jun 2021      0.006700
5    07 Jun 2021      0.000734
				
			

There is no need for Part 3 as We have already calculated the Percentage Change using pct_change() function of Pandas.

Part 4 - Calculate the covariance of the stock/index to the benchmark

First We shall convert the daily_change column of both the Pandas Dataframe to List for our ease of Calculation. Even When in our first article, CoVariance applied on Google Sheets was done Series only. You can revisit clicking here.

				
					x=df["daily_change"].tolist()
y=df2["daily_change"].tolist()

print("List of x:")
print(x)
print("List of y:")
print(y)

#stackoverflow.com/questions/42670055/is-there-any-better-way-to-calculate-the-covariance-of-two-lists-than-this
mean_x = sum(x) / len(x)
mean_y = sum(y) / len(y)

covariance = sum((a - mean_x) * (b - mean_y) for (a,b) in zip(x,y)) / len(x)
print(covariance)
				
			

Output

				
					List of x:
[-0.0017427675148135036, 0.006168528864059608, -0.02498554077501447, 0.013643374065725578, 0.011821161048689133]
List of y:
[-0.0007905463307582572, -0.003898894574776879, -0.0065066480278311856, 0.006699562209992127, 0.0007337945756380471]
4.873388157877867e-05
				
			

Part 5 - Calculate the Variance of the benchmark

				
					mean = sum(y) / len(y)
variance = sum((i - mean) ** 2 for i in y) / len(y)
print(variance)
				
			

Output

				
					2.0150753721209677e-05

				
			

Part 6 - Getting The Beta

				
					beta = covariance/variance
print(beta)
				
			

Output

				
					2.418464453142704

				
			

So, That’s How You calculate the Beta of stock in the Indian Share Market in Python.

Wrapping Up

Here goes the final version of the get_beta() function. It has more brevity and it also fixes the mess of various types of timestamps across the equity_history() and index_history() function.

				
					def get_beta_df_maker(symbol,days):
    if("NIFTY" in symbol):
        end_date = datetime.datetime.now().strftime("%d-%b-%Y")
        end_date = str(end_date)

        start_date = (datetime.datetime.now()- datetime.timedelta(days=days)).strftime("%d-%b-%Y")
        start_date = str(start_date)

        df2=index_history(symbol,start_date,end_date)
        df2["daily_change"]=df2["CLOSE"].astype(float).pct_change()
        df2=df2[['HistoricalDate','daily_change']]
        df2 = df2.iloc[1: , :]
        return df2
    else:
        end_date = datetime.datetime.now().strftime("%d-%m-%Y")
        end_date = str(end_date)

        start_date = (datetime.datetime.now()- datetime.timedelta(days=days)).strftime("%d-%m-%Y")
        start_date = str(start_date)

        df = equity_history(symbol,"EQ",start_date,end_date)

        df["daily_change"]=df["CH_CLOSING_PRICE"].pct_change()
        df=df[['CH_TIMESTAMP','daily_change']]
        df = df.iloc[1: , :] #thispointer.com/drop-first-row-of-pandas-dataframe-3-ways/
        return df

def get_beta(symbol,days,symbol2="NIFTY 50"):
    df = get_beta_df_maker(symbol,days)
    df2 = get_beta_df_maker(symbol2,days)

    x=df["daily_change"].tolist()
    y=df2["daily_change"].tolist()
    #stackoverflow.com/questions/42670055/is-there-any-better-way-to-calculate-the-covariance-of-two-lists-than-this
    mean_x = sum(x) / len(x)
    mean_y = sum(y) / len(y)
    covariance = sum((a - mean_x) * (b - mean_y) for (a,b) in zip(x,y)) / len(x)

    mean = sum(y) / len(y)
    variance = sum((i - mean) ** 2 for i in y) / len(y)

    beta = covariance/variance
    return round(beta,3)


for x in fnolist():
    try:
        print(x+" : "+str(get_beta(x,255)))
        break
    except:
        pass

#NIFTY Against NIFTY Bank
x = "NIFTY 50"
print(x+" : "+str(get_beta(x,255,"NIFTY BANK")))

#NIFTY Bank Against NIFTY
x = "NIFTY BANK"
print(x+" : "+str(get_beta(x,255)))
				
			

Output

				
					TORNTPHARM : -0.168
NIFTY 50 : 0.55
NIFTY BANK : 1.395
				
			

If You remove the break command in the Line 49 as highlighted here, You will get the list of entire stocks of FNO and their Betas.

Note – We used 255 as Number of Days because it is globally assumed that, there are 255 trading days. For near-term correlation, feel free to change the values.

Join The Conversation?