在價值投資中,股票目前的估值狀況在歷史上處于什么地位對于投資決策有著非常重要的參考價值。
本文利用Python來獲取某只股票的估值在歷史中處于何種位置。
(如需注冊可以考慮拉兄弟一把:https://tushare.pro/register?reg=124585 )
在本文中使用了以下庫:
* numpy* pandas* matplotlib* seaborn 非必要* tushare 獲取金融數(shù)據(jù)的接口
其它庫大家應(yīng)該都比較熟悉,而Tushare(pro版本)的詳細信息請見 https://tushare.pro/
閑話不多,直接擼代碼
#各種Importimport tushare as tsimport pandas as pdimport matplotlib.pyplot as pltimport matplotlib as mplimport seaborn as sbimport numpy as npsb.set_style("whitegrid") #繪圖樣式mpl.rcParams['font.sans-serif'] = ['SimHei'] # 指定默認字體mpl.rcParams['axes.unicode_minus'] = False # 解決保存圖像是負號'-'顯示為方塊的問題ts.set_token('08a1f9ec134442837328a82f2f5235394d84c') #請注冊使用自己的TS key,這個key沒用pro = ts.pro_api()stock_code = '000002.SZ' #需要查閱的股票代碼,前邊是代碼,后邊是市場,詳見Tushare說明def get_data(x): #取得股票數(shù)據(jù)的函數(shù),包括股票價格,復權(quán)信息,基本的基本面信息 df_day = pro.daily(ts_code=x) #取日線行情,最新限制,只能取4000條,需要再多,用循環(huán)按日期取多次 df_adj_factor = pro.adj_factor(ts_code=x) #取復權(quán)因子 df_basic = pro.daily_basic(ts_code=x) #取基本面信息 del df_basic['close'] #去掉冗余信息 #合并數(shù)據(jù)并返回 df = df_day.merge(right=df_adj_factor,how='left',on=['ts_code','trade_date']) df = df.merge(right=df_basic,how='left',on=['ts_code','trade_date']) return dfdef get_name(x): #返回股票名字 df = pro.namechange(ts_code=x, fields='name') return df.iloc[0,0]def str_to_date(str): #轉(zhuǎn)換YYYYMMDD到Y(jié)YYY-MM-DD if len(str)==8: return str[0:4]+'-'+str[4:6]+'-'+str[6:8] #老人家表示知道format但就愛那么干 else: return str title = stock_code + ' - ' + get_name(stock_code) #顯示標題df = get_data(stock_code) #取得數(shù)據(jù)df['trade_date']=df['trade_date'].apply(str_to_date) #轉(zhuǎn)換trade_date到日期類型,并設(shè)置為索引df['trade_date'] = pd.to_datetime(df['trade_date'])df.set_index('trade_date',inplace=True)#按季度做重采樣,并計算收盤價以及基本面信息period_type = 'Q' #Q季度,也可以用M月df_quote = df.resample(period_type).last()df_quote['close'] = df['close'].resample(period_type).last()df_quote['PE'] = df['pe'].resample(period_type).last()df_quote['PB'] = df['pb'].resample(period_type).last()df_quote['PS'] = df['ps'].resample(period_type).last()df_quote['adj_factor'] = df['adj_factor'].resample(period_type).last()df_quote = df_quote[df_quote['ts_code'].notnull()]df_quote['Price'] = df_quote['close']*df_quote['adj_factor'] #計算復權(quán)價df_quote.reset_index(inplace=True) #重置索引df = df_quote.loc[:,['trade_date','PE','PB','PS','Price']] #取需要的列df.plot(kind='line',x='trade_date', figsize=(15,13),title=title, fontsize=20, subplots=True, logy=False)plt.show()
先看一下最近幾個季度的情況,由于是季線,最后的日期和當前日期有出入,本文寫在2018年10月初
df.tail()
trade_date | PE | PB | PS | Price | |
---|---|---|---|---|---|
62 | 2017-12-31 | 16.3099 | 2.9463 | 1.4258 | 4264.53800 |
63 | 2018-03-31 | 13.1005 | 2.7699 | 1.5130 | 4570.71700 |
64 | 2018-06-30 | 9.6808 | 1.9941 | 1.1180 | 3377.58000 |
65 | 2018-09-30 | 9.5627 | 1.9886 | 1.1044 | 3466.83240 |
66 | 2018-12-31 | 8.5868 | 1.7857 | 0.9917 | 3113.01576 |
再看一下目前估值處于歷史什么位置。
可以看出,目前市盈率,市凈率,市銷率都在25%以下,確實估值較低。
df.describe()
PE | PB | PS | Price | |
---|---|---|---|---|
count | 67.000000 | 67.000000 | 67.00000 | 67.000000 |
mean | 19.105633 | 2.626366 | 2.14339 | 1317.099314 |
std | 15.265163 | 1.451415 | 1.97986 | 1160.259605 |
min | 5.894200 | 1.158900 | 0.65800 | 90.256450 |
25% | 10.497050 | 1.838950 | 1.18255 | 316.619235 |
50% | 14.883800 | 2.204200 | 1.61960 | 972.723840 |
75% | 20.841950 | 2.785050 | 2.03310 | 1733.848000 |
max | 90.315500 | 8.354600 | 11.58220 | 4570.717000 |
我們再看一下,目前的估值(以市盈率PE為例),和歷史上哪些時刻相當?
可以看出,目前估值和2013-2014的熊市底部區(qū)域相當
df = df.sort_values('PE')df.head(20)
trade_date | PE | PB | PS | Price | |
---|---|---|---|---|---|
47 | 2014-03-31 | 5.8942 | 1.1589 | 0.6580 | 945.50257 |
48 | 2014-06-30 | 6.0253 | 1.3197 | 0.6727 | 1019.65792 |
49 | 2014-09-30 | 6.6883 | 1.3151 | 0.7467 | 1131.85728 |
46 | 2013-12-31 | 7.0464 | 1.2955 | 0.8577 | 938.49019 |
45 | 2013-09-30 | 8.0116 | 1.5088 | 0.9752 | 1067.05049 |
66 | 2018-12-31 | 8.5868 | 1.7857 | 0.9917 | 3113.01576 |
44 | 2013-06-30 | 8.6386 | 1.7047 | 1.0515 | 1151.19905 |
53 | 2015-09-30 | 8.9329 | 1.6115 | 0.9608 | 1622.40031 |
43 | 2013-03-31 | 9.4264 | 1.8537 | 1.1474 | 1237.53988 |
39 | 2012-03-31 | 9.4589 | 1.7188 | 1.2683 | 938.72016 |
65 | 2018-09-30 | 9.5627 | 1.9886 | 1.1044 | 3466.83240 |
41 | 2012-09-30 | 9.6302 | 1.6822 | 1.2913 | 969.55959 |
64 | 2018-06-30 | 9.6808 | 1.9941 | 1.1180 | 3377.58000 |
51 | 2015-03-31 | 9.6949 | 1.7301 | 1.0428 | 1703.95072 |
50 | 2014-12-31 | 10.1272 | 1.9497 | 1.1306 | 1713.81440 |
40 | 2012-06-30 | 10.1786 | 1.8023 | 1.3648 | 1010.14452 |
52 | 2015-06-30 | 10.1874 | 1.8045 | 1.0958 | 1790.25792 |
59 | 2017-03-31 | 10.8067 | 2.0026 | 0.9447 | 2732.65356 |
37 | 2011-09-30 | 10.9301 | 1.7229 | 1.5697 | 820.81328 |
38 | 2011-12-31 | 11.2773 | 1.7514 | 1.6196 | 846.88884 |