Compare commits

...

2 Commits

2 changed files with 118 additions and 0 deletions

View File

@ -1,6 +1,8 @@
import pandas as pd import pandas as pd
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import seaborn as sns import seaborn as sns
import statsmodels.api as sm
import numpy as np
import quantcommon import quantcommon
# 모멘텀 포트폴리오. 최근 12개월 수익률이 높은 주식 # 모멘텀 포트폴리오. 최근 12개월 수익률이 높은 주식
@ -51,4 +53,60 @@ g.set(ylabel=None)
g.fig.set_figwidth(15) g.fig.set_figwidth(15)
g.fig.set_figheight(8) g.fig.set_figheight(8)
plt.subplots_adjust(wspace=0.5, hspace=0.2) plt.subplots_adjust(wspace=0.5, hspace=0.2)
# plt.show()
# k-ratio(모멘텀의 꾸준함 지표)
ret = price_pivot.pct_change().iloc[1:]
ret_cum = np.log(1 + ret).cumsum()
x = np.array(range(len(ret)))
y = ret_cum.iloc[:, 0].values
reg = sm.OLS(y, x).fit()
reg.summary()
x = np.array(range(len(ret)))
k_ratio = {}
for i in range(0, len(ticker_list)):
ticker = data_bind.loc[i, '종목코드']
try:
y = ret_cum.loc[:, price_pivot.columns == ticker]
reg = sm.OLS(y, x).fit()
res = float(reg.params / reg.bse)
except:
res = np.nan
k_ratio[ticker] = res
k_ratio_bind = pd.DataFrame.from_dict(k_ratio, orient='index').reset_index()
k_ratio_bind.columns = ['종목코드', 'K_ratio']
k_ratio_bind.head()
data_bind = data_bind.merge(k_ratio_bind, how='left', on='종목코드')
k_ratio_rank = data_bind['K_ratio'].rank(axis=0, ascending=False)
print(data_bind[k_ratio_rank <= 20])
k_ratio_momentum = price_list[price_list['종목코드'].isin(data_bind.loc[k_ratio_rank <= 20, '종목코드'])]
plt.rc('font', family='Malgun Gothic')
g = sns.relplot(data=k_ratio_momentum,
x='날짜',
y='종가',
col='종목코드',
col_wrap=5,
kind='line',
facet_kws={
'sharey': False,
'sharex': True
})
g.set(xticklabels=[])
g.set(xlabel=None)
g.set(ylabel=None)
g.fig.set_figwidth(15)
g.fig.set_figheight(8)
plt.subplots_adjust(wspace=0.5, hspace=0.2)
plt.show() plt.show()

View File

@ -0,0 +1,60 @@
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import quantcommon
# 퀄리티(우량주) 포트폴리오. 영업수익성이 높은 주식
engine = quantcommon.QuantCommon().create_engine()
ticker_list = pd.read_sql("""
select * from kor_ticker
where 기준일 = (select max(기준일) from kor_ticker)
and 종목구분 = '보통주';
""", con=engine)
fs_list = pd.read_sql("""
select * from kor_fs
where 계정 in ('당기순이익', '매출총이익', '영업활동으로인한현금흐름', '자산', '자본')
and 공시구분 = 'q';
""", con=engine)
engine.dispose()
fs_list = fs_list.sort_values(['종목코드', '계정', '기준일'])
fs_list['ttm'] = fs_list.groupby(['종목코드', '계정'], as_index=False)[''].rolling(
window=4, min_periods=4).sum()['']
fs_list_clean = fs_list.copy()
fs_list_clean['ttm'] = np.where(fs_list_clean['계정'].isin(['자산', '자본']),
fs_list_clean['ttm'] / 4, fs_list_clean['ttm'])
fs_list_clean = fs_list_clean.groupby(['종목코드', '계정']).tail(1)
fs_list_pivot = fs_list_clean.pivot(index='종목코드', columns='계정', values='ttm')
fs_list_pivot['ROE'] = fs_list_pivot['당기순이익'] / fs_list_pivot['자본']
fs_list_pivot['GPA'] = fs_list_pivot['매출총이익'] / fs_list_pivot['자산']
fs_list_pivot['CFO'] = fs_list_pivot['영업활동으로인한현금흐름'] / fs_list_pivot['자산']
quality_list = ticker_list[['종목코드', '종목명']].merge(fs_list_pivot,
how='left',
on='종목코드')
# print(quality_list.round(4).head())
quality_list_copy = quality_list[['ROE', 'GPA', 'CFO']].copy()
quality_rank = quality_list_copy.rank(ascending=False, axis=0)
mask = np.triu(quality_rank.corr())
fig, ax = plt.subplots(figsize=(10, 6))
sns.heatmap(quality_rank.corr(),
annot=True,
mask=mask,
annot_kws={"size": 16},
vmin=0,
vmax=1,
center=0.5,
cmap='coolwarm',
square=True)
ax.invert_yaxis()
quality_sum = quality_rank.sum(axis=1, skipna=False).rank()
print(quality_list.loc[quality_sum <= 20,
['종목코드', '종목명', 'ROE', 'GPA', 'CFO']].round(4))