본문 바로가기
Quant

키움 API를 통해 분봉 데이터 가져오기 - kiwoom.block_request

by 인천고래 2024. 6. 26.
반응형

안녕하세요. 주식 투자 관련 지식을 공유하는 인천고래입니다.

오늘은 분봉 데이터를 연속적으로 가져오기 위해 꼭 알아야만 하는 block_request() 메서드에 대해 작성하도록 하겠습니다.

 

키움증권에서는 분봉 데이터를 API를 통해서 제공을 하고 있고 1년 치의 데이터를 보유하고 있습니다.

즉, 1년 전의 데이터를 얻을 수 없으니 지속적인 업데이트를 해야 자기만의 주식 데이터를 만들 수 있습니다.

 

그리고 또 하나의 문제점은 Kiwoom API에서는 분봉 데이터를 요청할 때, 특정 기간을 명시적으로 지정하여 데이터를 요청하는 기능을 제공하지 않습니다. 올해의 데이터만 필요해서 2024년 1월 1일부터 2024년 6월 26일까지의 데이터를 요청할 수 없다는 것이죠.

 

대신, Kiwoom API는 최신 데이터부터 과거 데이터까지 순차적으로 블록 단위로 데이터를 제공합니다.

따라서 원하는 기간 동안의 데이터를 얻기 위해서는 반복적으로 데이터를 요청 (block_request) 하면서 수집한 데이터의 날짜를 확인하고, 필요한 데이터만 남기도록 필터링해야 합니다.

 

아래는 기존 코드를 수정하여 특정 기간 동안의 데이터를 요청하고 필터링하는 방법입니다.

# First block request
df_firstblock = kiwoom.block_request(tr,
                                     종목코드=code,
                                     수정주가구분=1,
                                     틱범위=tick_range,
                                     output="주식분봉차트조회",
                                     next=0)

 

block_request 코드 설명

kiwoom.block_request() kiwoom API를 이용하여 첫 번째 블록 데이터를 요청합니다.

  • tr: 은 요청 유형(여기서는 분봉 차트 조회),
  • 종목코드: 주식 코드,
  • 수정주가구분: 수정주가 여부(1: 수정주가),
  • 틱범위: 틱 간격,
  • output: 결과 출력 형식,
  • next: 다음 데이터 요청 여부(0: 첫 요청)를 의미합니다.
  • df_firstblock : 키움 API를 통해서 전달받은 데이터가 데이터프레임 형식으로 저장이 됩니다.

첫 번째 요청을 통해서 자신이 원하는 기간에 대한 데이터가 존재한다면 추가로 호출할 필요없이 전달받은 데이터를 드리븐 하면 됩니다.

 

다만, 요청 1번으로 받은 데이터가 자신이 원하는 기간에 부족한 경우 next=2로 바꿔서 호출을 하면 됩니다.

이 경우 키움 API가 전달할 수 있는 모든 데이터를 블록화하여 while... 데이터가 바닥이 날 때까지 계속 호출 & 전달을 하게 됩니다.

 

아래의 코드를 보겠습니다.

df_remainblock = kiwoom.block_request(tr,
                                      종목코드=code,
                                      수정주가구분=1,
                                      틱범위=tick_range,
                                      output="주식분봉차트조회",
                                      next=2)

 

다른 것이라고는 next=2 만 변경이 된 것입니다.

 

처음 요청을 하고 받은 데이터에 추가로 데이터가 필요한 경우 block_request() 함수를 재 호출해서 사용해야 하고

모든 데이터를 다 받을 필요가 없는 경우라면

전달 받은 데이터 df_remainblock의 데이터를 검사해서 자신이 원하는 데이터가 있는지 확인한 후 데이터가 충족될 경우 while문을 빠져나와서 추가 요청을 하지 않도록 해야 합니다.

        oldest_date_in_block = pd.to_datetime(df_remainblock['체결시간'].min(), format='%Y%m%d%H%M%S')
        if oldest_date_in_block < pd.to_datetime(start_date):
            break

 

전달받은 데이터의 '체결시간'을 체크해서 제일 오래된 데이터가  start_date보다 작은지 체크하고 조건 만족하면  while문을 빠져나오도록 break를 걸었습니다.

 

소스 코드 공유

아래는 전체 코드입니다.

def get_API_minute_data(kiwoom, stock_code, start_date, end_date, tick_range=1):
    tr = "opt10080"
    code = stock_code
    df_list = []

    # First block request
    df_firstblock = kiwoom.block_request(tr,
                                         종목코드=code,
                                         수정주가구분=1,
                                         틱범위=tick_range,
                                         output="주식분봉차트조회",
                                         next=0)
    df_list.append(df_firstblock)

    # Continue requesting while there is more data
    while kiwoom.tr_remained:
        df_remainblock = kiwoom.block_request(tr,
                                              종목코드=code,
                                              수정주가구분=1,
                                              틱범위=tick_range,
                                              output="주식분봉차트조회",
                                              next=2)
        df_list.append(df_remainblock)
        # print("df_remainblock['체결시간'].min()", df_remainblock['체결시간'].min())
        oldest_date_in_block = pd.to_datetime(df_remainblock['체결시간'].min(), format='%Y%m%d%H%M%S')
        if oldest_date_in_block < pd.to_datetime(start_date):
            break

    # Concatenate all data
    df = pd.concat(df_list)
    df.reset_index(drop=True, inplace=True)

    # 한글 컬럼 이름을 영어로 변경
    df.rename(columns={
        '현재가': 'Close',
        '거래량': 'Volume',
        '시가': 'Open',
        '고가': 'High',
        '저가': 'Low',
        '체결시간': 'DateTime'
    }, inplace=True)

    # Clean and preprocess the data
    df['Close'] = df['Close'].apply(lambda x: x.lstrip('-')).astype('float')
    df['Open'] = df['Open'].apply(lambda x: x.lstrip('-')).astype('float')
    df['High'] = df['High'].apply(lambda x: x.lstrip('-')).astype('float')
    df['Low'] = df['Low'].apply(lambda x: x.lstrip('-')).astype('float')
    df['DateTime'] = pd.to_datetime(df['DateTime'], format='%Y%m%d%H%M%S', errors='raise')

    df_all = df.drop(['수정주가구분', '수정비율', '대업종구분', '소업종구분', '종목정보', '수정주가이벤트', '전일종가'], axis=1)

    # Filter by date range
    df_all = df_all[(df_all['DateTime'] >= pd.to_datetime(start_date + ' 09:00:00')) & (
            df_all['DateTime'] <= pd.to_datetime(end_date + ' 15:30:00'))]
    df_all = df_all.sort_values(by='DateTime')

    return df_all

 

 

아래는 해당 함수를 사용한 분봉 데이터를 가져와서 보조지표를 추가하는 전체 코드를 공개한 글이니 어떻게 활용을 하는지 확인해 보시면 좋을 것 같네요.

오늘도 제 글을 읽어주셔서 감사합니다.

 

 

키움API로 분봉 데이터 가져오기 (주식 데이터 수집 및 분석 , python 소스 코드 포함

안녕하세요. 주식 투자 관련 프로그램을 공유하는 인천고래입니다.금일은 일봉 차트가 아닌 분봉 차트 데이터를 키움 API를 이용해서 가져오는 소스 코드를 공유하고자 합니다. 퀀트 투자를 하

i-whale.com

 

 

반응형
-

댓글