본문 바로가기
퀀트 분석/트레이딩 시스템 개발

파이썬 주식 트레이딩 시스템 (2) - 일별 주가 데이터 조회

by 쿼카퀀트 2024. 2. 4.
728x90

 

이번엔 발급받은 API키와 토큰으로 삼성전자의 과거 일별 데이터를 받아오겠습니다.

 

1. 전달 데이터 구조

먼저, 증권사 서버에 우리가 필요로 하는 데이터가 어떤건지 알려줘야겠죠?

우리는 주식 시세를 받아올 예정이므로, 관련 호출인 KIS Developers의 '국내주식시세 - 주식현재가 시세' 설명서에 들어갑니다.

설명서에는 입력해야하는 Headers, Params가 적혀져 있습니다. 아래 스크린샷과 같네요. 전달해야하는 값이 많아보이지만 겁먹지 마세요 어떻게 입력해야하는지 다 알려드릴게요ㅎㅎ

 

먼저 Headers는 모든 호출에서 거의 동일한 구조니까, 한번 만들어두고 계속 돌려쓰면 됩니다. 다음으로 Query Parameter는 각 호출 종류(주문, 시세조회 등)에 따라 필요로 하는 데이터를 입력해줍니다.

 

headers 값은 아래 get_header 함수로 만듭니다(앞으로도 많이 사용할 함수니 저장해두세요).

파라미터인 tr_id는 호출 종류에 따라 KIS Developers 홈페이지에서 대응되는 값을 찾아야 합니다. 홈페이지에서 원하는 호출을 찾으면, 아래 스크린샷처럼 'Headers - tr_id'에 필요한 tr_id 값이 있습니다.

 

이렇게 tr_id값을 찾았다면, 그 외 필요한 값은 간단합니다. api_key, secret_key는 증권사에서 발급받은 키를 입력하구요, access_token은 앞선 포스팅에서 발급받은 토큰을 입력합니다.

def get_header(tr_id):
    headers = {"content-type":"application/json",
            "appkey":api_key, 
            "appsecret":secret_key,
            "authorization":f"Bearer {access_token}",
            "tr_id":tr_id,
            }
    return headers

 

 

2. 데이터 수신

이제 과거 주가 데이터를 받아옵니다.

먼저, 파라미터를 설정합니다. 각 파라미터 설명은 아래 코드 주석에 적어두었습니다.

get_header에는 '주식현재가 시세' 호출에 맞는 tr_id를 찾아 입력해줍니다(FHKST03010100 입니다).

import requests
import pandas as pd
import json

base_url = 'https://openapi.koreainvestment.com:9443'

# 파라미터 설정 
ticker = '005930' # 삼성전자 티커
api_starttime = '00000101' # 0000년 1월 1일부터
api_endtime = '99991231' # 9999년 12월 31일까지의 데이터
api_freq = 'D' # 일봉
api_adj_price = True # 수정주가로 받아오기

# headers, params 제작
headers = get_header('FHKST03010100')
params = {
        "fid_cond_mrkt_div_code":"J",
        "fid_input_iscd": ticker,
        "fid_input_date_1":api_starttime,
        "fid_input_date_2":api_endtime,
        "fid_period_div_code":api_freq,
        "fid_org_adj_prc":0 if api_adj_price else 1,
        }
        
# 데이터 수신 및 정제
url = base_url + '/uapi/domestic-stock/v1/quotations/inquire-daily-itemchartprice'
temp = requests.get(url, headers=headers, params=params).json()['output2'][::-1]
temp = pd.DataFrame(temp)
temp = temp.rename(columns={'stck_bsop_date':'timestamp','stck_clpr':'close','stck_oprc':'open','stck_hgpr':'high','stck_lwpr':'low','acml_vol':'volume'})
temp[['close','open','high','low','volume']] = temp[['close','open','high','low','volume']].astype(float)

 

마지막에서 네번째 줄 requests.get()으로 데이터를 불러오면, output2에 주가 데이터가 리스트로 저장되어 있습니다. 저는 개인적으로 최신 데이터가 아래쪽 row에 있는걸 선호해, [::-1]로 리스트의 순서를 바꿔줬습니다.

다음줄에서 이를 DataFrame으로 만들고, ohlcv와 날짜값을 찾아 이름을 변경해줍니다.

마지막으로, ohlcv값을 float타입으로 바꿔줍니다.

 

이렇게 하면 temp 값에는 아래처럼 주가 데이터가 저장됩니다.

 

제 경우 최신 일자(2024년 2월 2일)부터 과거 100영업일의 데이터가 입력되었습니다.

 

 

3. 마무리

자, 이렇게 과거 데이터를 수신하는 방법을 배워봤는데요, 이 방식의 치명적인 단점이 한 가지 있어 마지막으로 이를 알려드리고자 합니다. 이 방법은 한국투자증권 api를 호출하는 것이기 때문에, 콜 횟수 제한이 있습니다. 때문에 속도 제한이 생길 수밖에 없습니다. 전종목 데이터를 불러올 땐 이게 큰 문제가 되겠죠.

 

따라서, FinanceDataReader, 라던지 네이버 증권, 혹은 pykrx의 api를 사용해 과거 데이터를 불러오는게 더 자주 사용됩니다(다만, 시세가 지연되기에 지금 당장의 주가를 가져오기엔 적합하진 않습니다).

 

다음 시간엔 이들 소스를 활용해 과거 데이터를 불러오는 방법을 추가로 배워보도록 하겠습니다.

728x90

댓글