看到社群大佬对这个策略已经有很好的诠释了,看了回测数据也是真的厉害,出于兴趣,就自己做了一下分析,感觉抓上涨很有效,对于下跌判断没有上涨敏感,但对规避大熊市感觉还是可以的。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import StandardScaler
security = '000001.XSHG'
prices = get_price(security, '2005-01-05', '2019-01-01', '1d', ['high', 'low', 'open'])
long = 18 #beta calculation period
def caculate_beta(long, prices):
beta_list = [] #beta list
R_list = [] #r squared list
for i in range(long,len(prices)):
X = prices.low[i-long:i].reshape(-1,1)
y = prices.high[i-long:i].reshape(-1,1)
reg = LinearRegression().fit(X,y)
beta_list.append(reg.coef_[0][0])
R_list.append(reg.score(X,y))
R_list = np.asarray(R_list).reshape(-1,1)
beta_list = np.asarray(beta_list).reshape(-1,1)
#standardize beta
scaler = StandardScaler()
beta_std = scaler.fit_transform(beta_list)
beta_rightdev = R_list*beta_list*beta_std
return (beta_list,beta_std,beta_rightdev)
beta_list, beta_std, beta_rightdev = caculate_beta(long,prices)
sns.distplot(beta_std)
plt.show()
sns.distplot(beta_rightdev)
plt.show()
sns.distplot(beta_rightdev,hist_kws={'cumulative': True}, kde_kws={'cumulative': True})
plt.show()
hold_period = [10,30,60,90]
def calculate_return_df(price,hold_period):
#price has to be a series
origional_name = price.name
#turn price series to df
price = pd.DataFrame(price)
for i in hold_period:
return_arr = price[origional_name]/price[origional_name].shift(i)-1
return_arr = return_arr.dropna().values
for y in range(i):
return_arr = np.append(return_arr,np.nan)
price[str(y+1)+'_days_return'] = return_arr
return price
return_df = calculate_return_df(prices.open,hold_period)
return_df.head()
open | 10_days_return | 30_days_return | 60_days_return | 90_days_return | |
---|---|---|---|---|---|
2005-01-05 | 1241.68 | -0.013369 | 0.056126 | -0.013393 | -0.149282 |
2005-01-06 | 1252.49 | -0.031234 | 0.047066 | -0.003465 | -0.161894 |
2005-01-07 | 1239.32 | -0.030170 | 0.053199 | -0.000153 | -0.143393 |
2005-01-10 | 1243.58 | 0.011612 | 0.048031 | -0.011748 | -0.147936 |
2005-01-11 | 1252.71 | -0.000287 | 0.025936 | -0.000399 | -0.172410 |
for _ in range(long):
beta_list = np.append(np.nan,beta_list.reshape(1,-1)[0])
for _ in range(long):
beta_std = np.append(np.nan,beta_std.reshape(1,-1)[0])
for _ in range(long):
beta_rightdev = np.append(np.nan,beta_rightdev.reshape(1,-1)[0])
return_df['beta'] = beta_list
return_df['beta_standardized'] = beta_std
return_df['beta_rightdev'] = beta_rightdev
return_df.head()
open | 10_days_return | 30_days_return | 60_days_return | 90_days_return | beta | beta_standardized | beta_rightdev | |
---|---|---|---|---|---|---|---|---|
2005-01-05 | 1241.68 | -0.013369 | 0.056126 | -0.013393 | -0.149282 | NaN | NaN | NaN |
2005-01-06 | 1252.49 | -0.031234 | 0.047066 | -0.003465 | -0.161894 | NaN | NaN | NaN |
2005-01-07 | 1239.32 | -0.030170 | 0.053199 | -0.000153 | -0.143393 | NaN | NaN | NaN |
2005-01-10 | 1243.58 | 0.011612 | 0.048031 | -0.011748 | -0.147936 | NaN | NaN | NaN |
2005-01-11 | 1252.71 | -0.000287 | 0.025936 | -0.000399 | -0.172410 | NaN | NaN | NaN |
return_df = return_df.dropna()
return_df.head()
open | 10_days_return | 30_days_return | 60_days_return | 90_days_return | beta | beta_standardized | beta_rightdev | |
---|---|---|---|---|---|---|---|---|
2005-01-31 | 1210.76 | 0.081651 | -0.004130 | -0.062903 | -0.092339 | 0.765083 | -1.117775 | -0.651961 |
2005-02-01 | 1189.50 | 0.098815 | 0.009046 | -0.056595 | -0.074771 | 0.794287 | -0.874047 | -0.560804 |
2005-02-02 | 1189.50 | 0.102455 | 0.014880 | -0.073888 | -0.081976 | 0.840015 | -0.492419 | -0.345942 |
2005-02-03 | 1253.81 | 0.045964 | -0.039049 | -0.118367 | -0.115927 | 0.698184 | -1.676084 | -0.754894 |
2005-02-04 | 1238.61 | 0.053802 | -0.031422 | -0.118964 | -0.095002 | 0.726553 | -1.439331 | -0.669978 |
y_list = ['10_days_return','30_days_return','60_days_return','90_days_return']
X_list = ['beta','beta_standardized','beta_rightdev']
fig , axes = plt.subplots(nrows=3,ncols=4,figsize=(30, 20))
plt.figure(20)
for x in range(1,len(X_list)+1):
for y in range(1,len(y_list)+1):
axes[x-1][y-1].scatter(return_df[X_list[x-1]],return_df[y_list[y-1]])
plt.show()
<matplotlib.figure.Figure at 0x7fe56c0b5050>
def plot_df(return_df,variable):
analysis_df = return_df.loc[:,[variable,'10_days_return','30_days_return','60_days_return','90_days_return']]
group_df = analysis_df.groupby(pd.cut(analysis_df[variable],20)).mean().drop([variable],axis=1)
group_df.plot()
plt.show()
plot_df(return_df,'beta')
plot_df(return_df,'beta_standardized')
plot_df(return_df,'beta_rightdev')
return_df.head()
open | 10_days_return | 30_days_return | 60_days_return | 90_days_return | beta | beta_standardized | beta_rightdev | |
---|---|---|---|---|---|---|---|---|
2005-01-31 | 1210.76 | 0.081651 | -0.004130 | -0.062903 | -0.092339 | 0.765083 | -1.117775 | -0.651961 |
2005-02-01 | 1189.50 | 0.098815 | 0.009046 | -0.056595 | -0.074771 | 0.794287 | -0.874047 | -0.560804 |
2005-02-02 | 1189.50 | 0.102455 | 0.014880 | -0.073888 | -0.081976 | 0.840015 | -0.492419 | -0.345942 |
2005-02-03 | 1253.81 | 0.045964 | -0.039049 | -0.118367 | -0.115927 | 0.698184 | -1.676084 | -0.754894 |
2005-02-04 | 1238.61 | 0.053802 | -0.031422 | -0.118964 | -0.095002 | 0.726553 | -1.439331 | -0.669978 |
df = return_df[return_df.beta_rightdev<-0.9].loc[:,y_list]>0
df.sum()/len(df)
10_days_return 0.735023 30_days_return 0.672811 60_days_return 0.622120 90_days_return 0.629032 dtype: float64
hold_period = [0.7,1,1.5]
def bet_probability(hold_period, sign):
if sign > 0:
for i in hold_period:
df = return_df[return_df.beta_rightdev>i].loc[:,y_list]>0
print df.sum()/len(df)
print ""
print 'sample size is '+str(len(df))
print ""
print ">>>>>>>>>>>>>>>>>"
else:
for i in hold_period:
df = return_df[return_df.beta_rightdev<i*-1].loc[:,y_list]>0
print df.sum()/len(df)
print ""
print 'sample size is '+str(len(df))
print ""
print ">>>>>>>>>>>>>>>>>"
bet_probability(hold_period,1)
10_days_return 0.730530 30_days_return 0.677570 60_days_return 0.627726 90_days_return 0.627726 dtype: float64 sample size is 642 >>>>>>>>>>>>>>>>> 10_days_return 0.735065 30_days_return 0.664935 60_days_return 0.597403 90_days_return 0.612987 dtype: float64 sample size is 385 >>>>>>>>>>>>>>>>> 10_days_return 0.768786 30_days_return 0.705202 60_days_return 0.653179 90_days_return 0.722543 dtype: float64 sample size is 173 >>>>>>>>>>>>>>>>>
hold_period = [0.7,0.9,1.1]
bet_probability(hold_period,-1)
10_days_return 0.448468 30_days_return 0.495822 60_days_return 0.526462 90_days_return 0.529248 dtype: float64 sample size is 359 >>>>>>>>>>>>>>>>> 10_days_return 0.443609 30_days_return 0.421053 60_days_return 0.458647 90_days_return 0.533835 dtype: float64 sample size is 133 >>>>>>>>>>>>>>>>> 10_days_return 0.368421 30_days_return 0.684211 60_days_return 0.736842 90_days_return 0.736842 dtype: float64 sample size is 19 >>>>>>>>>>>>>>>>>
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程