AI 탐구노트

주가 정보 가져오기 본문

DIY 테스트

주가 정보 가져오기

42morrow 2024. 9. 21. 10:38

 

지난 번에 종목 별 주가 현황표를 만들어 봤습니다.

당시 데이터를 외부에서 Json 타입으로 생성해서 입력으로 전달하는 것으로 가정했었죠.

그래서, 이번에는 주가 정보를 가져와서 전처리를 하는 과정을 테스트해 보기로 했습니다.

 

사용 용도 결정

주가 정보는 용도에 따라 굉장히 스펙트럼이 넓은 녀석이라 먼저 어떤 용도로 사용할 것인지를 결정해야 합니다. 

그래서 저는 다음과 같은 사용 용도를 설정해 봤습니다. 

 

  • 1차 : 종목별 당일 주가 정보 리스트 생성 
  • 2차 : 시가총액을 추가해 finviz 의 S&P 500 map 유사 도구 생성 

 

먼저 간 선배들의 발자취를  좇아보자

 

주가 정보를 가져올 수 있는 방법을 조사해보니 python으로 주가 정보를 처리하는 방법은 다음과 같이 몇 가지가 있었습니다. 

역시 인터넷은 정보의 바다로군요... ^^

  • KRX 사이트에서 데이터(CSV 타입) 파일 저장 후 로딩하는 방식
  • Yahoo Finance 패키지 이용
  • PyKrx 패키지 이용
  • FinanceDataReader 패키지 이용
  • KRX, Naver 등의 API 혹은 사이트 내 정보 크롤링 
  • 증권사의 Open API를 이용하는 방식
  • 기타 등등

 

필요로 하는 데이터는 KRX 사이트에서 쉽게 구할 수 있는 것 같았습니다. 

아래 그림처럼 사이트 접속해서 조회하고자 하는 날짜를 선택하고 파일 (xls, csv 타입)로 저장하면 되는거죠.

 

사진 : KRX (한국거래소) 홈페이지 상의 주식 전종목 시세 정보

 

 

하지만, 이 작업은 수작업으로 진행해야 한다는 것이 문제입니다.

BeautifulSoap 패키지를 이용해서 하는 방법이 있을 것 같긴 한데...

그건 또 공부해야 하고 시행착오도 있을테니 다음 기회로 미루고 저는 다른 방법을 찾기로 했습니다. 

 

FinanceDataReader는 아무래도 데이터의 업데이트 관련 이슈가 있는 것 같아서 제외했고

KRX, Naver 등의 API 혹은 사이트 내 정보 크롤링, 증권사들의 Open API를 이용하는 방식 등은 수행해야 하는 일이 너무 많아질 것 같아서 패스... 

Yahoo Finance 패키지를 이용하는 것은 단순히 주가 외의 다양한 정보를 가져와서 쓸 수 있다는 측면은 좋아보였습니다.

다만, ticker 이름(종목명)을 가져오는 부분이 없어서 불편해서 이 방식도 일단은 패스했습니다.

 

최종적으로 선택한 것은  Pykrx 패키지를 이용하는 방법입니다. 

참고로 구글 검색에서 'python, 주가 정보' 로 검색어를 넣으면 가장 많이 나오는 적용 사례들도  Pykrx 패키지를 이용하고 있습니다. 

 

 

종목 코드와 종목명을 가져와 보자

 

제일 먼저 종목코드와 종목명의 세트를 생성해 봐야겠습니다.

PyKrx github에 보면 이 모듈은 Naver, KRX 주가정보를 스크래핑하므로 API의 무분별한 호출을 자제해 달라고 되어 있습니다.

 

그래서, 반복해서 사용될 정보는 읽어와서 CSV 파일로 저장해두고 이를 로딩하는 방식으로 접근합니다.

 

import datetime
import pandas as pd
from pykrx import stock

def get_korean_stock_list():
    date = datetime.datetime.now().strftime("%Y%m%d")
    df_kor_tickers = pd.DataFrame()

    try:
    	# tickers = stock.get_market_ticker_list(date, market='ALL') # KOSPI, KOSDAQ, KONEX 다 가져올 때
        ticker_list = stock.get_index_portfolio_deposit_file('5300')  # KRX 300에 속한 기업만 가져올 때

        for ticker in ticker_list:
            corp_name = stock.get_market_ticker_name(ticker)
            df = pd.DataFrame({'종목코드':ticker,
                            '종목명':corp_name,
                            '시장코드': 'krx300'
                            }, index = [0])
            df_kor_tickers = pd.concat([df_kor_tickers,df])
        df_kor_tickers = df_kor_tickers.reset_index(drop = True)
        df_kor_tickers.head()
        return df_kor_tickers
    except Exception as e:
        return None

if __name__ == "__main__":
    stock_list = get_korean_stock_list()
    
    if stock_list is not None:
        stock_list.to_csv('krx_stock_list.csv', index=False, encoding='utf-8')

 

 

위의 코드는 종목코드와 종목명을 가져와서 krx_stock_list.csv 파일로 저장합니다.

KRX 300 인덱스 코드인 '5300'을 이용해 KRX 300 기업들의 것만 가져오는 것으로 했습니다. 

 

사진 : 저장된 CSV 파일 예시

 

 

일 별 거래 정보를 가져와 보자

 

위에서 종목코드와 종목명을 가져왔으니 오늘 날짜의 종목별 주가 정보를 가져와서 둘을 합치도록 합니다.

 

종목코드, 종목명, 시장코드가 저장된 파일은 위의 CSV 파일에서 읽어오고, 

당일 주가 정보는 stock.get_market_ohlcv()에서 가져옵니다. 

KRX 300에는 KOSPI, KOSDAQ 기업들이 함께 들어 있기 때문에 일단 market='ALL'로 해서 다 가져온 다음,

csv 파일 상의 종목코드와 매칭되는 것만 머지하는 방식으로 진행할 계획입니다. 

 

from pykrx import stock
from datetime import datetime
import pandas as pd
from pathlib import Path

date = datetime.today().strftime('%Y%m%d')

# KRX 기업 정보 목록 [종목코드/종목명/시장코드]
csv_filename='krx_stock_list.csv'
df_stock_list = pd.read_csv(csv_filename, encoding='utf-8-sig',dtype={'종목코드': str})

# '종목코드'가 6자리 문자열이 되도록 앞에 0을 채움
df_stock_list['종목코드'] = df_stock_list['종목코드'].str.zfill(6)


# 당일 주가 정보 [종목코드/시가/고가/저가/종가/거래량/등락률/거래일자]
df_market_ohlcv = stock.get_market_ohlcv(date, market='ALL').reset_index()
df_market_ohlcv['거래일자'] = date
df_market_ohlcv.rename(columns={'티커':'종목코드'},inplace=True)

# '종목코드'를 문자열로 변환하고 6자리로 맞춤
df_market_ohlcv['종목코드'] = df_market_ohlcv['종목코드'].astype(str).str.zfill(6)


# '종목명'을 df_market_ohlcv에 매핑하여 추가하기
df_market_ohlcv['종목명'] = df_market_ohlcv['종목코드'].map(df_stock_list.set_index('종목코드')['종목명'])
print(df_market_ohlcv.head())

# '종목명'을 df_market_ohlcv에 추가하기 위해 df_stock_list와 병합
df_market_ohlcv = pd.merge(df_stock_list,df_market_ohlcv)
print(df_market_ohlcv.head())

# CSV 파일로 저장
df_market_ohlcv.to_csv('krx_stock_daily.csv', index=False, encoding='utf-8-sig')

 

 

실행 결과는 다음과 같습니다. 흠... 예상대로 나오긴 했네요.

   종목코드       종목명    시장코드       시가  ...       거래량           거래대금   등락률      거래일자
0  005930      삼성전자  krx300    63800  ...  32607829  2077511542788 -0.16  20240920
1  000660    SK하이닉스  krx300   160500  ...   7120720  1125813990164  2.81  20240920
2  373220  LG에너지솔루션  krx300   398500  ...    466822   186263823000  0.51  20240920
3  207940  삼성바이오로직스  krx300  1047000  ...    151659   159534054750  1.05  20240920
4  005380       현대차  krx300   250000  ...    808379   201799907000  1.83  20240920

 

 

오늘은 여기까지...  다음 번에는 이 정보를 이용해 KRX 300 맵을 생성해 봐야겠습니다.