import FinanceDataReader as fdr
%matplotlib inline
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

pd.options.display.float_format = '{:,.3f}'.format

주가지수보다 더 좋은 수익율을 자주 보여준다.#

mdl_data = pd.read_pickle('mdl_data.pkl')
mdl_data.head().style.set_table_attributes('style="font-size: 12px"').format(precision=3)
  open high low close volume change code name kosdaq_return return win_market close_r1 close_r2 close_r3 close_r4 close_r5 max_close
2021-01-05 2270 2285 2200 2250 410263 -0.004 060310 3S 1.008 0.996 0 1.018 1.018 0.998 0.967 0.971 1.018
2021-01-06 2225 2310 2215 2290 570349 0.018 060310 3S 0.996 1.018 1 1.000 0.980 0.950 0.954 0.950 1.000
2021-01-07 2290 2340 2240 2290 519777 0.000 060310 3S 1.008 1.000 0 0.980 0.950 0.954 0.950 0.959 0.980
2021-01-08 2300 2315 2225 2245 462568 -0.020 060310 3S 0.999 0.980 0 0.969 0.973 0.969 0.978 0.973 0.978
2021-01-11 2230 2275 2130 2175 409057 -0.031 060310 3S 0.989 0.969 0 1.005 1.000 1.009 1.005 1.002 1.009


이전 장에서 일봉 데이터에 KOSDAQ 주가지수 데이터를 추가한 후, 주가지수 수익율이 1 보다 작은 날, 종목 수익율이 1 보다 크면 win_market 이라는 변수에 1 을 담아 두도록 했습니다. win_market 의 과거 60일 동안 합계와 미래 수익율과의 관계를 보겠습니다. 별도로 주가지수 수익률 대비 종목 수익율의 비율을 새로운 변수로 만들어, 미래 수익율과의 상관관계도 볼 수 있도록 하겠습니다.

kosdaq_list = pd.read_pickle('kosdaq_list.pkl')

data_h5 = pd.DataFrame()

for code in kosdaq_list['code']:
    
    # 종목별 처리
    data = mdl_data[mdl_data['code']==code].sort_index().copy()
    
    # 과거 60일 win_market 누적 합
    data['num_win_market'] = data['win_market'].rolling(60).sum() # 주가지수 수익율이 1 보다 작을 때, 종목 수익율이 1 보다 큰 날 수
    data['pct_win_market'] = (data['return']/data['kosdaq_return']).rolling(60).mean() # 주가지수 수익율 대비 종목 수익율
        
    
    # 고가, 저가, 종가 수익율
    for i in [1,2,3,4,5]:

        data['high_r' + str(i)] = data['high'].shift(-1*i)/data['close']      
        data['low_r' + str(i)] = data['low'].shift(-1*i)/data['close']   
        data['close_r' + str(i)] = data['close'].shift(-1*i)/data['close']    
        
    data['max_close']  = data[['close_r1','close_r2','close_r3','close_r4','close_r5']].max(axis=1) # 5 영업일 종가 수익율 중 최고 값
    data.dropna(subset=['num_win_market','close_r1','close_r2','close_r3','close_r4','close_r5'], inplace=True) # missing 이 있는 행은 제거   
 
    data_h5 = pd.concat([data, data_h5], axis=0)

data_h5.to_pickle('data_h5.pkl')    
data_h5.head().style.set_table_attributes('style="font-size: 12px"').format(precision=3)   
  open high low close volume change code name kosdaq_return return win_market close_r1 close_r2 close_r3 close_r4 close_r5 max_close num_win_market pct_win_market high_r1 low_r1 high_r2 low_r2 high_r3 low_r3 high_r4 low_r4 high_r5 low_r5
2021-04-01 13100 13650 13100 13400 194185 0.023 238490 힘스 1.010 1.023 0 1.007 1.022 1.019 1.041 1.026 1.041 9.000 1.001 1.019 0.993 1.030 1.000 1.037 1.007 1.041 1.007 1.049 1.026
2021-04-02 13500 13650 13300 13500 136673 0.007 238490 힘스 1.004 1.007 0 1.015 1.011 1.033 1.019 1.022 1.033 9.000 1.001 1.022 0.993 1.030 1.000 1.033 1.000 1.041 1.019 1.030 1.015
2021-04-05 13600 13800 13400 13700 219062 0.015 238490 힘스 1.000 1.015 1 0.996 1.018 1.004 1.007 0.993 1.018 9.000 1.001 1.015 0.985 1.018 0.985 1.026 1.004 1.015 1.000 1.011 0.989
2021-04-06 13800 13900 13500 13650 135914 -0.004 238490 힘스 0.999 0.996 0 1.022 1.007 1.011 0.996 1.004 1.022 9.000 1.001 1.022 0.989 1.029 1.007 1.018 1.004 1.015 0.993 1.007 0.996
2021-04-07 13700 13950 13500 13950 195408 0.022 238490 힘스 1.005 1.022 0 0.986 0.989 0.975 0.982 1.018 1.018 9.000 1.002 1.007 0.986 0.996 0.982 0.993 0.971 0.986 0.975 1.022 0.971


예상한 바와 같이 주가지수가 빠질 때, 수익율이 좋았던 종목들은 미래 수익율이 좋게 나타났습니다.

data_h5 = pd.read_pickle('data_h5.pkl')    
ranks = pd.qcut(data_h5['num_win_market'], q=8)
print(data_h5.groupby(ranks)['max_close'].mean())
data_h5.groupby(ranks)['max_close'].mean().plot(figsize=(12,5))
num_win_market
(-0.001, 4.0]   1.022
(4.0, 5.0]      1.031
(5.0, 6.0]      1.031
(6.0, 7.0]      1.032
(7.0, 8.0]      1.032
(8.0, 9.0]      1.034
(9.0, 11.0]     1.036
(11.0, 22.0]    1.040
Name: max_close, dtype: float64
<AxesSubplot:xlabel='num_win_market'>
../_images/5.1.5_Hypothesis_5_6_2.png


주가지수 수익율 대비 종목수익율의 경우는 아주 크거나 작을 때 수익율이 좋게 나타났습니다.

ranks = pd.qcut(data_h5['pct_win_market'], q=10)
print(data_h5.groupby(ranks)['max_close'].mean())
data_h5.groupby(ranks)['max_close'].mean().plot(figsize=(12,5))
pct_win_market
(0.9747, 0.9964]   1.039
(0.9964, 0.9976]   1.029
(0.9976, 0.9985]   1.026
(0.9985, 0.9992]   1.024
(0.9992, 1.0]      1.025
(1.0, 1.0007]      1.026
(1.0007, 1.0016]   1.028
(1.0016, 1.0029]   1.031
(1.0029, 1.0052]   1.038
(1.0052, 1.0432]   1.049
Name: max_close, dtype: float64
<AxesSubplot:xlabel='pct_win_market'>
../_images/5.1.5_Hypothesis_5_8_2.png