Help us understand the problem. What is going on with this article?

pandas-datareaderで取得した株価から、収益率と累積収益率を計算する

More than 1 year has passed since last update.

1.日経平均を取得してグラフ描画する

test1.py
!pip install pandas_datareader

import matplotlib.pyplot as plt
import matplotlib.style as style
from datetime import datetime
import pandas_datareader.data as web

style.use('fivethirtyeight')

st='2018/01/01'
ed='2018/12/31'

df=web.DataReader('NIKKEI225','fred',st,ed)
df=df.fillna(method='ffill')
df.plot()

・pandas-datareaderを用いて株価データを取得
・日経平均は、セントルイス連邦準備銀行のFREDから取得
・matplotlibのスタイルは「fivethirtyeight」を使用。
 ※538:アメリカの統計学者ネイトシルバーのサイトFiveThirtyEight.comより
・株価は値が付かないケースもあるので、欠損値を埋める作業が必要。
・pandasには、fillna()が用意されている。method='ffill'、つまり前営業日の値で埋める処理を施す。

※出力結果:2018/01/04〜2018/11/23_nikkei225
20181125_1.png
2月と10月に大きく下落していますね...

2.収益率と累積収益率を計算する

test2.py
#
!pip install pandas_datareader

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as style
from datetime import datetime
import pandas_datareader.data as web

style.use('fivethirtyeight')

def culc(df):
        x=df.fillna(method='ffill').dropna()

        #変化率
        stk_ret=x.pct_change()
        g=stk_ret.plot()
        g.axhline(y = 0, color = 'black', linewidth = 1.3, alpha = .7)

        #累積積
        cum_ret_d=(1+stk_ret).cumprod()
        cum_ret_d.iloc[0]=1
        g=cum_ret_d.plot()
        g.axhline(y = 1.0, color = 'black', linewidth = 1.3, alpha = .7)

st='2018/01/01'
ed='2018/12/31'
ds=['DJIA','NIKKEI225']

df = web.DataReader(ds,'fred',st,ed)
culc(df)

・ダウ平均(DJIA)と日経平均(NIKKEI225)を取得
・複数の銘柄を取得する場合は、リストlistにしてDatareaderで引数指定すれば取得可能
・株価(指数)の日々の収益率を計算するには、dfの変化率をpct_change()で算出すれば可能
・ある時点を1(100)として、そこからの累積収益率を求める場合は、dfの変化率をpct_change()で算出して、それをcumprod()で累積積を算出すればOK
・dfのpct_change()を算出すると、dfの1件目の値は、最初の項目なので変化率が計算できずにNaNになる。ゆえに累積積をcumprod()で算出した後に1をセットしておく
・pct_changeのpctはpercent(パーセント)の略、cumprodはcumulative product(累積的な積)の略っぽい。
・グラフ上にYの実線を入れたい場合は、axhline()で描画する

※収益率の算出結果:pct_change()
20181125_2.png

※累積収益率の算出結果:pct_change()→ cumprod()
20181125_3.png

・累積収益率を計算する趣旨としては、例えばダウや日経平均など数値水準や通貨単位が異なるものを、任意の日を1もしくは100とした場合の、そこからの変化の推移を比較することが可能という点と。その任意の日から株式(orETFなど)をバイアンドホールドした場合の収益結果を示すことが可能という点である。
・上記グラフの場合だと、ダウと日経平均に連動のETFを2018年1月1日に1株ずつ購入し現在まで保有し続けた場合の収益結果を直感的に図示することが可能。(現実には売買単位100株とかあるので、1株で買える買えないというのはあるのだが、結果を単純化するという意味で1株ということになる)
・ここでいう「収益率」というのはキャピタルゲインの事であり、インカムゲイン配当収益は加味していない。もっと言うと証券会社への売買手数料や税金(譲渡課税や配当課税)もここでは考慮していない。

3.複数銘柄で組成したPFの収益率と累積収益率を計算する

test3.py
#
!pip install pandas_datareader

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.style as style
from datetime import datetime
import pandas_datareader.data as web

style.use('fivethirtyeight')

def culc(df):
        x=df.fillna(method='ffill').dropna()
        stk_ret=x.pct_change()
        cum_ret_d=(1+stk_ret).cumprod()
        cum_ret_d.iloc[0]=1
        g=cum_ret_d.plot()
        g.axhline(y = 1.0, color = 'black', linewidth = 1.3, alpha = .7)

st='2018/01/01'
ed='2018/12/31'
ds=['DJIA','NIKKEI225']

df = web.DataReader(ds,'fred',st,ed)
culc(df)

#2914:JT
#7201:Nissan

#2銘柄の株価取得
df = web.DataReader(['2914.JP','7201.JP'],'stooq')
#print(df.items)

x=df['Close']
x=x.sort_index(ascending=True)
x=x['2018-03-25':]
x=x.T
fd=x.sum()
culc(fd)

・日本株式の複数銘柄の株価を取得したい場合、pandas_datareaderを用いてStooqから取得
・複数銘柄をリストにしてpandas_datareaderを用いてStooqから取得すると、結果のデータセットはxyzの3次元オブジェクトが返ってくるので、上記ではまず終値[Close]を指定してDateと終値の2次元オブジェクトにして、そのあと3/25以降のレコードを利用するようにしている。あとdfの並び順が降順だったので、set_indexを指定して昇順に変更している。
・複数銘柄の株価の収益率と累積収益率を計算する場合は、pct_change()で変化率を計算した上で、cumprod()で累積の積を計算するという流れは一緒なのだが。収益率を算出する前に、最初にdfを転置(transpose)したものをsum()で各銘柄の株価の合計値を算出しておくのがポイント。
・df(データフレーム)はベクトルオブジェクトなので、行列の転置は超簡単に行える。
・上記の例では、配当利回りが高い(と言われている2銘柄)2914_JTと7201_日産自動車の株を3/25(権利落ち直前日)に1株ずつ購入して保有し続けた場合のpfの累積収益率を算出しグラフ描画している(該当pfは黄色)
※注:売買単位100株なので現実には1株だけ買うのは無理です
・JTは12月決算なので、正確に言うと 3月25日に購入してもしなくても配当には関係なしです。ただJTは1月2月に株価爆下げしているので、1月に購入していた場合、もっと悲惨な状況になっていたことかと。いや購入タイミングって重要ですよねー

20181125_4.png

・上記ではPFにJTと日産自動車の2銘柄のバイアンドホールドの累積収益率を算出したが、もちろんPFはロングショートでも可能です。pandas-datareader(FREDやstooq)ではTOPIXの値が取得できないのだけれども。例えば日経平均を1株買い、かつTOPIXを1株売るといったNT倍率チックなPFでも収益率は計算可能で、ショートするTOPIXの列の値に係数(-1)を掛けた上で、転置T→ sum()をしてあげれば計算可能かと思われ。
・ていうかTOPIXの値、どうやって調達すればいいのだろうか?

4.余談

ちなみに以下グラフは1年前、2017年のダウ平均と日経平均の累積収益率の推移です↓
20181124_5.png
ほぼ右肩上がりというか、ゴルティロックス(適温相場)というか。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away