Pythonでの株価の分析

Pythonをもうちょっと学ぶためにPythonでいろいろとやってみました。今回も携帯関連会社の株価で実施してみました。

データの取り込み

まずはいつもどおり、必要なライブラリーの取り込みを行います。

In [1]:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

データの取得

先の記事で格納済みのデータを取り込みます。まずはNTT (証券コード: 9432)から

In [2]:
ntt = pd.read_csv('NTT_Stock.csv',index_col = 'Date',parse_dates=True)
In [3]:
ntt
Out[3]:
High Low Open Close Volume Adj Close
Date
2000-01-04 4550.0 4450.0 4475.0 4475.0 184000000.0 2654.374756
2000-01-05 4350.0 4200.0 4300.0 4300.0 249000000.0 2550.572266
2000-01-06 4300.0 4150.0 4250.0 4175.0 175000000.0 2476.427246
2000-01-07 4150.0 4075.0 4075.0 4125.0 222000000.0 2446.769287
2000-01-10 4125.0 4125.0 4125.0 4125.0 0.0 2446.769287
2021-11-15 3309.0 3284.0 3292.0 3293.0 4842400.0 3293.000000
2021-11-16 3313.0 3283.0 3300.0 3286.0 4364400.0 3286.000000
2021-11-17 3283.0 3236.0 3278.0 3242.0 4517000.0 3242.000000
2021-11-18 3231.0 3198.0 3230.0 3215.0 5222500.0 3215.000000
2021-11-19 3200.0 3172.0 3195.0 3184.0 5809100.0 3184.000000

5482 rows × 6 columns

その他の携帯関連会社のデータ取り込み

同じように格納済みデータを取り込みます。

In [4]:
kddi = pd.read_csv('KDDI_Stock.csv',index_col = 'Date',parse_dates=True)
softbank = pd.read_csv('Softbank_Stock.csv',index_col = 'Date',parse_dates=True)
rakuten = pd.read_csv('Rakuten_Stock.csv',index_col = 'Date',parse_dates=True)
In [5]:
kddi
Out[5]:
High Low Open Close Volume Adj Close
Date
2000-01-04 2516.666748 2383.333252 2400.000000 2400.000000 4926600.0 1544.448242
2000-01-05 2416.666748 2283.333252 2316.666748 2366.666748 3225600.0 1522.998047
2000-01-06 2433.333252 2300.000000 2400.000000 2333.333252 4278000.0 1501.547607
2000-01-07 2266.666748 2183.333252 2266.666748 2200.000000 6285600.0 1415.744141
2000-01-10 2200.000000 2200.000000 2200.000000 2200.000000 0.0 1415.744141
2021-11-15 3462.000000 3434.000000 3450.000000 3446.000000 3296700.0 3446.000000
2021-11-16 3475.000000 3452.000000 3467.000000 3460.000000 2834600.0 3460.000000
2021-11-17 3447.000000 3405.000000 3431.000000 3409.000000 4016400.0 3409.000000
2021-11-18 3441.000000 3385.000000 3409.000000 3418.000000 3634800.0 3418.000000
2021-11-19 3446.000000 3401.000000 3446.000000 3410.000000 3338400.0 3410.000000

5482 rows × 6 columns

In [6]:
softbank
Out[6]:
High Low Open Close Volume Adj Close
Date
2000-01-04 5722.166504 5722.166504 5722.166504 5722.166504 9909000.0 5162.070801
2000-01-05 5311.166504 4250.000000 5250.000000 4811.166504 84618000.0 4340.241699
2000-01-06 4905.500000 4533.333496 4783.333496 4533.333496 28085400.0 4089.603760
2000-01-07 4444.500000 4255.500000 4255.500000 4255.500000 58633200.0 3838.963379
2000-01-10 4255.500000 4255.500000 4255.500000 4255.500000 0.0 3838.963379
2021-11-15 7029.000000 6896.000000 6990.000000 7000.000000 20705200.0 7000.000000
2021-11-16 7148.000000 6913.000000 6960.000000 7113.000000 18940200.0 7113.000000
2021-11-17 7217.000000 7113.000000 7170.000000 7132.000000 15818400.0 7132.000000
2021-11-18 7085.000000 6871.000000 7060.000000 6986.000000 17488400.0 6986.000000
2021-11-19 6935.000000 6805.000000 6826.000000 6856.000000 16608900.0 6856.000000

5482 rows × 6 columns

In [7]:
rakuten
Out[7]:
High Low Open Close Volume Adj Close
Date
2000-04-19 644.0 360.0 398.0 600.0 4000000.0 573.620056
2000-04-20 808.0 606.0 610.0 800.0 3000000.0 764.826965
2000-04-21 980.0 790.0 792.0 860.0 2000000.0 822.188904
2000-04-24 910.0 790.0 870.0 790.0 1000000.0 755.266541
2000-04-25 866.0 700.0 790.0 850.0 1000000.0 812.628479
2021-11-15 1199.0 1155.0 1156.0 1193.0 7800500.0 1193.000000
2021-11-16 1209.0 1181.0 1194.0 1194.0 4164100.0 1194.000000
2021-11-17 1217.0 1182.0 1194.0 1205.0 5079500.0 1205.000000
2021-11-18 1262.0 1216.0 1219.0 1251.0 10023500.0 1251.000000
2021-11-19 1269.0 1228.0 1260.0 1247.0 7172400.0 1247.000000

5365 rows × 6 columns

株価データの表示

終値でそれぞれの株価を同じグラフに表示します。

In [8]:
ntt['Close'].plot(label='NTT',figsize=(16,8),title='Close Price')
kddi['Close'].plot(label='KDDI')
softbank['Close'].plot(label='Softbank')
rakuten['Close'].plot(label='Rakuten')
plt.legend()
Out[8]:
<matplotlib.legend.Legend at 0x7ff157cce550>

2020年以降のそれぞれの取引高を一つのグラフ上に表示します。

In [9]:
ntt.loc['2020-01-01':]['Volume'].plot(label='NTT',figsize=(16,8),title='Volume')
kddi.loc['2020-01-01':]['Volume'].plot(label='KDDI')
softbank.loc['2020-01-01':]['Volume'].plot(label='Softbank')
rakuten.loc['2020-01-01':]['Volume'].plot(label='Rakuten')
plt.legend()
Out[9]:
<matplotlib.legend.Legend at 0x7ff15e2f5f10>

2021年3月の終わりに楽天の取引高が非常に大きくなっていることがわかります。何が起こっているのかを調べるために、最大の取引高が発生している日時を調べます。

In [10]:
rakuten['Volume'].idxmax()
Out[10]:
Timestamp('2021-03-15 00:00:00')

この時に何があったのか調べてみると、日本郵政と楽天の資本提携が3月12日(金)に発表されており、それに伴って、週明けの3月15日(月)に取引が膨らんだようです。

https://corp.rakuten.co.jp/news/press/2021/0312_02.html

次は、取引高と株価をかけて、実際にそれぞれの株で売買された金額を見える化してみます。終値と取引高をかけます。

In [11]:
ntt['Total Ammount'] = ntt['Close']*ntt['Volume']
kddi['Total Ammount'] = kddi['Close']*kddi['Volume']
softbank['Total Ammount'] = softbank['Close']*softbank['Volume']
rakuten['Total Ammount'] = rakuten['Close']*rakuten['Volume']
In [12]:
ntt.loc['2020-01-01':]['Total Ammount'].plot(label='NTT',figsize=(16,8))
kddi.loc['2020-01-01':]['Total Ammount'].plot(label='KDDI')
softbank.loc['2020-01-01':]['Total Ammount'].plot(label='Softbank')
rakuten.loc['2020-01-01':]['Total Ammount'].plot(label='Rakuten')
plt.legend()
plt.ylabel('Total Ammount')
Out[12]:
Text(0, 0.5, 'Total Ammount')

ソフトバンクの株価で2020年12月の取引額がやたら大きい所があることがわかります。楽天の時と同様に調べてみると以下のようになります。

In [13]:
softbank.loc['2020-01-01':]['Total Ammount'].idxmax()
Out[13]:
Timestamp('2020-12-10 00:00:00')

2020年12月9日に出資先のドアダッシュの上場があり、それに伴って取引が拡大したようです。

https://www.bloomberg.co.jp/news/articles/2020-12-10/QL3M03T0G1L701

移動平均線の描画

ソフトバンクの始値の50日と200日の移動平均線を書いてみます。

In [14]:
softbank['MA50'] = softbank['Open'].rolling(50).mean()
softbank['MA200'] = softbank['Open'].rolling(200).mean()
softbank[['Open','MA50','MA200']].plot(label='Softbank',figsize=(16,8))
Out[14]:
<AxesSubplot:xlabel='Date'>

株価の関係ー散布図

次にそれぞれの株価の関係を見てみます。散布図で表示して見ます。

In [15]:
from pandas.plotting import scatter_matrix
In [16]:
mobile_stock = pd.concat([ntt['Close'],kddi['Close'],softbank['Close'],rakuten['Close']],axis=1)
In [17]:
mobile_stock.columns = ['NTT','KDDI','Softbank','Rakuten']
In [18]:
scatter_matrix(mobile_stock,figsize=(11,11),alpha=0.2,hist_kwds={'bins':50});

ローソク足の描画

2021年10月のソフトバンクのローソク足を描画してみます。

In [19]:
import mplfinance as mpf
mpf.plot(softbank.loc['2021-10':'2021-10'], type='candle', figratio=(12,4))

株価分析

毎日の変化量など株価の分析をしてみます。

日次の株価変化量

日次の株価変化量を計算してみます。公式は以下のとおりです。

r_tは日次の株価変化量
p_tはある日の株価
p_t-1はある日の前日の株価

日次の株価変化量は前日に買った株を翌日に買った場合に得られる(損益率)を算出しています。これは、株式の将来の価値を予測するのには役に立ちませんが、株式のボラティリティを分析するのに非常に役立ちます。毎日のリターンの分布が広い株の株価は日ごとに変動しやすくなります。日次の株価変化量を計算し、ヒストグラムでプロットして、どの株が最も安定しているかを確認してみます。

まずはNTTの株価変化量の計算

pct_changeはデータの前後の変化率を計算します。引数は変化率を求める前後の日数です。今回は日次の変化量なので1です。

In [20]:
ntt['returns'] = ntt['Close'].pct_change(1)
In [21]:
ntt.head()
Out[21]:
High Low Open Close Volume Adj Close Total Ammount returns
Date
2000-01-04 4550.0 4450.0 4475.0 4475.0 184000000.0 2654.374756 8.234000e+11 NaN
2000-01-05 4350.0 4200.0 4300.0 4300.0 249000000.0 2550.572266 1.070700e+12 -0.039106
2000-01-06 4300.0 4150.0 4250.0 4175.0 175000000.0 2476.427246 7.306250e+11 -0.029070
2000-01-07 4150.0 4075.0 4075.0 4125.0 222000000.0 2446.769287 9.157500e+11 -0.011976
2000-01-10 4125.0 4125.0 4125.0 4125.0 0.0 2446.769287 0.000000e+00 0.000000

NTT以外の日次変化量も計算します。

In [22]:
kddi['returns'] = kddi['Close'].pct_change(1)
softbank['returns'] = softbank['Close'].pct_change(1)
rakuten['returns'] = rakuten['Close'].pct_change(1)
In [23]:
kddi.head()
Out[23]:
High Low Open Close Volume Adj Close Total Ammount returns
Date
2000-01-04 2516.666748 2383.333252 2400.000000 2400.000000 4926600.0 1544.448242 1.182384e+10 NaN
2000-01-05 2416.666748 2283.333252 2316.666748 2366.666748 3225600.0 1522.998047 7.633920e+09 -0.013889
2000-01-06 2433.333252 2300.000000 2400.000000 2333.333252 4278000.0 1501.547607 9.982000e+09 -0.014085
2000-01-07 2266.666748 2183.333252 2266.666748 2200.000000 6285600.0 1415.744141 1.382832e+10 -0.057143
2000-01-10 2200.000000 2200.000000 2200.000000 2200.000000 0.0 1415.744141 0.000000e+00 0.000000
In [24]:
softbank.head()
Out[24]:
High Low Open Close Volume Adj Close Total Ammount MA50 MA200 returns
Date
2000-01-04 5722.166504 5722.166504 5722.166504 5722.166504 9909000.0 5162.070801 5.670095e+10 NaN NaN NaN
2000-01-05 5311.166504 4250.000000 5250.000000 4811.166504 84618000.0 4340.241699 4.071113e+11 NaN NaN -0.159205
2000-01-06 4905.500000 4533.333496 4783.333496 4533.333496 28085400.0 4089.603760 1.273205e+11 NaN NaN -0.057748
2000-01-07 4444.500000 4255.500000 4255.500000 4255.500000 58633200.0 3838.963379 2.495136e+11 NaN NaN -0.061287
2000-01-10 4255.500000 4255.500000 4255.500000 4255.500000 0.0 3838.963379 0.000000e+00 NaN NaN 0.000000
In [25]:
rakuten.head()
Out[25]:
High Low Open Close Volume Adj Close Total Ammount returns
Date
2000-04-19 644.0 360.0 398.0 600.0 4000000.0 573.620056 2.400000e+09 NaN
2000-04-20 808.0 606.0 610.0 800.0 3000000.0 764.826965 2.400000e+09 0.333333
2000-04-21 980.0 790.0 792.0 860.0 2000000.0 822.188904 1.720000e+09 0.075000
2000-04-24 910.0 790.0 870.0 790.0 1000000.0 755.266541 7.900000e+08 -0.081395
2000-04-25 866.0 700.0 790.0 850.0 1000000.0 812.628479 8.500000e+08 0.075949
In [26]:
import seaborn as sns
sns.set()

それぞれの株のヒストグラムを表示してみます。

0を中心に正規分布していることがわかります。

In [27]:
ntt['returns'].hist(bins=50)
Out[27]:
<AxesSubplot:>
In [28]:
kddi['returns'].hist(bins=50)
Out[28]:
<AxesSubplot:>
In [29]:
softbank['returns'].hist(bins=50)
Out[29]:
<AxesSubplot:>
In [30]:
rakuten['returns'].hist(bins=50)
Out[30]:
<AxesSubplot:>

すべてのヒストグラムを重ねてみます。

In [31]:
ntt['returns'].hist(bins=100,label='NTT',figsize=(10,8),alpha=0.5)
kddi['returns'].hist(bins=100,label='KDDI',alpha=0.5)
softbank['returns'].hist(bins=100,label='Softbank',alpha=0.5)
rakuten['returns'].hist(bins=100,label='Rakuten',alpha=0.5)
plt.legend()
Out[31]:
<matplotlib.legend.Legend at 0x7ff15cb5ef10>

正直、よくわからないので、KDEで表示してみます。ソフトバンクと楽天が重なってわかりにくいので、楽天を赤点線で表示してます。

In [32]:
ntt['returns'].plot(kind='kde',label='NTT',figsize=(12,6))
kddi['returns'].plot(kind='kde',label='KDDI')
softbank['returns'].plot(kind='kde',label='Softbank')
rakuten['returns'].plot(kind='kde',label='Rakuten',ls='--')
plt.legend()
Out[32]:
<matplotlib.legend.Legend at 0x7ff15d1392e0>

こうやって見てみると、楽天とソフトバンクはほとんど変わらないように見えることがわかります。

さらにボックスプロットで表示してみます。

In [33]:
box_df = pd.concat([ntt['returns'],kddi['returns'],softbank['returns'],rakuten['returns']],axis=1)
box_df.columns = ['NTT','KDDI','Softbank','Rakuten']
box_df.plot(kind='box',figsize=(8,11),colormap='jet')
Out[33]:
<AxesSubplot:>

イメージ通りではあるのですが、ソフトバンクと楽天のボラタリティが大きいことがわかります。

株価間の株価変化量の関係の確認

株価の時と同じように変化量の関係を散布図で表示してみます。

In [34]:
scatter_matrix(box_df,figsize=(8,8),alpha=0.2,hist_kwds={'bins':50});

なんとなくNTTとKDDIは関係がありそうです。という事で、NTTとKDDIで表示

In [35]:
box_df.plot(kind='scatter',x='NTT',y='KDDI',alpha=0.4,figsize=(10,8))
*c* argument looks like a single numeric RGB or RGBA sequence, which should be avoided as value-mapping will have precedence in case its length matches with *x* & *y*.  Please use the *color* keyword-argument or provide a 2D array with a single row if you intend to specify the same RGB or RGBA value for all points.
Out[35]:
<AxesSubplot:xlabel='NTT', ylabel='KDDI'>

累積日次変化量

次は該当の株に2000年1月1日(楽天は2000年4月に上京しているので、上場時)に1円投資したら、現在の株価がどうなっているかを調べてみます。

累積日次変化量の数式は以下の通り:

NTTの累積日次変化量を計算します。

累積日次変化量を計算するには累積積を求める必要があるのでcumprod関数を利用します。

In [36]:
ntt['Cumulative Return'] = (1 + ntt['returns']).cumprod()
In [37]:
ntt.head()
Out[37]:
High Low Open Close Volume Adj Close Total Ammount returns Cumulative Return
Date
2000-01-04 4550.0 4450.0 4475.0 4475.0 184000000.0 2654.374756 8.234000e+11 NaN NaN
2000-01-05 4350.0 4200.0 4300.0 4300.0 249000000.0 2550.572266 1.070700e+12 -0.039106 0.960894
2000-01-06 4300.0 4150.0 4250.0 4175.0 175000000.0 2476.427246 7.306250e+11 -0.029070 0.932961
2000-01-07 4150.0 4075.0 4075.0 4125.0 222000000.0 2446.769287 9.157500e+11 -0.011976 0.921788
2000-01-10 4125.0 4125.0 4125.0 4125.0 0.0 2446.769287 0.000000e+00 0.000000 0.921788

同様に他の株式も計算します。

In [38]:
kddi['Cumulative Return'] = (1 + kddi['returns']).cumprod()
softbank['Cumulative Return'] = (1 + softbank['returns']).cumprod()
rakuten['Cumulative Return'] = (1 + rakuten['returns']).cumprod()
In [39]:
ntt['Cumulative Return'].plot(label='NTT',figsize=(16,8),title='Cumulative Return')
kddi['Cumulative Return'].plot(label='KDDI')
softbank['Cumulative Return'].plot(label='Softbank')
rakuten['Cumulative Return'].plot(label='Rakuten')
plt.legend()
Out[39]:
<matplotlib.legend.Legend at 0x7ff16162faf0>

2000年1月1日のソフトバンクの株価が高かったこともあり、意外と、楽天が1番になりました。
でも、20年で2倍にしかならないってどうなんだろうと思います。もっとも、配当を考慮してませんが。

ちなみに、配当を考慮すると以下のようになって、KDDIと楽天が同じような感じですね。どちらにしても2倍程度です。

In [40]:
ntt['returns'] = ntt['Adj Close'].pct_change(1)
kddi['returns'] = kddi['Adj Close'].pct_change(1)
softbank['returns'] = softbank['Adj Close'].pct_change(1)
rakuten['returns'] = rakuten['Adj Close'].pct_change(1)
ntt['Cumulative Return'] = (1 + ntt['returns']).cumprod()
kddi['Cumulative Return'] = (1 + kddi['returns']).cumprod()
softbank['Cumulative Return'] = (1 + softbank['returns']).cumprod()
rakuten['Cumulative Return'] = (1 + rakuten['returns']).cumprod()
ntt['Cumulative Return'].plot(label='NTT',figsize=(16,8),title='Cumulative Return')
kddi['Cumulative Return'].plot(label='KDDI')
softbank['Cumulative Return'].plot(label='Softbank')
rakuten['Cumulative Return'].plot(label='Rakuten')
plt.legend()
Out[40]:
<matplotlib.legend.Legend at 0x7ff161bc84c0>

Follow me!

Python株価分析

Posted by Etsu