見出し画像

EPS成長と株価推移の関係性を視覚化!

なぜ株に投資をするかと言えば「儲けようとする」からであり、「儲ける」とは何かというとキャピタルゲイン(株価の値上がり)とインカムゲイン(配当)に分けられる。配当を出していれば、分かりやすいのだけど、配当を出していない場合は、仮に配当を出したとしたら、どれくらい出せるのか?みたいなことを考えて収益に注目するとPEREPSを見てキャピタルゲインを狙う事になる。

ただ、PERは株価とともに変動するモノなので、株価の妥当性を考える変数としては、株価と切り離して業績で見れるEPSで見た方がシンプルになる

そして、EPSと株価の成長をみた場合、「株価が収益性をシンプルに映し出す」のであれば、「株価とEPSは1:1の正比例」になると考えられる。では、実際に、そのようになっているのか、株価とEPSの関係性を検証してみたい。

という事で、EPS成長と株価推移をグラフにして関係性を下記の様に視覚化してみる事にした。

画像25

仕様は下記のような仕様とした。

仕様
EPS、株価の成長率は前期比の積み上げとする。
(売上に季節性があると上下に変動するが、長期で見れば、妥当なラインに収束すると想定。)
・決算日(EPS発表日)の株価を取得するが、株価を1期前の決算日にシフトさせ、最新の決算に対応する株価は現在の株価とする。
(わかり難い仕様であるが、決算の内容を次の決算までに株価に織り込むと仮定して、株価を1期前の決算日にシフトさせる事とした。長期で見れば、些細な事であるし、何より、現在の株価を取り込む事で現在の価格が割安か割高かを表せるので、この仕様とした。)
・EPSと株価の成長が1:1の正比例となる目安としてX=Yの線を引く。

では、検証していこう。

0.事前準備

事前準備はこちら。5分もあればできると思います。

1.ライブラリのインストール

必要なライブラリを2つインストールする。

ライブラリのインストール1

!pip install yfinance

ライブラリのインストール2

!pip install yahoo_fin

2.コーディング

コーディングは下記の通り。

詳細はコメントに記載したので割愛。

#! pip install yfinance
#!pip install yahoo_fin
import yfinance as yf
import yahoo_fin.stock_info as si
import numpy as np
import pandas as pd
import pandas_datareader.data as web
from datetime import datetime as dt
import datetime
from matplotlib import dates
import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as stats
import time
import warnings
warnings.simplefilter('ignore')
%matplotlib inline

# データ取得期間設定
start_tmp = '2015-01-01'
end_tmp = datetime.date.today().strftime('%Y-%m-%d')

# 銘柄の指定
codelist = ['KO','JNJ','ABBV','COST','PG','MMM','MSFT',
'AMZN','FB','AAPL','GOOGL','XOM','MO','ADBE','CRM','VEEV','BABA','MCD']

# 繰り返し処理で結果を保持するデータフレーム
df_temp=pd.DataFrame(columns={'Ticker'})

for i in range(len(codelist)):
 # EPS情報の取得    
 ticker=codelist[i]
 ticker_earnings_hist = si.get_earnings_history(ticker)
 # EPS情報の整形
 df =pd.DataFrame.from_dict(ticker_earnings_hist).loc[:,['startdatetime','epsestimate','epsactual','epssurprisepct']]
 df.rename(columns={'epsestimate':'EPS_Estimate','epsactual':'EPS_Actual','epssurprisepct':'EPS_Suprise','startdatetime':'Date'},inplace=True)
 df['Date'] = pd.to_datetime(df['Date'], format='%Y-%m-%d')
 df = df.sort_index(axis='index',ascending=False)[['Date','EPS_Estimate', 'EPS_Actual','EPS_Suprise']]

 # 期間調整
 df=df[(df['Date'] >= start_tmp)]   
 df=df.set_index('Date')
 df.index = df.index.tz_convert(None)
 df=df.dropna()

 # 株価を取得する開始時期を、EPSの最初と一致させる
 start = df.index[0]
 
 # メインの株価データ取得    
 # data_stk = pd.DataFrame(web.DataReader(ticker, 'stooq', start, end)['Close'])
 df_st =  pd.DataFrame(yf.download(ticker, start=start)['Adj Close'])
 df_st.rename(columns={'Adj Close':'Stock_Price'},inplace=True)
 df=df.join(df_st)
 df["Stock_Price"]=df["Stock_Price"].shift(-1)#株価を1行ズラす
 df.iloc[-1,3]=df_st.iloc[-1,0]#今の株価を入れ
 df_all=(1+df[{'EPS_Actual','Stock_Price'}].pct_change()).cumprod()
 df_all=df_all.join(df["EPS_Suprise"])
 df_all=df_all.dropna()

 plt.rcParams.update(plt.rcParamsDefault) 

 fig, ax1 = plt.subplots(figsize=(8, 4),facecolor="white")

 # 傾き1の正比例の直線を書く
 x=np.arange(df_all["Stock_Price"].min(),df_all["Stock_Price"].max(),0.1)
 y=x
 ax1.plot(x, y,alpha=0.2,color='black')  

 # 散布図作成
 df_all.plot.scatter(x='Stock_Price', y='EPS_Actual', c='EPS_Suprise',
               cmap='jet', edgecolors='black',alpha=1,ax=ax1)

 # 散布図を線で結ぶ
 df_all.plot(x='Stock_Price', y='EPS_Actual',alpha=0.2,ax=ax1)

 # 終点を分かり易くするために、最後の線を赤にする。
 df_all.iloc[[-2,-1]].plot(x='Stock_Price', y='EPS_Actual',alpha=0.2,ax=ax1,color="red")

 # 決算時期の補足のテキストを記入
 for i in range(len(df_all)):
   ax1.annotate(df_all.index[i].strftime('%Y-%m'), (df_all['Stock_Price'][i], df_all['EPS_Actual'][i]),size=8,color="gray")
 ax1.get_legend().set_visible(False)
 ax1.set_title(ticker +" "+str(df_all.index[0].year)+" - "+ str(df_all.index[-1].year))
 plt.show()
 plt.close()
 time.sleep(3)

 # 最後のレコードをデータフレームに退避
 df_all['Ticker']=ticker
 df_temp=df_temp.append(df_all.iloc[-1])

 # すべてのレコードをデータフレームに退避
 # df_all['Ticker']=ticker
 # df_temp=df_temp.append(df_all)

 # 散布図と回帰直線を書くコード
 # sns.set(style="darkgrid",color_codes=True)
 # sns.jointplot(data=df_all,x='Stock_Price', y='EPS_Actual',kind="reg",color='r')
 # plt.show()

fig, ax1 = plt.subplots(figsize=(8, 4),facecolor="white")

# 傾き1の正比例の直線を書く
x=np.arange(df_temp["Stock_Price"].min(),df_temp["Stock_Price"].max(),0.1)
y=x
ax1.plot(x, y,alpha=0.2,color='black')  

# サマリー情報(ティッカーコードのテキストを記入)
for i in range(len(df_temp)):
 ax1.annotate(df_temp["Ticker"][i]+" "+df_temp.index[i].strftime('%Y-%m'), (df_temp['Stock_Price'][i], df_temp['EPS_Actual'][i]),size=8,color="gray")

# サマリー情報(すべての銘柄の最終レコードをプロット)
df_temp.plot.scatter(x='Stock_Price', y='EPS_Actual', c='EPS_Suprise',
               cmap='jet', edgecolors='black',alpha=1,ax=ax1)
ax1.set_title("Summary" +" "+str(df_all.index[0].year)+" - "+ str(df_all.index[-1].year))
plt.show()

# サマリー情報(すべての銘柄の最終レコードを出力)
df_temp

# ここまで

3.実行結果

実行すると下記の結果が出力される。

グラフの見方
 グラフ名:銘柄と対象期間
 縦軸:EPSの成長率
 横軸:株価の上昇率
 点の色:決算予想からの乖離(サプライズ)
 文字:決算時期
 灰色の線:X=Yの線(上部が割安、株が割高)
 青の線:過去の推移、赤の線:直近の推移

画像1

コカコーラは売上に季節性があるようで、上下に変動している。7月の決算が高くなる傾向があるようである。(通常、業績を前期比ではなく、前年同期比で見るのは、このようなシーズナリティを排除するためである。今回は前期比で見ているが長期で業績を見る分には問題ないだろう。)

画像2

画像3

AbbVieは割安な水準にあるように見える。

画像4

コストコの決算は9月(10月)にEPSが高くなる傾向がある様子。

画像5

画像6

画像7

マイクロソフトはEPSの成長よりも株価の成長が早い。

画像8

Amazonの近年を見ると、株価よりもEPSの成長の方が早く、割安に見える。

画像9

Facebookは政治的リスクが嫌気され、割安に放置されているように見える。

画像10

AppleはEPSの成長に対して、株価の成長が早い。

画像12

Googleは、EPSと株価の成長が正比例に近い。

画像13

画像14

画像15

Adobeは、綺麗に正比例になっている。

画像16

SalesForceは割安に見える。

画像17

Veeva Systemsは正比例に近い動きをしているが、最近は株価の上昇が早くなっている。

画像18

Alibabaは政府の規制・罰金の影響もあり、直近の推移(赤の線)を見ると割安水準から割高水準に遷移している。罰金の影響が一時的なモノだと考えるなら、まだ、割安水準であるが、政治的リスクが嫌気され、伸び悩んでいる。正比例の水準あたりで下値を切り上げていくFacebookような動きをするのかもしれない。

画像19

画像20

全ての銘柄の「直近の点」を抜き出すと上図のようになる。全体的には、正比例の線に近いところに位置するが、Amazonが突出して割安にみえる。

画像21

回帰直線とヒストグラムをつけると上図のようになる。
Amazonの影響で回帰直線は、割安側に振れている。

次に、直近の点だけでなく、全ての点を抜き出すと下記のようになる。

画像22

画像23

ここでも、Amazonの影響が大きく、回帰直線が割安側に振れている。
次に、Amazonを除くと下記のようになる。

画像24

画像25

Amazonを除外すると、やや割高だが、回帰直線はX=Yにだいぶ近くなる。

個別銘柄の事業状況によって、違いはありつつも、ざっくり全体的にみると、ある程度はEPSと株価に1:1に近い正比例の関係がありそうである。

注意:これらの結果は、該当の検証期間でみると、そう見えるというモノであり、開始時期を変更すると見え方が変わります。例えば、EPSが低い時期を開始時期に設定すると割安に見えたりします。従って、これらは絶対的な割安・割高をあらわしているものではなく、株価の値上がり・値下がりを保証するものではありません。

まぁ、そこそこ面白いツールができたように思います。
期間銘柄を変えながら、直近の株価の位置(赤の線)を見て、割安・割高の状態を見てみてはいかがでしょうか?

(利用上の注意:上場まもない会社や、最近黒字化した企業など、EPSの変動が激しい企業の場合、割安・割高の妥当性は低くなる思いますのでご注意ください。スリープ処理をいれていますが、相手のサーバーに負荷がかかるので、銘柄数は絞って利用してください。たまにエラーとなります。サーバの負荷が低いときにリトライしてみてください。)

何かの参考になれば幸いです。

では!

おつかれさん「缶コーヒー1杯ぐらい、ご馳走してあげよう」という太っ腹な方がいれば、投げ銭をお願いします!
課金しなくても、参考になったら「ハートボタン、フォロー、リツイート」をお願いします。
読まれる可能性があがるので、次の記事を書くやる気が出ます。

ここから先は

43字

¥ 100

この記事が気に入ったらサポートをしてみませんか?