(Python : Basic) 수익률 계산해 보기

Posted by : at

Category : Python


디폴트 install, import

!pip install finance-datareader
!pip install beautifulsoup4 
!pip install numpy
!pip install pandas
# default settings
import numpy as np
import pandas as pd
from datetime import datetime

# jupyter notebook 여러 실행인자 실행해도 print되게 만들기
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

pd.set_option('display.float_format', lambda x: '%.3f' % x)
pd.set_option('max_columns', None)

6. 수익률 계산

import FinanceDataReader as fdr

df1 = fdr.DataReader("005930", '2018-01-02', '2018-10-30')
df2 = fdr.DataReader("069500", '2018-01-02', '2018-10-30')
df = pd.concat([df1['Close'], df2['Close']], axis=1)
df.columns = ['삼성전자', 'KODEX 200']
df.head()
삼성전자 KODEX 200
Date
2018-01-02 51020 30317
2018-01-03 51620 30446
2018-01-04 51080 30206
2018-01-05 52120 30616
2018-01-08 52020 30822

수익률의 계산을 위해 dataframe shift() 써보기

# 데이터를 한 칸 아래로 내린다
df.shift()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 51020.000 30317.000
2018-01-04 51620.000 30446.000
2018-01-05 51080.000 30206.000
2018-01-08 52120.000 30616.000
... ... ...
2018-10-24 43050.000 25636.000
2018-10-25 42550.000 25504.000
2018-10-26 41000.000 25097.000
2018-10-29 41000.000 24699.000
2018-10-30 41400.000 24499.000

202 rows × 2 columns

df.shift(periods=1).head()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 51020.000 30317.000
2018-01-04 51620.000 30446.000
2018-01-05 51080.000 30206.000
2018-01-08 52120.000 30616.000
# 초 단위로 내릴 수 있음.
df.shift(1, freq="S").head()
삼성전자 KODEX 200
Date
2018-01-02 00:00:01 51020 30317
2018-01-03 00:00:01 51620 30446
2018-01-04 00:00:01 51080 30206
2018-01-05 00:00:01 52120 30616
2018-01-08 00:00:01 52020 30822
df.head()
df.shift().head()
삼성전자 KODEX 200
Date
2018-01-02 51020 30317
2018-01-03 51620 30446
2018-01-04 51080 30206
2018-01-05 52120 30616
2018-01-08 52020 30822
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 51020.000 30317.000
2018-01-04 51620.000 30446.000
2018-01-05 51080.000 30206.000
2018-01-08 52120.000 30616.000
# 이렇게 하면 수익률을 계산할 수 있겠지?
(df / df.shift() - 1).head()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 0.012 0.004
2018-01-04 -0.010 -0.008
2018-01-05 0.020 0.014
2018-01-08 -0.002 0.007

좀 더 간단하게 pct_change()를 써볼까?

# 위와 정확히 동일하다
df.pct_change(periods=1).head()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 0.012 0.004
2018-01-04 -0.010 -0.008
2018-01-05 0.020 0.014
2018-01-08 -0.002 0.007
df.pct_change(periods=2).head()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 NaN NaN
2018-01-04 0.001 -0.004
2018-01-05 0.010 0.006
2018-01-08 0.018 0.020
# 뭐 대략 이런식으로 쓰이겠지??
simple_rtn_df = df.pct_change().fillna(0)
simple_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 0.000 0.000
2018-01-03 0.012 0.004
2018-01-04 -0.010 -0.008
2018-01-05 0.020 0.014
2018-01-08 -0.002 0.007

log단위로 수익률이 필요하다면?

# numpy와 함께라면 쉽다
np.log(df / df.shift()).head()
삼성전자 KODEX 200
Date
2018-01-02 NaN NaN
2018-01-03 0.012 0.004
2018-01-04 -0.011 -0.008
2018-01-05 0.020 0.013
2018-01-08 -0.002 0.007
log_rtn_df = np.log(df / df.shift()).fillna(0)
log_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 0.000 0.000
2018-01-03 0.012 0.004
2018-01-04 -0.011 -0.008
2018-01-05 0.020 0.013
2018-01-08 -0.002 0.007

그래프로 그려보자

!pip install seaborn
import matplotlib.pyplot as plt
import seaborn as sns
log_rtn_df.plot()
<AxesSubplot:xlabel='Date'>



c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

png

log_rtn_df.hist(bins=50, sharex=True)
array([[<AxesSubplot:title={'center':'삼성전자'}>,
        <AxesSubplot:title={'center':'KODEX 200'}>]], dtype=object)

png

log_rtn_df.boxplot()
<AxesSubplot:>



c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

png

sns.distplot(log_rtn_df['KODEX 200'], kde=False, bins=50);
sns.distplot(log_rtn_df['삼성전자'], kde=False, bins=50);
c:\Git\python-data\venv\lib\site-packages\seaborn\distributions.py:2619: FutureWarning: `distplot` is a deprecated function and will be removed in a future version. Please adapt your code to use either `displot` (a figure-level function with similar flexibility) or `histplot` (an axes-level function for histograms).
  warnings.warn(msg, FutureWarning)

png

sns.pairplot(log_rtn_df);
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\seaborn\axisgrid.py:88: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  self._figure.tight_layout(*args, **kwargs)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

png

누적 수익률 계산해 보기

df.head()
삼성전자 KODEX 200
Date
2018-01-02 51020 30317
2018-01-03 51620 30446
2018-01-04 51080 30206
2018-01-05 52120 30616
2018-01-08 52020 30822
df.iloc[0]
삼성전자         51020
KODEX 200    30317
Name: 2018-01-02 00:00:00, dtype: int64
cum_rtn_df = df / df.iloc[0]
cum_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 1.000 1.000
2018-01-03 1.012 1.004
2018-01-04 1.001 0.996
2018-01-05 1.022 1.010
2018-01-08 1.020 1.017
simple_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 0.000 0.000
2018-01-03 0.012 0.004
2018-01-04 -0.010 -0.008
2018-01-05 0.020 0.014
2018-01-08 -0.002 0.007
cum_rtn_df = (1 + simple_rtn_df).cumprod()
cum_rtn_df.head() 
삼성전자 KODEX 200
Date
2018-01-02 1.000 1.000
2018-01-03 1.012 1.004
2018-01-04 1.001 0.996
2018-01-05 1.022 1.010
2018-01-08 1.020 1.017

log로 표현

log_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 0.000 0.000
2018-01-03 0.012 0.004
2018-01-04 -0.011 -0.008
2018-01-05 0.020 0.013
2018-01-08 -0.002 0.007
cum_rtn_df = np.exp(log_rtn_df.cumsum())
cum_rtn_df.head()
삼성전자 KODEX 200
Date
2018-01-02 1.000 1.000
2018-01-03 1.012 1.004
2018-01-04 1.001 0.996
2018-01-05 1.022 1.010
2018-01-08 1.020 1.017

시각화

cum_rtn_df.plot()
<AxesSubplot:xlabel='Date'>



c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49340 (\N{HANGUL SYLLABLE SAM}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 49457 (\N{HANGUL SYLLABLE SEONG}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51204 (\N{HANGUL SYLLABLE JEON}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)
c:\Git\python-data\venv\lib\site-packages\IPython\core\pylabtools.py:151: UserWarning: Glyph 51088 (\N{HANGUL SYLLABLE JA}) missing from current font.
  fig.canvas.print_figure(bytes_io, **kw)

png


About Taehyung Kim

안녕하세요? 8년차 현업 C++ 개발자 김태형이라고 합니다. 😁 C/C++을 사랑하며 다양한 사람과의 협업을 즐깁니다. ☕ 꾸준한 자기개발을 미덕이라 생각하며 노력중이며, 제가 얻은 지식을 홈페이지에 정리 중입니다. 좀 더 상세한 제 이력서 혹은 Private 프로젝트 접근 권한을 원하신다면 메일주세요. 😎

Star
Useful Links