본문 바로가기
개발 프로젝트/Python

Python을 활용해 원자재 가격과 주가와의 상관관계 분석

by BuyAndPray 2020. 12. 2.
반응형

* 주피터 노트북에서 개발을 진행하였습니다.

 

그러면 지금부터 본격적으로 원자재 가격과 주가와의 상관관계를 수치적으로 계산해보겠다. 

 

원자재 가격The World Bank에서 Monthly Price 데이터를 다운로드하여 사용하고, 주가 데이터이전 포스팅(링크)에서 설명하였듯이 Python FinanceDataReader 라이브러리를 사용하도록 하겠다.

 

원자재 가격 데이터 가져오기

먼저 다운로드한 월별 원자재 데이터를 Pandas를 활용해 DataFrame에 저장해보겠다.

 

pandas.read_excel()을 활용해 'CMOHistoricalDataMonthly.xlsx' 파일을 읽어온다. 읽으려는 엑셀 파일 sheet name이 'Monthly Prices' 이기 때문에 sheet_name 옵션도 설정해주고, 쓸데없는 description 부분을 날리기 위해 header도 설정해준다.

 

그런 뒤 2010년 1월부터의 데이터만 남겨놓고, 숫자가 아닌 Nan 타입의 데이터를 가진 열을 삭제하면 아래와 같은 결과가 나온다. 그리고 index가 0번부터 시작하기 위해 reset_index()를 적용한다.

 

import pandas as pd
import numpy as np

commodity = pd.read_excel('CMOHistoricalDataMonthly.xlsx', sheet_name="Monthly Prices", header=4)
commodity.drop([0, 1], inplace=True) # 불필요한 행 삭제
commodity.rename(columns = {'Unnamed: 0' : 'Date'}, inplace=True) # column 이름을 date로 변경

# 2010년 이후로만 분석한다
monthFilter = (commodity['Date'] >= '2010')
commodity = commodity[monthFilter]

# 데이터를 숫자로 변환 시킨 뒤 Nan 열 삭제 
commodity = commodity.apply(pd.to_numeric, errors='coerce')
commodity.dropna(axis=1, inplace=True)
commodity.reset_index(drop=True, inplace=True)

commodity

2010년 1월부터 원자재 별 가격 데이터 일부

 

원자재 가격과 주가 사이 상관계수 구하기

앞에서 추출했던 원자재 가격과 주가 사이의 상관계수를 구해보면서 상관관계를 분석해보도록 하겠다.

 

먼저 상관계수를 저장할 DataFrame coe를 생성한다. 그리고 앞에서 나온 상장 기업들 각각의 주가 데이터를 받아온 뒤 월별 평균 종가 데이터를 계산한다. 원자재 가격 데이터는 10월까지만 존재하기 때문에 주가 데이터도 마지막 달은 삭제했다. corrwith()를 사용해서 원자재(commodity)와 주가(df) 사이의 상관계수를 구한다.

 

최종으로 나온 결과는 아래와 같고, 주가 데이터가 1350개 정도라 계산하는데 꽤 시간이 걸렸다.

 

 

coe = pd.DataFrame(columns=commodity.columns)

for symbol in krx.Symbol:
  name = krx[krx['Symbol'] == symbol]['Name']
  df = fdr.DataReader(symbol, '2010-01-01').reset_index()
  df = df.groupby([df['Date'].dt.year, df['Date'].dt.month], as_index=False).mean()['Close']

  ## 마지막 달 삭제
  df.drop(df.tail(1).index,inplace=True)
  cor = commodity.corrwith(df, axis=0)
  cor.name = name.tolist()[0]
  coe = coe.append(cor)

coe

원자재와 주가사이의 상관계수들

 

계산 결과가 얼마나 정확한지 한 번 분석해보도록 하겠다. WTI 유가와 상관관계가 높은 주식은 삼성중공업 대우조선해양 같은 조선주들이었다. 실제로 조선주들의 주가는 원유 가격에 꽤 민감한 편이다. 저유가 상태가 지속될 경우 수주가 끊길 수도 있다는 불안감 때문이다. 

 

성광벤드 또한 조선사들에게 기자재 부품을 납품하는 것이 주된 사업이기에 조선업 수주에 민감하고 이 때문에 성광벤드 또한 WTI 유가와 큰 상관관계를 가지는 것으로 나타났다.

 

WTI유가 기준 상관계수(내림차순)

 

하지만 이 처럼 인과관계가 뚜렷하게 나타나는 경우는 드물었다. 엔씨소프트와 바나나 가격 사이에는 0.86 정도로 높은 상관관계가 있는 것으로 나타났지만 상식적으로 생각해도 엔씨소프트의 주가와 바나나 가격 사이에는 아무런 연관성이 없다.

 

주가를 결정하는 요인은 수만 가지이다. 조선업처럼 원자재 가격이 주가에 큰 영향을 미치는 산업분야도 있었지만 그렇지 않은 분야도 많았다. 따라서 어떤 단편적인 정보만을 가지고 투자하는 것은 금물인 것 같다.

 

전체 코드는 아래와 같다.

 

# -*- coding: utf-8 -*-
"""FinanceDataReader.ipynb

Automatically generated by Colaboratory.
"""

# https://github.com/FinanceData/FinanceDataReader/wiki/Users-Guide

! pip install finance-datareader

import FinanceDataReader as fdr

krx = fdr.StockListing('KRX')

columns = ['Symbol', 'Market', 'Name', 'Sector', 'Industry','ListingDate']
marketFilter = (krx['Market'] == 'KOSPI') | (krx['Market'] == 'KOSDAQ')
dateFilter = (krx['ListingDate'] <= '2010-01-01')
krx = krx[marketFilter & dateFilter][columns]
krx

import pandas as pd
import numpy as np

commodity = pd.read_excel('CMOHistoricalDataMonthly.xlsx', sheet_name="Monthly Prices", header=4)
commodity.drop([0, 1], inplace=True) # 불필요한 행 삭제
commodity.rename(columns = {'Unnamed: 0' : 'Date'}, inplace=True) # column 이름을 date로 변경

# 2010년 이후로만 분석한다
monthFilter = (commodity['Date'] >= '2010')
commodity = commodity[monthFilter]

# 데이터를 숫자로 변환 시킨 뒤 Nan 열 삭제 
commodity = commodity.apply(pd.to_numeric, errors='coerce')
commodity.dropna(axis=1, inplace=True)
commodity.reset_index(drop=True, inplace=True)

commodity

coe = pd.DataFrame(columns=commodity.columns)

for symbol in krx.Symbol:
  name = krx[krx['Symbol'] == symbol]['Name']
  df = fdr.DataReader(symbol, '2010-01-01').reset_index()
  df = df.groupby([df['Date'].dt.year, df['Date'].dt.month], as_index=False).mean()['Close']

  ## 마지막 달 삭제
  df.drop(df.tail(1).index,inplace=True)
  cor = commodity.corrwith(df, axis=0)
  cor.name = name.tolist()[0]
  coe = coe.append(cor)

coe.to_csv("coe.csv", mode='w')

coe

 

원자재 가격과 주가와의 상관관계 분석 시리즈

반응형

댓글