티스토리 뷰
한국은 미국에 영향을 많이 받습니다. 주식에서도 그럴까요? 미국 주식이 떨어지면 한국 주식도 떨어질까요, 아니면 관련이 없을까요. 그 궁금증을 해결하기 위해 다음과 같은 가설을 설정한 후, 분석을 진행해보았습니다.
가설1. S&P 500 index와 한국 KOSPI에 속하는 기업 주식 중 관련이 있는 주식이 존재할 것이다.
위의 가설을 입증하기 위해서 다음과 같은 순서로 분석을 진행하였습니다.
1. 회사 주식 코드 가져오기
pykrx 라이브러리를 활용하여 주식 정보를 가져왔습니다. pykrx 는 naver와 krx 등의 도메인에서 주식 데이터를 쉽게 가져오는데 도움이 되는 라이브러리입니다.
get_market_ticker_list 함수의 입력 인자로 날짜와 마켓이 있습니다. 리턴값으로 기업 주식 코드를 반환합니다.
from pykrx import stock
from pykrx import bond
import pandas as pd
tickers = stock.get_market_ticker_list("20240311", market="KOSPI")
print(tickers[:10])
#['095570', '006840', '027410', '282330', '138930', '001460', '001465', '001040', '079160', '00104K']
2. 기업명 매칭하기
기업 코드만 가지고는 어떤 기업인지 알 수 없습니다. 코드를 기반으로 코드: 기업명의 쌍을 가지는 dictionary를 만들어줍니다.
code_company_dct = {}
for ticker in tickers:
company_name = stock.get_market_ticker_name(ticker)
code_company_dct[code] = company_name
print(code_company_dct)
#{'095570': 'AJ네트웍스',
'006840': 'AK홀딩스',
'027410': 'BGF',
'282330': 'BGF리테일',
'138930': 'BNK금융지주',
'001460': 'BYC',
'001465': 'BYC우'
...
'079980': '휴비스',
'005010': '휴스틸',
'000540': '흥국화재',
'000545': '흥국화재우',
'003280': '흥아해운'}
3. KOSPI 데이터 전처리
get_market_ohlcv 함수를 활용하여 주식 데이터를 가져옵니다. 샘플로 삼성(005930) 주식 정보를 가져온 후 전처리를 해보도록 하겠습니다. 함수의 입력 인자로 시작날짜, 종료일자, 기업코드, 날짜구분(일,년,월,시 등)이 있습니다.
samsung_df = stock.get_market_ohlcv("20240124", "20240425", "005930", "d") #005930은 삼성 주식 코드
print(samsung_df.head())
'''
시가 고가 저가 종가 거래량 등락률
날짜
2024-01-24 75200 75200 73500 74000 12860661 -1.595745
2024-01-25 74200 74800 73700 74100 11737747 0.135135
2024-01-26 73700 74500 73300 73400 11160062 -0.944669
2024-01-29 73800 75200 73500 74400 13976521 1.362398
2024-01-30 75000 75300 73700 74300 12244418 -0.134409
'''
날짜기준 오름차순으로 정렬되어있음을 확인하실 수 있습니다.
데이터프레임으로 예상되며 각 컬럼별 데이터 타입을 확인해보겠습니다.
print(samsung_df.info())
<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 59 entries, 2024-01-24 to 2024-04-19
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 시가 59 non-null int32
1 고가 59 non-null int32
2 저가 59 non-null int32
3 종가 59 non-null int32
4 거래량 59 non-null int32
5 등락률 59 non-null float64
dtypes: float64(1), int32(5)
memory usage: 2.1 KB
None
날짜 데이터가 인덱스로 잡혀있습니다. 분석을 위해서는 날짜 데이터가 필요합니다. reset_index로 날짜를 하나의 컬럼으로 만들어줍니다.
samsung_df = samsung_df.reset_index()
print(samsung_df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 59 entries, 0 to 58
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 날짜 59 non-null datetime64[ns]
1 시가 59 non-null int32
2 고가 59 non-null int32
3 저가 59 non-null int32
4 종가 59 non-null int32
5 거래량 59 non-null int32
6 등락률 59 non-null float64
dtypes: datetime64[ns](1), float64(1), int32(5)
memory usage: 2.2 KB
None
S&P 500 데이터와 조인을 할 때, 날짜를 활용합니다. 현재의 날짜 데이터에는 시분초가 생략되어 있습니다. 연월일만 남기기 위해 데이터 타입을 string으로 변환해줍니다.
samsung_df['날짜'] = pd.to_datetime(samsung_df['날짜']).dt.strftime('%Y-%m-%d')
print(samsung_df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 59 entries, 0 to 58
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 날짜 59 non-null object
1 시가 59 non-null int32
2 고가 59 non-null int32
3 저가 59 non-null int32
4 종가 59 non-null int32
5 거래량 59 non-null int32
6 등락률 59 non-null float64
dtypes: float64(1), int32(5), object(1)
memory usage: 2.2+ KB
None
4. S&P 500 Index
4.1. 데이터 수집
크롤링하는 방법도 있지만 지금은 빠르게 진행하기 위해 WSJ 에서 데이터를 다운 받았습니다.
시작날짜: 01/25/2024 to 종료날짜: 04/24/2024 (월/일/연도)를 선택한 후,
오른쪽 DOWNLOAD A SPREADSHEET를 눌르면 HistoricalPrices.csv 파일을 받을 수 있습니다.
4.2. S&P 500 INDEX 전처리
데이터프레임으로 읽고 확인해보겠습니다.
sp_df = pd.read_csv("HistoricalPrices.csv")
print(sp_df.head())
Date Open High Low Close
0 04/19/24 5005.44 5019.02 4953.56 4967.23
1 04/18/24 5031.52 5056.66 5001.89 5011.12
2 04/17/24 5068.97 5077.96 5007.25 5022.21
3 04/16/24 5064.59 5079.84 5039.83 5051.41
4 04/15/24 5149.67 5168.43 5052.47 5061.82
print(sp_df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 62 entries, 0 to 61
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Date 62 non-null object
1 Open 62 non-null float64
2 High 62 non-null float64
3 Low 62 non-null float64
4 Close 62 non-null float64
dtypes: float64(4), object(1)
memory usage: 2.5+ KB
None
컬럼명에 띄어쓰기가 있는 것이 보입니다. 띄어쓰기를 제거해줍니다.
sp_df.columns = ["Date", "Open', "High", "Low", "Close"]
'''
변경전
Index(['Date', ' Open', ' High', ' Low', ' Close'], dtype='object')
변경후
Index(['Date', 'Open', 'High', 'Low', 'Close'], dtype='object')
'''
현재 분석 목적은 미국 주식이 오르면 한국 주식도 오르는지 확인하는 것입니다.
시간상 같은 날짜에 한국 주식 시장이 먼저 열리고 종료된 후, 미국 주식 시장이 열립니다.
분석 목적에 맞게 보기 위해서는 어제 미국 주식 정보를 오늘 한국 주식 정보와 비교해야 합니다.
이를 위해 S&P 500 Date에 -1일을 해줘야 합니다.
# Date 열에서 1일을 빼기
sp_df['Date'] = pd.to_datetime(sp_df['Date'])
sp_df['Date'] = sp_df['Date'] - pd.Timedelta(days=1)
'''
변경전
Date Open High Low Close
0 04/19/24 5005.44 5019.02 4953.56 4967.23
1 04/18/24 5031.52 5056.66 5001.89 5011.12
2 04/17/24 5068.97 5077.96 5007.25 5022.21
3 04/16/24 5064.59 5079.84 5039.83 5051.41
4 04/15/24 5149.67 5168.43 5052.47 5061.82
변경후
Date Open High Low Close
0 2024-04-18 5005.44 5019.02 4953.56 4967.23
1 2024-04-17 5031.52 5056.66 5001.89 5011.12
2 2024-04-16 5068.97 5077.96 5007.25 5022.21
3 2024-04-15 5064.59 5079.84 5039.83 5051.41
4 2024-04-14 5149.67 5168.43 5052.47 5061.82
'''
국내 주식 데이터와 조인하기 위해 Date를 코스피 데이터와 동일한 형태와 타입으로 변경해줘야 합니다.
to_datetime과 strftime을 활용하여 데이터 형태와 타입을 변경해줍니다.
sp_df['Date'] = pd.to_datetime(sp_df['Date']).dt.strftime('%Y-%m-%d')
print(sp_df.info())
'''
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 62 entries, 0 to 61
Data columns (total 5 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 Date 62 non-null object
1 Open 62 non-null float64
2 High 62 non-null float64
3 Low 62 non-null float64
4 Close 62 non-null float64
dtypes: float64(4), object(1)
memory usage: 2.5+ KB
None
'''
5. 데이터 조인
S&P 500 데이터와 삼성 데이터를 조인하도록 하겠습니다.
all_df = sp_df.merge(samsung_df, left_on="Date", right_on="날짜", how="inner")
all_df.head()
Date Open High Low Close 날짜 시가 고가 저가 종가 거래량 등락률
0 2024-01-24 4886.66 4898.15 4869.34 4894.16 2024-01-24 75200 75200 73500 74000 12860661 -1.595745
1 2024-01-25 4888.91 4906.69 4881.47 4890.97 2024-01-25 74200 74800 73700 74100 11737747 0.135135
2 2024-01-29 4925.89 4931.09 4916.27 4924.97 2024-01-29 73800 75200 73500 74400 13976521 1.362398
3 2024-01-30 4899.19 4906.75 4845.15 4845.65 2024-01-30 75000 75300 73700 74300 12244418 -0.134409
4 2024-01-31 4861.11 4906.97 4853.52 4906.19 2024-01-31 73400 74000 72500 72700 15703560 -2.153432
종가-시가, Close-Open을 함으로써 해당 날짜에 주식 가격과 S&P500 INDEX가 올랐는지 떨어졌는지를 나타내는 컬럼을 만듭니다.
# 6. 시가 - 종가 컬럼 만들기
all_df["sp_plus_minus"] = all_df["Close"] - all_df["Open"]
all_df["kospi_plus_minus"] = all_df["종가"] - all_df["시가"]
6. 상관 분석
두 데이터 간에 관련이 있는지, 통계적으로 유의미한지를 확인하기 위해 상관 분석을 수행합니다.
해석은 다음과 같이 합니다.
statistic(r) = -1 ~ 1 사이의 값을 가지며, +인 경우, 하나의 데이터가 증가할 때 다른 데이터도 증가함을 의미합니다. -인 경우 하나가 증가할 때 다른 하나는 감소함을 의미합니다. 1이나 -1에 가까울수록 강한 상관, 0에 가까울수록 관련이 없다고 해석합니다.
pvalue = 위의 결과를 통계적으로 유의미하다고 판단하는 기준. 보통 0.05 이하면 유의미하다고 판단합니다.
import scipy.stats as stats
print(f"코스피, S&P500: {stats.pearsonr(all_df["kospi_plus_minus"], all_df["sp_plus_minus"])}")
'''
코스피, S&P500: PearsonRResult(statistic=0.1297019268233488, pvalue=0.38488737209424173)
'''
해석하면 일별 삼성 주식의 증감과 일별 S&P INDEX는 양의 상관을 가지며 약한 상관을 가지고, 이 결과는 통계적으로 유의미하지 않다고 볼 수 있습니다. 쉽게 말해 삼성 주식은 S&P INDEX와 관계가 없다고 보시면 됩니다.
'파이썬' 카테고리의 다른 글
S&P 500 Index를 활용한 KOSPI 기업 주식 분석 및 시뮬레이션-2 (0) | 2024.04.25 |
---|---|
파이썬_파이스파크(pyspark) 활용하기 1. 스팸분류기 (0) | 2018.12.25 |
파이썬_주식데이터를 활용한 회귀 신경망 스터디 4. 회귀 신경망 응용편 (0) | 2018.12.15 |
파이썬_주식데이터를 활용한 회귀 신경망 스터디 3.회귀 신경망 코드 (0) | 2018.12.08 |
파이썬_주식데이터를 활용한 회귀 신경망 스터디 2.회귀분석실습 (1) | 2018.11.28 |