05 ten_years_stock
| 242 Minute Read on Visualization
10 Years Korea Stock Price¶
- KOSPI 200 종목을 대상으로 10년 동안 수익률에 대해 시각화 하였음
- 200종목을 11개의 산업으로 분류 하였음(gics 기준)
- 주가는 Yahoo Finance에서 다운을 받아 수정 종가가 아닌 일반 종가를 사용하여 수익률을 계산하였음
In [1]:
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
from pandas_datareader import data, wb
from datetime import datetime
import seaborn as sns
import squarify
import matplotlib.font_manager as fm
import matplotlib
font_location = "/usr/share/fonts/truetype/nanum/NanumGothic.ttf"
font_name = fm.FontProperties(fname=font_location).get_name()
matplotlib.rc('font', family=font_name)
from pylab import rcParams
rcParams['figure.figsize'] = 16, 10
from pandas_datareader import data as pdr
import fix_yahoo_finance as yf
import numpy as np
In [3]:
df_prices = pd.read_csv("yahoo_prices.csv")
startday = datetime(2007, 1, 1)
endday = datetime(2017, 9, 18)
# download dataframe
df_kospi = pdr.get_data_yahoo('^KS11', start=startday, end=endday)
#gics = pd.read_excel("gics.xlsx", converters={'상장주식수(주)':float})
gics = pd.read_excel("gics.xlsx", converters={'scode':str})
gics = gics.rename(columns={'업종': 'sector','종목명': 'asset','거래대금(원)':'tr_vol','상장시가총액(원)':'mar_cap'})
gics = gics[['sector', 'scode', 'asset','mar_cap', 'tr_vol' ]]
gics['sector'][gics['sector'].str.contains('정보')] = '정보기술'
gics.head(10)
Out[3]:
In [4]:
#gics.rename(columns={'업종':'sector','종목명':'asset'},inplace=True)
df_prices.rename(columns={'Date':'date','sname':'asset','Cl':'close'},inplace=True)
df_prices = df_prices.merge(gics[['sector','asset','mar_cap']], left_on='asset', right_on='asset' )
df_prices = df_prices[['date','sector','asset','close','mar_cap']]
In [5]:
df_170901 = df_prices[df_prices['date'] == '2017-09-01']
WordCloud를 사용하여 Kospi200 종목들을 표시함¶
In [6]:
from wordcloud import WordCloud
df_170901['asset'].values
dlist = (df_170901['asset'].values)
#wordcloud = WordCloud(font_path= "/usr/share/fonts/truetype/nanum/NanumGothic.ttf" ).generate(str(dlist))
wordcloud = WordCloud(font_path= "/usr/share/fonts/truetype/nanum/NanumGothic.ttf", relative_scaling = 0.2,
min_font_size = 5, max_font_size = 20 ).generate(str(dlist))
fig = plt.figure(1)
plt.imshow(wordcloud)
plt.axis('off')
plt.show()
fig.savefig("word1.png", dpi=900)
In [7]:
grby1 = df_170901.groupby('sector').count().reset_index()
In [8]:
grby1 = grby1.sort_values('date',ascending=True)
df_170901.head()
Out[8]:
산업별 분류¶
In [9]:
height = grby1['date']
bars = grby1['sector']
y_pos = np.arange(len(bars))
plt.bar(y_pos, height)
plt.xticks(y_pos, bars)
plt.show()
#https://python-graph-gallery.com/1-basic-barplot/
시가총액별 TreeMap¶
In [10]:
squarify.plot(sizes=df_170901['mar_cap'], label=df_170901['asset'], alpha=.8, )
plt.axis('off')
Out[10]:
In [11]:
df_prices.head()
Out[11]:
df_prices(Kospi200 종목들 데이터)와 df_kospi를 merge¶
In [12]:
#df_prices를 피봇 처리
df_prices= df_prices.pivot_table(values= 'close', index = 'date', columns= ['sector','asset'])
In [13]:
df_prices.head()
Out[13]:
In [14]:
df_kospi.rename(columns={'Date':'date','Close':'kospi'},inplace=True)
df_kospi = df_kospi[['kospi']]
df_kospi.columns = pd.MultiIndex.from_tuples([('index','kospi')])
df_pr = df_kospi.merge(df_prices, left_index = True, right_index = True)
In [15]:
df_pr.head(5)
Out[15]:
월별 수익률 계산¶
In [16]:
# 일별 시계열을 월별로 resample 함
df_prm = df_pr.resample('BM').apply(lambda x:x[-1])
In [17]:
df_prm.head(5)
Out[17]:
In [18]:
# 중간에 수익율이 비어 있으면 보간
df_prm =df_prm.interpolate()
# 전월에 수익률이 없으면 다음월의 수익률로 대체
df_prm= df_prm.fillna(method='bfill')
# 수익률 계산
df_m_ret = df_prm.pct_change()
# 첫월 수익률 NA이므로 제거
df_m_ret = df_m_ret.dropna()
In [19]:
# 누적수익률 계산
df_m_cumret = (df_m_ret + 1).cumprod() -1
In [20]:
df_m_cumret.head(5)
Out[20]:
업종 평균을 계산후 그래프¶
In [21]:
#
#df_m_cumret.plot()
df_m_cumret.groupby(level=[0], axis =1).mean().plot()
Out[21]:
In [22]:
df_m_cumret.groupby(level=[0], axis =1).mean().tail(5)
Out[22]:
- 그래프와 표를 통해서 지난 10년동안 업종별로 건강관리, 필수소비재, 자유소비재, 에너지 정보, 소재 등이 높은 수익률을 보임.
섹터별 종목별 수익률 그래프¶
In [23]:
fig, axes = plt.subplots(4,3, figsize = (18,50))
grby2 = df_m_cumret.groupby(level=[0], axis = 1)
for i, (name, group) in enumerate(grby2):
group.plot(ax = axes[i // 3][i % 3])
상위 15종목 월간 Heatmap¶
In [24]:
df_15 = df_m_cumret.sort_values('2017-09-29 00:00:00', ascending=0, axis = 1)
In [25]:
df_15 = df_15.iloc[:,:15]
df_15.columns = df_15.columns.droplevel()
In [26]:
df_15.columns.values
Out[26]:
In [27]:
df_m_15 = df_m_ret
df_m_15.columns = df_m_15.columns.droplevel()
In [28]:
df_m_15 = df_m_15[df_15.columns.values]
In [29]:
#df15 = df15.iloc[:,:15]
#df_m_15.columns = df_m_15.columns.droplevel()
df_m_15.columns.name = 'asset'
df_m_15.index.name = 'date'
In [30]:
import plt_m_heat
plt_m_heat.plot_monthly_ic_heatmap(df_m_15)
plt.show()
년도별 상위 10 종목¶
In [31]:
# 월별 수익률을 복리로 처리하는 것이 맞지만 계산의 편의를 위한 단순합함
df_m_ret.groupby(df_m_ret.index.year).sum()
Out[31]:
In [32]:
grby5= df_m_ret.groupby(df_m_ret.index.year)
In [33]:
fig, axes = plt.subplots(4,3, figsize = (18,50))
import matplotlib.cm as cm
for i, (name, group) in enumerate(grby5):
srz = group.sum()
srz[srz.rank(pct=True)>0.95].sort_values(ascending =False).plot(kind= 'barh' ,cmap=cm.RdYlGn,
ax = axes[i // 3][i % 3], title = (" Return {} ".format(name)))