
簡(jiǎn)書(shū)不維護(hù)了,歡迎關(guān)注我的知乎:波羅學(xué)的個(gè)人主頁(yè)
自2018年2月份開(kāi)始,由于一些可知的原因,我們的大A股已經(jīng)持續(xù)了一年的下跌,近3600點(diǎn)跌到了最低的2500左右。大家都在說(shuō)現(xiàn)在的市場(chǎng)估值已經(jīng)相當(dāng)?shù)土?。那今天我們就用?shù)據(jù)說(shuō)話,來(lái)具體看看當(dāng)前的市場(chǎng)估值情況。
注:因?yàn)檫x取數(shù)據(jù)有部分缺失,故數(shù)據(jù)選取時(shí)間統(tǒng)一為2012年1月1日~2019年2月14日(單身狗在情人節(jié)規(guī)劃這篇文章,怎苦字了得?。?。非金融出生,加入部分自己的思考,有錯(cuò)請(qǐng)指正。
什么是估值
談到股市,最常聽(tīng)到的就是諸如 "股市已經(jīng)到達(dá)3000點(diǎn)了"、"股市剛剛突破了4000點(diǎn)"之類的話。此處的多少點(diǎn)上某種意義上是代表了人們?cè)敢鉃楣墒懈冻龅膬r(jià)。
那么估值呢?簡(jiǎn)言之就是估計(jì)的某件東西的價(jià)值,該數(shù)字通常是無(wú)法準(zhǔn)確得知的。一家公司的估值,主要是由該公司當(dāng)前情況和未來(lái)的發(fā)展?jié)摿Φ榷喾矫嬉蛩貨Q定。市場(chǎng)的估值則是可以由這些大大小的公司來(lái)決定,可由其成分股通過(guò)某些算法計(jì)算而得,可參見(jiàn)指數(shù)估值計(jì)算方法。
那么如何來(lái)評(píng)價(jià)市場(chǎng)估值的高低呢?我們知道,準(zhǔn)確的估值是無(wú)法得知的,大家常會(huì)用PE和PB來(lái)衡量估值高低,PE為市盈率,即市值/盈利,PB是市凈率,即市值/凈資產(chǎn)。當(dāng)這些指標(biāo)高于某個(gè)值時(shí),我們就會(huì)認(rèn)為當(dāng)前的估值處于高位,反之則處于低位。我們可以此來(lái)簡(jiǎn)化估值的評(píng)估邏輯。
那么,下面將通過(guò)數(shù)據(jù)來(lái)分析這些指標(biāo),來(lái)評(píng)價(jià)下當(dāng)前股市。
分析工具為Python,下面首先導(dǎo)入一些必要的python包,數(shù)據(jù)來(lái)自于TusharePro:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
import tushare as ts
api = ts.pro_api(token='認(rèn)證token')
以啥分析市場(chǎng)
市場(chǎng),通常可以用某些指數(shù)來(lái)代表。指數(shù)有很多,通常都是基于不同標(biāo)準(zhǔn)編制的。
我們這里將選取同花順股票軟件上的六大指數(shù)來(lái)進(jìn)行分析,即上證綜指(000001.SH)、深圳成指(399001.SZ)、創(chuàng)業(yè)板指(399006.SZ)、滬深300(000300.SH)、上證50(000016.SH)和中證500(000905.SH)。
關(guān)于各個(gè)指數(shù)的樣本和一些選取的準(zhǔn)則,可以自行網(wǎng)上搜索。
獲取目標(biāo)數(shù)據(jù)
接下來(lái)我們開(kāi)始獲取數(shù)據(jù),并做一些相應(yīng)的處理,如對(duì)數(shù)據(jù)按交易時(shí)間升序排列以便于后續(xù)的分析。
因?yàn)樾枰@取六大指數(shù)的數(shù)據(jù),首先定義一些輔助變量:
index_codes = [
'000001.SH',
'399001.SZ',
'399006.SZ',
'000300.SH',
'000016.SH',
'000905.SH'
]
start_date = '20120101' # 開(kāi)始日期
end_date = '20190214' # 結(jié)束日期
index_dict = {} # 存儲(chǔ)指標(biāo)數(shù)據(jù)
為了批量獲取數(shù)據(jù),定義一個(gè)單指數(shù)數(shù)據(jù)獲取與處理的函數(shù),返回值為pd.DataFrame類型,pandas為我們提供了很多常用的數(shù)據(jù)分析方法。
def get_index_valudation_indicator_df(code, start_date, end_date):
fields = 'trade_date,pe,pb'
data = api.index_dailybasic(
ts_code=code,
start_date=start_date,
end_date=end_date,
fields=fields
)
data = data.drop_duplicates()
data.index = pd.to_datetime(data['trade_date'])
data = data.sort_index()
return data
到這里,我們開(kāi)始正式下載數(shù)據(jù)。一個(gè)for循環(huán)獲取就把所有數(shù)據(jù)加載到index_dict中,多么簡(jiǎn)潔快速。代碼如下:
for index_code in index_codes:
index_dict[index_code] = get_index_valudation_indicator_df(index_code, start_date, end_date)
先檢查下各指數(shù)數(shù)據(jù)行數(shù),確保成功獲取數(shù)據(jù):
for k, index_df in index_dict.items():
print(k, len(index_df))
輸出如下:
000001.SH 1728
399001.SZ 1728
399006.SZ 1728
000300.SH 1728
000016.SH 1728
000905.SH 1728
都為1728行,一切正常!來(lái)簡(jiǎn)單觀察一下數(shù)據(jù),以上證綜指為例打印出結(jié)尾5行數(shù)據(jù):
index_dict['000001.SH'].tail(5)
輸出如下:
trade_date pe pb
trade_date
2019-02-01 20190201 12.61 1.30
2019-02-11 20190211 12.77 1.32
2019-02-12 20190212 12.83 1.32
2019-02-13 20190213 13.08 1.35
2019-02-14 20190214 13.07 1.34
pandas為我們提供了一個(gè)info方法可以查看數(shù)據(jù)的整體情況。如下:
index_dict['000001.SH'].info()
輸出如下:
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 1728 entries, 2012-01-04 to 2019-02-14
Data columns (total 3 columns):
trade_date 1728 non-null object
pe 1728 non-null float64
pb 1728 non-null float64
dtypes: float64(2), object(1)
memory usage: 54.0+ KB
可以看出我們的數(shù)據(jù)時(shí)間跨度為2012年01月04日至2019年02月14日,共1728條記錄。不是從2012年1月1日開(kāi)始當(dāng)然是因?yàn)?月1日至1月3日是元旦假期。
注:最初數(shù)據(jù)獲取時(shí),選擇了2010年1月1日~2019年2月14日,但數(shù)據(jù)檢查時(shí)發(fā)現(xiàn)部分指數(shù)缺失,故退而求其次縮短了時(shí)間段。
開(kāi)始正式分析
進(jìn)入正題,我們?cè)撊绾芜M(jìn)行分析?先來(lái)談一些個(gè)人對(duì)估值的看法。
我們經(jīng)常會(huì)聽(tīng)到這樣的說(shuō)法,美股PE和PB為某個(gè)范圍內(nèi)時(shí)則表明當(dāng)前的估值是合理的,若高于或低于該值就被認(rèn)為是貴或便宜了。中國(guó)也是如此,不過(guò)A股通常會(huì)比美股的合理值高出一不少,這是否表明泡沫的存在?個(gè)人看法,中國(guó)經(jīng)濟(jì)長(zhǎng)期處在高速發(fā)展階段,所存環(huán)境不同與美股截然不同,對(duì)未來(lái)的預(yù)期高一點(diǎn)自然是可以理解的。簡(jiǎn)單的思考后,我總結(jié)出了如下幾個(gè)觀點(diǎn):
- 合理的估值會(huì)隨著大環(huán)境變化而變化;
- 合理的估值隨著不同市場(chǎng)行業(yè)的預(yù)期不同而不同;
- 合理的估值在一定時(shí)間周期與大環(huán)境下是相對(duì)確定的;
基于以上這些看法,下面開(kāi)始具體的分析。
A股當(dāng)前的合理估值是多少
雖然從長(zhǎng)期來(lái)看,合理的估值在不斷變化,但短期內(nèi)是有一個(gè)值可供我們參考的。那么我們?nèi)绾潍@取到這個(gè)值呢?能想到的辦法就是從歷史數(shù)據(jù)中分析而來(lái),可計(jì)算的幾個(gè)指標(biāo)有:平均數(shù)、頻率分布最高區(qū)間(類似眾數(shù))、中位數(shù)。這里選取的是7年的數(shù)據(jù),當(dāng)然沒(méi)有什么理由,在保證數(shù)據(jù)準(zhǔn)確完備的前提下選的時(shí)間線盡量長(zhǎng)點(diǎn)。下面開(kāi)始來(lái)計(jì)算這些指標(biāo)。
先定義一個(gè)函數(shù)計(jì)算歷史估值的分布情況并返回最高分布區(qū)間,并計(jì)算出這個(gè)區(qū)間的平均數(shù)。
def get_interval_freq_max(data):
c = pd.cut(data, bins=10).value_counts() # 計(jì)算各區(qū)間分布數(shù)量,假設(shè)為10
p = c / c.sum() # 計(jì)算各區(qū)間分布頻率
m = p.max() # 計(jì)算最大值
for k, v in p.items(): # 找出最大值的key,即所在區(qū)間
if m == v:
max_interval = k
return data[(data >= max_interval.left) & (data <= max_interval.right)].mean()
計(jì)算指標(biāo)并輸出,最后轉(zhuǎn)化為pd.DataFrame類型以便于作圖,下面為代碼實(shí)現(xiàn):
index_current_indicator_dict = {}
for k, index in index_dict.items():
index_current_indicator_dict[k] = {
'pb': index['pb'][-1],
'pb_mean': index['pb'].mean(),
'pb_high_feq': get_interval_freq_max(index['pb']),
'pb_median': index['pb'].median(),
'pe': index['pe'][-1],
'pe_mean': index['pe'].mean(),
'pe_high_feq': get_interval_freq_max(index['pe']),
'pe_median': index['pe'].median()
}
indicator_df = pd.DataFrame(index_current_indicator_dict)
print(indicator_df)
000001.SH 399001.SZ 399006.SZ 000300.SH 000016.SH 000905.SH
pb 1.340000 2.250000 3.840000 1.380000 1.170000 1.680000
pb_high_feq 1.601113 3.118865 5.752357 1.494908 1.205844 2.235625
pb_mean 1.605637 2.710625 5.342436 1.552286 1.343003 2.629954
pb_median 1.590000 2.640000 4.990000 1.500000 1.270000 2.480000
pe 13.070000 20.130000 34.870000 12.300000 10.230000 19.360000
pe_high_feq 11.022995 15.323544 35.389715 11.991063 10.478383 27.131933
pe_mean 13.755469 24.546250 55.418264 12.171325 10.062737 36.700735
pe_median 13.550000 21.475000 54.820000 11.970000 9.970000 34.140000
從輸出的數(shù)據(jù)分析不夠直觀,下面我們來(lái)嘗試通過(guò)圖形方式展現(xiàn),先來(lái)看PB:
columns = ['pb', 'pb_mean', 'pb_high_feq', 'pb_median']
indicator_df.loc[columns].T.plot(kind='bar', figsize=(15, 5))
輸出如下:

讀圖可以得到如下的結(jié)論:
- 無(wú)論使用哪個(gè)指標(biāo)作為合理估值,選取的6大指數(shù)PB(即藍(lán)色柱)當(dāng)前都處在低位;
- 創(chuàng)業(yè)板的PB最高,這或許與大家對(duì)創(chuàng)業(yè)板公司的成長(zhǎng)有較高預(yù)期有關(guān);
- 無(wú)論使用哪個(gè)指標(biāo)作為合理估值,中證500當(dāng)前PB與它們都有較大的差距;
再來(lái)看PE:
columns = ['pe', 'pe_mean', 'pe_high_feq', 'pe_median']
indicator_df.loc[columns].T.plot(kind='bar', figsize=(15, 5))

讀上圖會(huì)發(fā)現(xiàn)一些與PB指標(biāo)相同的結(jié)論,比如創(chuàng)業(yè)板估值依然是最高,中證500當(dāng)前被嚴(yán)重低估等。那么有哪些不同呢?一個(gè)最易得出的結(jié)論就是多數(shù)指數(shù)當(dāng)前的市盈率在其他各指標(biāo)中并非最低。不知道這是不是近期企業(yè)盈利下降有關(guān)。
總體而言,如果鐘愛(ài)于指數(shù)投資、堅(jiān)信價(jià)值回歸,當(dāng)前或許較適合增加中證500配置比重。
當(dāng)前估值處在歷史什么位置
以上的分析主要從總體角度觀察。下面我們將從時(shí)間序列上觀察估值的歷史變化,而最好的方式從分位的角度來(lái)看問(wèn)題。
我們先來(lái)計(jì)算各指數(shù)的估值處在近7年的什么分位,計(jì)算代碼如下:
index_current_quantile_dict = {}
for k, index in index_dict.items():
index_current_quantile_dict[k] = {
'pb_percentile': stats.percentileofscore(index['pb'], index['pb'][-1]),
'pe_percentile':stats.percentileofscore(index['pe'], index['pe'][-1])
}
pd.DataFrame(index_current_quantile_dict)
輸出如下:
000001.SH 399001.SZ 399006.SZ 000300.SH 000016.SH 000905.SH
pb_percentile 13.425926 33.767361 25.954861 23.350694 19.994213 4.687500
pe_percentile 45.949074 47.366898 10.358796 55.555556 57.725694 3.009259
從這張表可以得出哪些結(jié)論?所有指數(shù)的市凈率都處在1/2分位以下,而對(duì)于市盈率,除了中證500和創(chuàng)業(yè)板指,都位于1/2分位附近。創(chuàng)業(yè)板指和中證500低估較為明顯,特別是中證500,無(wú)論從凈資產(chǎn)還是盈利角度來(lái)看都有很大的投資價(jià)值。
上面是計(jì)算最近的情況,我們也可以通過(guò)繪制歷史的變化圖,來(lái)看看不同時(shí)期估值指標(biāo)的表現(xiàn)情況。同時(shí)可以添加相應(yīng)的分位輔助線(包括1/4、1/2、3/4分位)來(lái)更好的對(duì)比。
以上證指數(shù)為例:
data_pe = index_dict['000001.SH'][['pe']].copy()
data_pb = index_dict['000001.SH'][['pb']].copy()
data_pe['pe_Q1'] = data_pe['pe'].quantile(0.25)
data_pe['pe_Q2'] = data_pe['pe'].quantile(0.5)
data_pe['pe_Q3'] = data_pe['pe'].quantile(0.75)
data_pb['pb_Q1'] = data_pb['pb'].quantile(0.25)
data_pb['pb_Q2'] = data_pb['pb'].quantile(0.5)
data_pb['pb_Q3'] = data_pb['pb'].quantile(0.75)
準(zhǔn)備好數(shù)據(jù),直接作出兩指標(biāo)的時(shí)間序列變化圖:
fig = plt.figure()
ax_pe, ax_pb = fig.subplots(2, 1)
ax_pe.set_title('pe timeseries')
ax_pb.set_title('pb timeseries')
data_pe[['pe_Q1', 'pe_Q2', 'pe_Q3', 'pe']].plot(figsize=(12, 15), ax=ax_pe)
data_pb[['pb_Q1', 'pb_Q2', 'pb_Q3', 'pb']].plot(figsize=(12, 15), ax=ax_pb)
plt.show()
繪圖結(jié)果:

可以看出,在2012年至2014年期間估值長(zhǎng)期處于低位,足足有兩年之久。所以說(shuō),雖然當(dāng)前資產(chǎn)較為便宜,但并不代表就來(lái)一定會(huì)上漲。不過(guò)或許是蓄力越久,爆發(fā)就有力。眾所周知,2014年下半年至2015年上半年的那一波瘋牛市。