티스토리 뷰

한국은 미국에 영향을 많이 받습니다. 주식에서도 그럴까요? 미국 주식이 떨어지면 한국 주식도 떨어질까요, 아니면 관련이 없을까요. 그 궁금증을 해결하기 위해 다음과 같은 가설을 설정한 후, 분석을 진행해보았습니다.

 

가설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 파일을 받을 수 있습니다.

 

WSJ화면

 

 

다운받은 결과

 

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와 관계가 없다고 보시면 됩니다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함