🐍 파이썬 데이터 분석 프로젝트/📈 KOSPI 시각화 분석

📈 데이콘 KOSPI 주가 분석 03. 이동평균선 시각화

nyamin9 2023. 1. 15. 10:51

모바일은 화면을 돌려 가로화면으로 보시는 게 읽으시기 편할 수 있습니다. 돌려서 보시는 걸 추천드릴게요!!

 

 


 

📝 목차

1. Datetime Index 생성

2. 시각화

3. rolling window( ) 함수 : 이동평균선
    3.1. 이동평균 데이터 생성
    3.2. 상관관계 분석
    3.3. 단기이평선, 장기이평선, 실지수 비교
    3.4. 2019년 이후의 이동평균선
    3.5. 2022년도의 이동평균선

 

📈 이번 포스팅에서는 KOSPI 데이터를 시각화하고 이동평균선을 바탕으로 향후 KOSPI 지수를 예측해 볼 것입니다.

 


🏆 1. Datetime Index 생성

 

# 코스피지수의 종가를 plotting
fig = go.Figure()
fig.add_trace(go.Line(x = kospi.index, y = kospi['Close'], marker_color = '#8c8cf5'))
fig.update_layout({'template' : 'plotly_white'})
fig.show()

 

 

📈 시험삼아 그래프를 출력해본 결과 x축이 데이터의 개수로 라벨링 된 것을 알 수 있었습니다. 즉, 데이터의 인덱스가 x축을 구성한 상태이기에 Date열을 인덱스로 변환하여 향후 분석과 시각화를 진행하기로 결정하였습니다.

 

# 데이터의 Date column을 datetime64 자료형으로 변경
kospi['Date'] = pd.to_datetime(kospi['Date'])
kospi.info()
>> Out[34]

RangeIndex: 11031 entries, 0 to 11030
Data columns (total 7 columns):
 #   Column  Non-Null Count  Dtype         
---  ------  --------------  -----         
 0   Date    11031 non-null  datetime64[ns]
 1   Close   11031 non-null  float64       
 2   Open    11031 non-null  float64       
 3   High    11031 non-null  float64       
 4   Low     11031 non-null  float64       
 5   Volume  11031 non-null  float64       
 6   Change  11031 non-null  float64       
dtypes: datetime64[ns](1), float64(6)
memory usage: 603.4 KB

 

# 변경한 datetime을 인덱스로 설정함
kospi = kospi.set_index('Date').copy()
kospi

 


🏆 2. 시각화

 

# 한 도표에 시가, 종가, 고가, 저가를 모두 출력
fig = go.Figure()
fig.add_trace(go.Line(x = kospi.index, y = kospi['Close'], name = 'Close'))
fig.add_trace(go.Line(x = kospi.index, y = kospi['Open'], name = 'Open'))
fig.add_trace(go.Line(x = kospi.index, y = kospi['High'], name = 'High'))
fig.add_trace(go.Line(x = kospi.index, y = kospi['Low'], name = 'Low'))

fig.update_layout(
    {
        'title' : {'text':'년도에 따른 KOSPI 지수 - 종가, 시가, 고가, 저가'},
        'xaxis' : {'title':'년도', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()

 

📈 일반적인 방식은 아니지만 전체적인 추세를 알아보기 위해 한 도표에 종가, 시가, 저가, 고가를 모두 plot 했습니다. 전체적으로 오버랩되는 도표가 그려졌으며, 데이터가 굉장히 오랜 기간에 대한 데이터이기에 전체 범위에서 모든 주가를 시각화하는 것은 상당히 비효율적인 일이라 생각하였습니다.

 


🏆 3. Rolling Window( ) 함수 : 이동평균선

 

📈 주가 예상에 중요한 수치중 하나로 이동평균선(moving average)이 있습니다. (당일-x일)~(당일)까지 주가의 평균을 이은 선입니다.

 

📈 주로 5일, 10일, 20일, 60일, 120일 이평선을 사용하며, 20일 이평선까지는 단기, 60일까지는 중기, 120일 초과 이평선은 장기 이평선으로 구분하는 경우가 많습니다.

 

📈 이동평균선의 움직임으로 주가를 예측하기 위해서는 단기이동평균선과 장기이동평균선을 비교해야 합니다.

 

▪ 투자론에서 단기이동평균선이 장기이동평균선보다 위에 있는 경우(정배열), 그 겹쳐서 올라가기 시작하는 점을 골든크로스라고 합니다. 이때 주가가 오를 것이라 예측합니다.

 

▪ 반면 단기이동평균선이 장기이동평균선보다 밑에 있는 경우(역배열), 겹쳐서 내려가기 시작하는 점을 데드크로스라고 합니다. 이때 주가가 하락할 것이라 예측합니다.

 

 일반적으로 주가 데이터는 시계열 데이터인 경우가 많습니다. 이를 처리하기 위해서 파이썬은 .rolling() 함수를 제공합니다.

# 데이터프레임에서 하나의 열 Series를 s라 하면 평균을 구하고 싶은 일수 X에 대하여
r = s.rolling(window=X).mean()

 

📈 이를 통해서 단기이평선과 장기이평선을 비교하거나, 실제 주가를 비교하여 미래의 주가를 예측합니다.

 


🏆 3.1. 이동평균 데이터 생성 및 plotting

 

# 5, 10, 20, 60, 120, 200일 이동평균 구함
mov_5 = kospi['Close'].rolling(window=5).mean()
mov_10 = kospi['Close'].rolling(window=10).mean()
mov_20 = kospi['Close'].rolling(window=20).mean()
mov_60 = kospi['Close'].rolling(window=60).mean()
mov_120 = kospi['Close'].rolling(window=120).mean()
mov_200 = kospi['Close'].rolling(window=200).mean()

# kospi 데이터프레임에 이동평균 데이터 추가
kospi['mov_5'] = mov_5
kospi['mov_10'] = mov_10
kospi['mov_20'] = mov_20
kospi['mov_60'] = mov_60
kospi['mov_120'] = mov_120
kospi['mov_200'] = mov_200
kospi

 


🏆 3.2. 상관관계 분석

 

📈 이렇게 이동평균선까지 구해서 넣은 새로운 데이터프레임이 생성되었습니다.


📈 이번에는 이 데이터프레임으로부터 각 column들 간의 상관관계를 분석해볼 것입니다.

 

kospi_corr = kospi.corr()

mask = np.zeros_like(kospi_corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True

plt.figure(figsize = (12,9))
ax = sns.heatmap(kospi_corr, mask = mask, 
		 annot=True, annot_kws=dict(color='r'), linewidths=.5, cmap='Blues')
plt.show()

 

- 상관관계를 구한 결과 종가, 시가, 고가, 저가와 각각의 이동평균선들은 서로 아주 높은 양의 상관관계를 보임을 확인할 수 있었습니다. 거의 정비례한다고 볼 수 있을 것 같네요.

 

- 반면 변동률과 다른 column들 간의 상관관계는 매우 작은 음의 상관관계를 보여주었습니다.

 

- 거래량은 다른 column들과 양의 상관관계를 가지기는 하지만 보편적인 기준인 0.7을 넘지 못할 뿐더러, 이동평균선들과 비교하면 그렇게 높은 값은 아닐 것이라 결론지었습니다.

 

- 이에, 주식의 가격을 예측하는 데에 각각의 이동평균선이 관계가 있다고 볼 수 있습니다. 따라서 이번 시각화에서 코스피지수를 예측하기 위해 종가와 이동평균선을 사용할 계획입니다.

 

 


🏆 3.3. 단기이평선, 장기이평선, 코스피지수 비교

 

# 200일 장기이평선과 실제 종가를 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi.index, y = kospi['Close'], 
	    	      name = '실제 종가', marker_color = '#8c8cf5'))
                  
fig.add_trace(go.Line(x = kospi.index, y = kospi['mov_200'], 
                      name = '200일 장기이평선', marker_color = '#ff0000'))

fig.update_layout(
    {
        'title' : {'text':'200일 장기이평선과 실제 종가 비교'},
        'xaxis' : {'title':'년도', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()


- 200일간의 장기이평선과 실제 종가를 비교한 결과 장기이평선의 전체적인 추세가 실제 종가를 따라감을 확인할 수 있습니다. 다만, 전체적인 추세가 원래의 지수보다 뒤쪽에서 형성된다는 점이 다릅니다. 이제 단기이평선과 실제 주가와의 관계를 비교해봅시다.

 

# 20일 단기이평선과 실제 종가를 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi.index, y = kospi['Close'], 
                      name = '실제 종가', marker_color = '#8c8cf5'))
                      
fig.add_trace(go.Line(x = kospi.index, y = kospi['mov_20'], 
                      name = '20일 단기이평선', marker_color = '#ff0000'))

fig.update_layout(
    {
        'title' : {'text':'20일 단기이평선과 실제 종가 비교'},
        'xaxis' : {'title':'년도', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()

 


- 20일 차이이기 때문에 거의 같은 모습을 보여줍니다. 본격적인 주가 예측을 위해 이제 단기이평선과 장기이평선을 비교할 것입니다.

 

# 단기이평선과 장기이평선을 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi.index, y = kospi['mov_200'], 
                      name = '200일 장기이평선', marker_color = '#ff0000'))
                      
fig.add_trace(go.Line(x = kospi.index, y = kospi['mov_20'], 
                      name = '20일 단기이평선', marker_color = '#8c8cf5'))

fig.update_layout(
    {
        'title' : {'text':'200일 장기이평선과 20일 단기이평선 비교'},
        'xaxis' : {'title':'년도', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()


- 단기이평선과 장기이평선을 비교해보니 장기이평선과 실제 종가지수를 비교하는 것과 큰 차이가 보이지 않습니다. 아마 1981년부터 2022년까지의 데이터를 모두 사용하려니 그 스케일의 범위가 너무 넓은 것 같습니다. 좀 더 좁은 기간에 대해서 비교해보는 게 정확할 듯 합니다.

 

- 비교적 최근의 주가를 예측하기 위해 주가가 전반적으로 오른 2019년 이후의 주가만을 사용해서 각 이평선과 실제 주가를 비교해볼 것입니다.

 

 


🏆 3.4. 2019년 이후의 코스피 지수를 사용한 이동평균선

 

# 2019년 이후의 데이터만을 사용하기 위한 슬라이싱
kospi_2019 = kospi[10118:]

# 2019년 이후의 장기이평선, 단기이평선, 실제 종가 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi_2019.index, y = kospi_2019['Close'], 
                      name = '실제 코스피 지수 (종가)', marker_color = '#5abeff'))
                      
fig.add_trace(go.Line(x = kospi_2019.index, y = kospi_2019['mov_200'], 
                      name = '200일 장기이평선', marker_color = '#ff0000'))
                      
fig.add_trace(go.Line(x = kospi_2019.index, y = kospi_2019['mov_20'], 
                      name = '20일 단기이평선', marker_color = 'orange'))

fig.update_layout(
    {
        'title' : {'text':'2019년 이후의 장기이평선, 단기이평선, 실제 종가 비교'},
        'xaxis' : {'title':'월 / 년도', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()

 

  • 이렇게 좁은 기간에 대해서 시각화해본 결과 실제 지수와 200일 장기이평선 간의 차이가 생각보다 큰 것을 확인할 수 있습니다. 또한 2022년대의 실제 지수와 이동평균선은 모두 우하향하는 추세입니다.
  • 2020년대 후반기와 2021년대 전반에 걸쳐 KOSPI 지수가 급등한 것을 알 수 있습니다. 반면 2022년 들어서는 좀처럼 상승하는 모습을 보여주지 못하고 있습니다.
  • 단기이동평균선(20일)과 장기이동평균선(200일), 그리고 실제 주가를 비교해본 결과 위에서 언급한 이론대로 단기이동평균선이 장기이동평균선보다 위에 있는 경우에는 주가가 상승하고, 반대인 경우에는 지수가 하락하는 것을 확인할 수 있습니다.
  • 주가가 변동하는 이유들은 정말 복잡하기에 단순한 시각화만으로 예측하기에는 섣부를 것이지만, 두 이동평균선 사이의 간극을 비교해보면 그렇게 빠르게 지수가 회복할 것으로 보이지는 않네요.

 


🏆 3.5. 2022년의 코스피지수를 사용한 이동평균선

 

# 2019년 이후의 장기이평선, 단기이평선, 실제 종가 비교
kospi_2022 = kospi[10860:]

# 2022년도 장기이평선(200), 단기이평선(20), 실제 종가 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['Close'], 
                      name = '실제 코스피 지수 (종가)', marker_color = '#5abeff'))
                      
fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_200'], 
                      name = '200일 장기이평선', marker_color = '#ff0000'))
                      
fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_20'], 
                      name = '20일 단기이평선', marker_color = 'orange'))

fig.update_layout(
    {
        'title' : {'text':'2022년도 장기이평선(200), 단기이평선(20), 실제 종가 비교'},
        'xaxis' : {'title':'월 (2022)', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()

 

# 2022년도 이평선, 실제 종가 비교
fig = go.Figure()
fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_200'], name = '200일 장기이평선'))

fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_120'], name = '120일 단기이평선'))

fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_60'], name = '60일 단기이평선'))

fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_20'], name = '20일 단기이평선'))

fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['mov_10'], name = '10일 단기이평선'))

fig.add_trace(go.Line(x = kospi_2022.index, y = kospi_2022['Close'], 
                      name = '실제 코스피 지수 (종가)', marker_color = '#5abeff'))


fig.update_layout(
    {
        'title' : {'text':'2022년도 장기이평선, 단기이평선, 실제 종가 비교'},
        'xaxis' : {'title':'월 (2022)', 'showticklabels': True},
        'yaxis' : {'title':'KOSPI','showticklabels': True},
        
        'template' : 'plotly_white'
    })

fig.show()

 

- 단기이동평균선(20일)과 장기이동평균선(200일), 그리고 실제 주가를 비교해본 결과 위에서 언급한 이론대로 단기이동평균선이 장기이동평균선보다 위에 있는 경우에는 주가가 상승하고, 반대인 경우에는 주가가 하락하는 것을 확인할 수 있습니다.

 

- 2022년도의 실제 지수와 이동평균선들을 비교해보면, 60일 이후의 이동평균선들은 쉽게 반등할 생각이 없어 보입니다.

 

- 2022/09/13 부근의 단기이동평균선과 장기이동평균선 사이의 차이가 점점 좁아지고 있기는 하지만 아직 그 간극이 좁다고는 할 수 없기에 앞으로의 주가 역시 2800~3000 선을 넘기에는 오랜 시간이 걸릴 것 같습니다. 물론 단순히 시각화를 통한 예측이기에 어떤 일이 생길지는 쉽게 보장할 수 없을 듯 합니다.

 


📈 이렇게 해서 이동평균선과 지수 시각화를 통해 향후 KOSPI 지수의 추세를 예측해 보았습니다. 하지만 수치를 예측할 수는 없기 때문에 다음 포스팅에서는 주가 예측 모델에 주로 사용하는 FbProphet 모듈을 사용해서 코스피지수를 예측할 계획입니다.