Quantitative assessment

Annualized yield

Annualized rate of return is the current rate of return ( Daily yield , Weekly yield , Monthly yield ) Converted to the adult rate of return , It's a theoretical rate of return , It's not a real rate of return . Because annualized yield is variable , So the annual rate of return is not necessarily the same as the annualized rate of return .

Total yield :R=\frac{P_T-P_t}{P_t}
among ,P_T It's the selling price at the end of the period ,P_t It's the price at the beginning of the period .

Annualized yield :R_p=(1+R)^{\frac{m}{n}}-1
among ,R Is the total rate of return during the period ,m Is it with n( It can be days , Number of weeks , Number of months ) Corresponding calculation period , According to calculation Convention ,m=250,52,12 Refer to the day respectively , week , The conversion from month to year .

Maximum retracement

Push back at any historical point in the selected period , When the net value of the product reaches the lowest point, the maximum rate of return withdrawal . The maximum pullback is used to describe the worst possible situation after buying a product . Maximum withdrawal is an important risk indicator , For hedge funds and quantitative strategy Trading , This indicator is more important than volatility .
P Is the net value of a day ,i For one day ,j by i Some day after ,Pi For the first time i Net value of products per day ,Pj then is Pi Net value on a later day
The maximum withdrawal rate of the fund is calculated as follows :
Max\_drawdown=\frac{max(P_i-P_j)}{P_i}
That is to say, the withdrawal rate of each net value is evaluated , And then find the biggest one .

Beta: Beta coefficient

* It is equivalent to the overall volatility of performance evaluation benchmark income
beta=\beta_p=\frac{Cov(P_i,P_m)}{Var_m}

* Measuring the systemic risk of strategy :
If Beta by 1, Strategy and market ( Refer to Shanghai and Shenzhen 300 index ) Advance and retreat together
If Beta by 1.1, Market up 10% Time , Strategy up 11%; Market downturn 10% Time , Strategic decline 11%.
If Beta by 0.9, Market up 10% Time , Strategy up 9%; Market downturn 10% Time , Strategic decline 9%.

So here comes the question... , Beta Is the value great or small ?
This needs to be analyzed in detail , If it's a bull market , Prosperous stock market , Individual stocks , The market is soaring , Then you have to choose Beta High value strategy ;
If it's a bear market , Downward pressure on economy , We should choose Beta Low value strategy , In this way, we can better control the risk , Ensure the safety of funds .

Alpha: Alpha coefficient

* Actual income and income Beta The difference between the expected returns calculated by the coefficient .
* Represents the extent to which the strategy outperforms the expected rate of return

beta and alpha An estimate of

there beta and alpha The coefficients come from the capital asset pricing model , Let's have a look first CAPM:
E(r_i)=r_f+\beta (E(r_m)-r_f)
E(r_i) It's stocks i Expected rate of return ,r_f It's a risk-free rate ,E(r_m) It's the market index yield ;

\beta Coefficient is systemic risk , In the evaluation of stock market volatility risk and investment opportunities , It is often used to measure structural and systemic risks , It can be simply understood as the deviation degree of individual stock volatility from the market volatility .CAPM The econometric model can be expressed as :
r_i=\alpha+\beta r_m+\varepsilon
\alpha It can be understood as the excess rate of return ,\varepsilon It's a random disturbance , It can be understood as individual risk .

sharpe ratio

* On behalf of investors to take every extra risk , How much can I get ;
--- Excess rate of return per unit risk
* The higher the ratio , The higher the excess rate of return, the higher the unit risk .
So the Sharpe ratio is the higher the better ..

Sharpe\_ratio= \frac{R_p-R_f}{\sigma_p}
among ,R_p Annualized yield , R_f It's the risk-free rate of return ,\sigma_p Annualized volatility

Information ratio

Information\_ratio=\frac{R_p-R_m}{\sigma_t}
among ,R_p Annualized yield , R_f It is the base annualized rate of return ( Such as Shanghai and Shenzhen 300 index ),\sigma_t Is the annualized standard deviation of the difference between the strategy and the benchmark daily rate of return

Python Calculation examples

use tushare Get transaction data , Consider the simplest strategy : Buy hold ! Calculate the total rate of return for each period separately , Annualized yield , Maximum retracement ,beta,alpha coefficient , Sharpe ratio and information ratio .

# First introduce the package that may be used later (package)
import pandas as pd  
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline   

# Normal display of Chinese and minus sign when drawing
from pylab import mpl
mpl.rcParams['font.sans-serif']=['SimHei']
mpl.rcParams['axes.unicode_minus']=False
### get data :tushare Open source library ( Confirm that it is installed :pip install tushare)
import tushare as ts
# Start and end dates are optional , Otherwise, use the default
def get_data(code,start_date="2009-01-01", end_date="2019-01-18"):
    df = ts.get_k_data(code, start=start_date, end=end_date)
    df.index=pd.to_datetime(df.date)
    return df.close
# Return to closing price
# Shanghai Composite Index , Maotai, Guizhou , Industrial and Commercial Bank of China , China Ping An as an example
stocks={'sh':' Shanghai Composite Index ','600519':' Maotai, Guizhou ',
        '601398':' Industrial and Commercial Bank of China ','601318':' Ping An, China '}
# Acquire the above shares ( index ) The closing price of each day's right
df=pd.DataFrame()
for code,name in stocks.items():
    df[name]=get_data(code)
df.head()
# Take the first trading day as an example 2009 year 1 month 5 The daily closing price is the base point , Calculate net worth
df_new=df/df.iloc[0]
# Visualize the net value of the above stocks during the back test period
df_new.plot(figsize=(16,7))
# Icon title
plt.title(' Trend of net stock price ',fontsize=15)
# set up x Axis coordinates
my_ticks = pd.date_range('2008-01-01','2019-01-18',freq='Y')
plt.xticks(my_ticks,fontsize=12)
# Remove the upper part , The line on the right
ax=plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
plt.show()
[ Picture upload failed ...(image-dab38d-1548119602931)]

Cumulative rate of return and annualized rate of return

The yield can be calculated according to the above formula , Or use a logarithmic rate of return , Can also be based on the above cumulative net to launch the cumulative rate of return ( Accumulated Net -1).

### Interval cumulative yield ( Absolute rate of return )
total_ret=df_new.iloc[-1]-1
TR=pd.DataFrame(total_ret.values,columns=[' Cumulative yield '],index=total_ret.index)
TR
### Annualized yield , Let's assume that in a year 250 Trading day calculation
annual_ret=pow(1+total_ret,250/len(df_new))-1
AR=pd.DataFrame(annual_ret.values,columns=[' Annualized yield '],index=annual_ret.index)
AR
Maximum retracement

actually ,numpy and pandas With the help of library functions, we can calculate the maximum rollback in one line of code .

#numpy:np.maximum.accumulate Calculate the cumulative maximum value of the sequence
code=' Shanghai Composite Index '

n_d=((np.maximum.accumulate(df[code])-df[code])/np.maximum.accumulate(df[code])).max()
#pandas use cummax() Calculate the cumulative maximum value of the sequence
p_d=((df[code].cummax()-df[code])/df[code].cummax()).max()
# Print results
print(f'numpy Method calculation results :{round(n_d*100,2)}%')
print(f'pandas Method calculation results :{round(p_d*100,2)}%')                    
numpy Method calculation results :52.3%
pandas Method calculation results :52.3%
# Defined as a function , Reduce duplication of work
def max_drawdown(df):
    md=((df.cummax()-df)/df.cummax()).max()
    return round(md,4)
md={}
for code,name in stocks.items():
    md[name]=max_drawdown(df[name])
# Maximum pullback rate results :
MD=pd.DataFrame(md,index=[' Maximum retracement ']).T
MD
alpha and beta

Use regression to estimate alpha and beta Value of .

# Calculate daily yield
# Closing price missing value ( Suspension of trading ), Use pre value instead
rets=(df.fillna(method='pad')).apply(lambda x:x/x.shift(1)-1)[1:]
rets.head()
# The market index is x, The yield of individual stock is y
from scipy import stats
x=rets.iloc[:,0].values
y=rets.iloc[:,1:].values
AB=pd.DataFrame()
alpha=[]
beta=[]
for i in range(3):
# use scipy Library in stats.linregress linear regression
#python There are many ways to achieve regression ,
# as statsmodels.api Of OLS,sklearn Library, etc
    b,a,r_value,p_value,std_err=stats.linregress(x,y[:,i])
    #alpha Turn into annualized
    alpha.append(round(a*250,3))
    beta.append(round(b,3))
AB['alpha']=alpha
AB['beta']=beta
AB.index=rets.columns[1:]
# Output results :
AB
# Direct calculation with formula method beta value ( See formula above ):
beta1=rets[[' Shanghai Composite Index ',' Maotai, Guizhou ']].cov().iat[0,1]/rets[' Shanghai Composite Index '].var()
beta2=rets[[' Shanghai Composite Index ',' Industrial and Commercial Bank of China ']].cov().iat[0,1]/rets[' Shanghai Composite Index '].var()
beta3=rets[[' Shanghai Composite Index ',' Ping An, China ']].cov().iat[0,1]/rets[' Shanghai Composite Index '].var()
print(f' Maotai, Guizhou beta:{round(beta1,3)}')
print(f' Industrial and Commercial Bank of China beta:{round(beta2,3)}')
print(f' Ping An, China beta:{round(beta3,3)}')
Maotai, Guizhou beta:0.637
Industrial and Commercial Bank of China beta:0.614
Ping An, China beta:1.071
# Direct calculation with formula method beta value ( See formula above ):
#annual_ret It is the annualized rate of return calculated above
alpha1=(annual_ret[1]-annual_ret[0]*beta1)
alpha2=(annual_ret[2]-annual_ret[0]*beta2)
alpha3=(annual_ret[3]-annual_ret[0]*beta3)
print(f' Maotai, Guizhou alpha:{round(alpha1,3)}')
print(f' Industrial and Commercial Bank of China alpha:{round(alpha2,3)}')
print(f' Ping An, China alpha:{round(alpha3,3)}')
Maotai, Guizhou alpha:0.244
Industrial and Commercial Bank of China alpha:0.077
Ping An, China alpha:0.138
Sharpe ratio and information ratio

# The excess rate of return is based on the risk-free rate of return
# Assume that the risk-free rate of return is annualized 3%
exReturn=rets-0.03/250
# Calculate Sharpe ratio
sharperatio=np.sqrt(len(exReturn))*exReturn.mean()/exReturn.std()
# Output of Sharpe ratio
SHR=pd.DataFrame(sharperatio,columns=[' sharpe ratio '])
SHR
### Information ratio
# The excess rate of return is based on index rate of return or others
# Here, the Shanghai composite index is the benchmark
ex_return=pd.DataFrame() 
ex_return[' Maotai, Guizhou ']=rets.iloc[:,1]-rets.iloc[:,0]
ex_return[' Industrial and Commercial Bank of China ']=rets.iloc[:,2]-rets.iloc[:,0]
ex_return[' Ping An, China ']=rets.iloc[:,3]-rets.iloc[:,0]
ex_return.head()
# Calculate information ratio
information=np.sqrt(len(ex_return))*ex_return.mean()/ex_return.std()
# Output of information ratio
INR=pd.DataFrame(information,columns=[' Information ratio '])
INR
# Combine the above indicators into one table
indicators=pd.concat([TR,AR,MD,AB,SHR,INR],axis=1,join='outer',sort='False')
# The result is kept to three decimal places
indicators.round(3)

Technology