(1)篩選
使用作業1的程序
- 完成對滬深300指數成分股過去2015年1月-2018年1月三年的數據分析
- 按alpha從大到小,選擇出30只alpha最高的股票形成股票池1,以備進一步分析
(2)預測
- 對滬深300指數成分股2018年1月-2021年1月三年的數據分析
- 選擇出30只alpha最高的股票形成股票池2
- 觀察股票池1和股票池2的重合度
- 分別計算股票池1在2015-2018時間段和2018-2021時間段的Alpha均值,觀察Alpha均值的變化
- 對觀察結果進行思考與分析
股票基礎信息獲取網站

將滬深300的成分股的基礎信息整合到txt文件中

將獲取的股票基礎信息整理成csv文件便於在Python中讀取

使用tushare庫爬取股票交易數據,建立CAMP模型,進行分析,廢話不多話,直接上代碼!
"""
python3.7
-*- coding: UTF-8 -*-
@Project -> File :Code -> CAMP
@IDE :PyCharm
@Author :YangShouWei
@USER: 296714435
@Date :2021/4/6 15:41:37
@LastEditor:
"""
import pandas as pd
import tushare as ts
import matplotlib.pyplot as plt
import statsmodels.api as sm
import re
import numpy as np
def modelCAMP(code,name, starttime, endtime):
# 資本資產進價模型(CAPM)
# Ri -Rf = β*(Rm-Rf) + ε
# 載入股指數據
sh = ts.get_k_data('sh', start=starttime,end=endtime, autype='qfq') # 獲取上證數據
sh["p_change"] = (sh["close"] / sh["close"].shift(1) - 1) * 100 # 利用今日收盤價和前日收盤價計算股價波動,新增一列
try:
gzmt = ts.get_k_data(code, start=starttime,end=endtime, autype='qfq') # 獲取股票數據
# 一些企業在2018年之前還未上市,作為特殊情況處理,返回0
if len(gzmt.date) == 0:
return [0]
gzmt["p_change"] = (gzmt["close"] / gzmt["close"].shift(1) - 1) * 100
except:
return [0]
# print(code)
ret_merge = pd.merge(pd.DataFrame(sh.p_change), pd.DataFrame(gzmt.p_change), left_index = True, right_index = True, how = 'inner')
# 計算日無風險利率
Rf_year = 0.04 # 以2018 年中國三年期國債年化收益率為無風險利率
Rf = (1+Rf_year)**(1/365)-1 # 年利率轉化為日利率
# 計算風險溢價:Ri-Rf
Eret = ret_merge-Rf
Eret.head()
# 畫出兩個風險溢價的散點圖,查看相關性
plt.scatter(Eret.values[:, 0], Eret.values[:,1])
# plt.show()
# 利用最小二乘法進行線性回歸,擬合CAPM 模型
md_capm = sm.OLS(Eret.p_change_y[1:], sm.add_constant(Eret.p_change_x[1:]))
result = md_capm.fit()
text = str(result.summary())
print("\n{}CAMP建立".format(name))
print(result.summary())
alpha = result.params[0] # α系數
Beita = result.params[1] # β系數
Pvalue = result.pvalues[1]
print("a={},β={},pvalue={}".format(alpha,Beita,Pvalue))
# print("{}的α系數:{},β系數:{}".format(name,number1,number2))
return [alpha, Beita]
def readData():
# 讀取滬深300成分股的基礎信息
data = pd.read_csv('one.csv')
# print(data.head())
# print(data.columns)
# 處理數據,將股票代碼的數據類型從int轉換成字符串
code =[]
for i in data['股票代碼']:
if i<10:
i = '00000'+str(i)
elif i<100:
i = '0000' + str(i)
elif i < 1000:
i = '000' + str(i)
elif i < 10000:
i = '00' + str(i)
elif i < 100000:
i = '0' + str(i)
else:
i = str(i)
code.append(i)
data["股票代碼"] = code
plt.rcParams["font.sans-serif"] = "SimHei" #設置圖片中字體為中文黑體
# 繪制滬深300指數成分股行業匯總統計圖
draw = pd.DataFrame({"行業": data.groupby('主營行業')["主營行業"].count()})
draw.plot(kind="barh")
plt.title("滬深300成分股行業統計圖")
plt.xlabel("數量")
plt.ylabel("行業名稱")
plt.tick_params(axis='x', labelsize=8)
plt.tick_params(axis='y', labelsize=8)
plt.show()
return data
if __name__ == "__main__":
data = readData() # 讀取股票基礎數據
info ={"股票代碼":list(data["股票代碼"]), "企業名稱": list(data['股票簡稱']),"主營行業":list(data["主營行業"])}
df = pd.DataFrame(info)
# print(df)
# 篩選
stime = '2015-01-01'
etime = '2018-01-01'
# 依次計算企業的CAMP擬合結果
code = list(df['股票代碼'])
name = list(df["企業名稱"])
n1 = [] # 用於存放α系數
n2 = [] # 用於存放β系數
print("對滬深300指數成分股2015年1月-2018年1月的CAMP模型計算")
for i in range(len(code)):
num = modelCAMP(code[i],name[i],stime,etime)
if len(num) == 2:
n1.append(num[0])
n2.append(num[1])
elif num[0] == 0:
# print("{}在2018年還未上市".format(name[i]))
n1.append(np.nan)
n2.append(np.nan)
else:
print("不存在風險系數")
df1 = df
df1['α'] = n1 # 添加股票α系數
df1['β'] = n2 # 添加股票β系數
new1 = df1.sort_values(by='α', ascending=False) # 按照α進行降序
new1.to_csv("stock1.csv", index=False) # 將數據存入csv文件中
new1 = new1[:100]# 設定股票池1,選取α系數前30 的股票放入股票池1
mean1 = new1['α'].mean()
# print("股票池1的α平均值{}".format(mean1))
# 預測
stime = '2018-01-01'
etime = '2021-01-01'
n3 = [] # 存放α系數
n4 = [] # 存放β系數
print("對滬深300指數成分股2018年1月-2021年1月的CAMP模型計算")
for i in range(len(code)):
num = modelCAMP(code[i],name[i], stime, etime)
if len(num) == 2:
n3.append(num[0])
n4.append(num[1])
else:
print("不存在風險系數")
df2 = df
df2['α'] = n3 # 添加股票α系數
df2['β'] = n4 # 添加股票β系數
new2 = df2.sort_values(by='α', ascending=False) # 按照α進行降序
new2.to_csv("stock2.csv", index=None)
new2 = new2[:100] # 設定股票池1,選取α系數前30 的股票放入股票池2
# 計算股票池1和股票池2的重合度
c = 0
print("股票池1和股票池2都出現的企業")
for i in new1["企業名稱"]:
if i in list(new2["企業名稱"]):
print(i)
c += 1
print("股票池1和股票池2一共有{}支股票重合,重合度為{}".format(c,c/100))
# 繪制股票池中企業所屬行業分布圖
# draw1 = pd.DataFrame({"行業": new1.groupby('主營行業')["主營行業"].count()})
# draw1.plot(kind="barh")
# plt.title("股票池1行業統計圖")
# plt.xlabel("數量")
# plt.ylabel("行業名稱")
# plt.tick_params(axis='x', labelsize=8)
# plt.tick_params(axis='y', labelsize=8)
#
# draw2 = pd.DataFrame({"行業": new2.groupby('主營行業')["主營行業"].count()})
# draw2.plot(kind="barh")
# plt.title("股票池2行業統計圖")
# plt.xlabel("數量")
# plt.ylabel("行業名稱")
# plt.tick_params(axis='x', labelsize=8)
# plt.tick_params(axis='y', labelsize=8)
# plt.show()
#
# stime = '2018-01-01'
# etime = '2021-01-01'
# n5=[]
# print("對股票池1中的股票2018年1月-2021年1月的阿爾法值進行計算")
# code = list(new1["股票代碼"])
# name = list(new1["企業名稱"])
# for i in range(len(code)):
# num = modelCAMP(code[i], name[i], stime, etime)
# if len(num) == 2:
# n5.append(num[0])
# elif num[0] == 0:
# print("{}在2018年還未上市".format(name[i]))
# else:
# print("不存在風險系數")
# df3 = new1
# df3['α'] = n5 # 添加股票α系數
# m = 0
# for i in n5:
# m += i
# mean2 = m/len(n5)
# print("股票池1在2015年-2018年的α均值{},在2018年-2021年α的均值{}".format(mean1, mean2))