-
[Data] 파이썬을 이용한 주가 데이터 수집하기개발 이야기/TIL 2024. 7. 23. 18:51
들어가기에 앞서
주가 데이터를 수집할 때, 중요한 것은 여러 금융 이벤트들에 의해 주가가 변화 가능하다는 것이다.
실제 시장에서는 중간에 상장 폐지되거나, 합병이 되거나, 주식 분할이 일어나는 등 다양한 이벤트가 있어서 잘 정제된 데이터를 모으는 것은 백테스팅의 성과를 측정하는데 매우 중요한 지표이다.
이번 여름에 Index tracking을 주제로 연구를 진행하고 있는데 이를 위한 자료를 모으는데 정말 엄청난 우여곡절이 많았다(도서관가서 유료데이터 신청하고 뽑아오고 기타 등등, 상장과 지수편입에는 차이가 있음). 이번에는 그런 금융이벤트들을 최대한 반영하는 방법을 위주로 작성하였지만 다소 부족하거나 틀린 내용이 있을 수 있으니 언제든지 알려주시면 매우 감사..!하겠으며 동시에 차후에 알게된 내용이 있으면 추가할 예정이다.
추가로 참고자료 [1]의 흐름에 맞추어 (1)종목 리스트 조회, (2)상장 종목의 주가 데이터 조회, (3)상장폐지 종목의 주가 데이터 조회를 기준으로 작성하였다.
1. 데이터 수집 패키지
대다수 내가 보았던 금융계열 논문에서는 yahoo finance 데이터를 대다수 사용하였지만, 추가로 알아본 결과 4가지 파이썬 패키지를 주로 이용하는 것 같다.
import FinanceDataReader as fdr from pykrx import stock import pandas_datareader.data as pdr import yfinance as yf
2. 종목 리스트 조회
실제 주가 데이터를 수집할 때 가장 많이 간과하는 부분이 바로 상장폐지이다.
현재 시점에서는 어떤 주식이 상장폐지되었는지 알지만(혹은 관련 데이터를 얻을 수 없어 자연스럽게 반영이 안되지만) 실제 정확히 내용을 반영하기 위해서는 관련 내용을 포함해야한다.
종목리스트 조회는 어떤 종목이 어떤 시점에서 상장 폐지되었는지를 알려주는 기능이다.
특정 시점에 어떤 종목이 존재했는지는 정제된 데이터가 없지만(하나씩 찾아서 스스로 노가다를 뛰면 모으는게 가능하거나 유료 서비스의 경우 가능하다, 이번 진행한 연구에서는 두 방법을 모두 사용하였다)
FinanceDataReader는 현재 시점에서 가장 가까운 영업일 기준의 상장종목과 상장폐지 종목 리스트 조회 기능을 제공하고 있고, pykrx는 특정일자의 상장종목 리스트 조회 기능을 제공하고 있다.
2.1 FinanceDataReader
현재 시점의 시장별 상장종목 리스트를 가져올 수 있으며, 과거 특정 시점의 상장 종목 리스트는 알 수 없으나 상장폐지 종목을 알 수 있음
# 가장 최근 영업일의 시장별 종목리스트를 가져옴 stocks = fdr.StockListing('KRX') # 코스피, 코스닥, 코넥스 전체 stocks
상장 폐지 종목 조회
# KRX stock delisting symbol list 상장폐지 종목 전체 리스트 krx_delisting = fdr.StockListing('KRX-DELISTING') krx_delisting
2.2 pykrx
특정 시점의 상장 종목코드 조회 가능..!
해당 종목코드의 종목명을 조회하는 함수가 별도로 존재
# 날짜를 명시해주지 않으면 가장 최근 영업일의 시장별 종목리스트를 가져옴 # 시장을 명시하지 않으면 KOSPI 조회 tickers = stock.get_market_ticker_list("20190225", market="KOSDAQ") tickers[:6], tickers[-6:] (['095570', '006840', '027410', '282330', '138930', '001460'], ['005010', '069260', '000540', '000547', '000545', '003280']) tickers = stock.get_market_ticker_list('2010-01-01') tickers[:6], tickers[-6:] (['004560', '004565', '001460', '001465', '084680', '001040'], ['005010', '069260', '000540', '000547', '000545', '003280'])
어라라.. 참고로 블로그 주인은 http://data.krx.co.kr/contents/MDC/MDI/mdiLoader/index.cmd?menuId=MDC0201010106 Krx에서 하나하나 조회했다...ㅎㅎㅎ
3. 상장 종목의 주가 데이터 조회
주가, 즉 주식의 가격은 보통 OHLCV 즉 시가/고가/저가/종가/거래량을 대다수 제공한다. 또한 앞서 말한 액면분할 등을 고려한 수정주가의 경우 수정종가로 제공하는 경우가 많으나 거래량의 경우 보정되지 않은 경우가 있다.
또한 수정주가의 계산식이 패키지나 옵션별로 차이가 나는 경우가 있으니 필요에 따라 잘 조정해야한다.
참고한 자료에서도 삼성전자(005930)의 예시를 들었고, 가장 대표적인 한국 주식이며 2018년 5월 4일 1:50의 액면분할을 했기 때문에 동일한 예시를 사용했다.
모든 데이터는 조회시점에 따라 조회할 수 있는 최대 과거 시점이 다르다.
3.1. FinanceDataReader
- 조회 시점에 따라 조회할 수 있는 최대 과거가 변동
- 액면분할을 고려한 수정주가 조회
start_date = '1975-06-11' end_date = '2022-03-23' df_fdr = fdr.DataReader('005930', start=start_date, end=end_date) df_fdr
3.2. pykrx
- 1990년 데이터부터 조회 가능
- 수정주가가 디폴트로 조회됨(adjusted 옵션으로 수정주가 여부 설정가능)
- adjusted=False로 조회하면 1995-05-02부터 조회되고, 거래대금과 등락률 칼럼이 추가됨
- 액면분할을 반영한 수정주가가 조회되는데 거래량은 보정되지 않은 상태임
df_pykrx = stock.get_market_ohlcv_by_date(fromdate=start_date, todate=end_date, ticker="005930") df_pykrx
3.3 pandas_datareader
- 데이터소스를 naver로 지정하면 1990년 데이터부터 조회할 수 있고, yahoo로 지정하면 2000년 데이터부터 조회할 수 있음
- 액면분할이 고려된 수정주가로 조회됨
df_pdr = pdr.DataReader('005930', 'naver', start=start_date, end=end_date) df_pdr
- yahoo finance를 데이터소스로 사용할 때는 종목코드 뒤에 코스피 종목인 경우 .KS, 코스닥 종목인 경우 .KQ를 붙여줘야 함
# yahoo finance를 데이터 소스로 사용할 때는 종목코드 뒤에 코스피 종목인 경우 .KS, 코스닥 종목인 경우 .KQ를 붙여줘야 함 df_pdr = pdr.DataReader('005930.KS', 'yahoo', start=start_date, end=end_date) df_pdr
3.4. yfinance
- yahoo finance를 데이터 소스로 사용하는 패키지이기 때문에 위에서 설명한 바와 같이 코스피 종목에는 .KS, 코스닥 종목에는 .KQ를 붙여줘야 함
- 가장 다양한 정보 확인 가능 - 배당정보, 분할정보, 재무정보 등
- 2000년 데이터부터 조회 가능
- end에 설정한 일자의 전일자까지 조회되기 때문에 조회하고자 하는 종료일+1일을 end에 넣어줘야함
- 분단위 데이터도 조회 가능하지만 조회 가능한 기간에 제한이 있음
ticker = yf.Ticker('005930.KS') ticker.history( interval='1d', start=start_date, end='2022-03-24', actions=True, auto_adjust=True)
4. 상장폐지 종목의 주가 데이터 조회
상장폐지 종목의 주가 조회는 FinanceDataReader, pykrx, pandas_datareader에서 데이터 소스를 naver로 설정했을 때만 가능
001047 코드에 관한 각 패키지의 예시코드는 아래와 같음
4.1 FiancneDataReader
krx_delisting[krx_delisting.Symbol=='001047']
4.2 pykrx
stock.get_market_ohlcv_by_date(fromdate=start_date, todate=end_date, ticker="001047")
4.3. pandas_datareader
df_pdr = pdr.DataReader('001047', 'naver', start=start_date, end=end_date) df_pdr
추가적으로 krx나 naver를 데이터 소스로 사용하는 경우에는 거래량이 액면분할을 고려하지 않은 상태로 조회되고, yahoo finance를 데이터 소스로 사용하는 경우에는 거래량이 액면분할을 고려한 상태로 조회된다고 한다.
5. 그래서 어떻게 사용? - My case
우선 액면분할을 고려하여 반영하기 위해 수정종가를 사용했고, 또한 중간에 상장폐지된 종목들에 관해서는 따로 NA를 확인하여 naver를 소스로 변경하여 사용하였다.
기본적으로 yahoo finance 패키지를 이용하되 뒤에 상장폐지된 경우 pandas_datareader를 이용하여 조회하였다.
추가적으로 지수편입에 관한 자료들은 따로 유료 서비스를 이용하여 정제하였고, KOSPI의 경우는 해당 기간안에 존재한 모든 주식 코드를 set처리한뒤에 이후 NA처리하는 식으로 적용하였다.
참고 자료
[1] https://psystat.tistory.com/151 파이썬을 이용한 한국주식(코스피, 코스닥) 주가 데이터 수집 - FinanceDataReader, pykrx, pandas_datareader, yfinance 비교
'개발 이야기 > TIL' 카테고리의 다른 글
[TIL][Conda] conda 환경세팅 yml (1) 2024.09.30 [Gurobi] 최적화 프로그램 gruobi academic license 다운로드(학생판) (0) 2024.07.25 [Finance&OR&ML] 금융 및 최적화 관련 참고할 학술지 (0) 2024.07.03 [Error] sh syntax error: unexpected end of file (0) 2024.04.26 [Error] github에 공개된 모델을 돌려보는 법(sh, window multi process error) (0) 2024.04.25