대신증권 CybosPlus API로 코스피, 코스닥 지수 데이터 가져오기

2021. 4. 24. 17:21데이터 분석/주식투자 실험실

728x90

 

 

지난 글에서는 대신증권 CybosPlus API로 코스피, 코스닥 전 종목의 과거 주가정보를 가져오는 코드를 만들었습니다.

 

이번에는 이 코드를 약간만 변형해서 코스피, 코스닥 등 과거 주가지수를 가져오는 코드를 만들어 보겠습니다.

 

 

과거 주가지수 불러오기 위해 변경한 코드는 아래와 같으며, 개별 종목 주가 불러오는 코드와 차이점 위주로만 간단히 설명드립니다.

 

##지수정보 가져오기  (최초 생성)

import win32com.client
import pandas as pd 
import time
import datetime

column_dailychart = ['code', 'section', 'date', 'open', 'high', 'low', 'close']

instStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
nCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")

row = list(range(len(column_dailychart)))
rows = list()

CPE_MARKET_KIND = {'KOSPI':'U001',  'KOSDAQ':'U201'}


instStockChart.SetInputValue(1, ord('1'))
instStockChart.SetInputValue(2, '20140714')
instStockChart.SetInputValue(3, '20140101')
instStockChart.SetInputValue(5, (0, 2, 3, 4, 5))
instStockChart.SetInputValue(6, ord('D'))
instStockChart.SetInputValue(9, ord('1'))


for key, value in CPE_MARKET_KIND.items():

    remain_request_count =  nCpCybos.GetLimitRemainCount(1)
    print(key, value, '남은 요청 : ', remain_request_count)
    
    if remain_request_count == 0:
        print('남은 요청이 모두 소진되었습니다. 잠시 대기합니다.')

        while True:
            time.sleep(2)
            remain_request_count =  nCpCybos.GetLimitRemainCount(1)
            if  remain_request_count > 0:
                print('작업을 재개합니다. (남은 요청 : {0})'.format(remain_request_count))
                break
            print('대기 중...')
            
    instStockChart.SetInputValue(0, value)

    
    # BlockRequest
    instStockChart.BlockRequest()

    # GetHeaderValue
    numData = instStockChart.GetHeaderValue(3)
    numField = instStockChart.GetHeaderValue(1)

    # GetDataValue
    for i in range(numData):
        row[0] =  value
        row[1] = key  # 코스피, 코스닥 여부
        row[2] = instStockChart.GetDataValue(0, i)  # 날짜
        row[3] = instStockChart.GetDataValue(1, i)  # 시가
        row[4] = instStockChart.GetDataValue(2, i)  # 고가
        row[5] = instStockChart.GetDataValue(3, i)  # 저가
        row[6] = instStockChart.GetDataValue(4, i)  # 종가
        rows.append(list(row))   
    
print('데이터를 모두 불러왔습니다.')

dailychart= pd.DataFrame(data = rows, columns= column_dailychart)
dailychart = dailychart.sort_values(['code','date'])
dailychart.to_csv('dailychart_index.csv', index=False)

print('모든 데이터를 저장하였습니다.')

 

 


 

1. 요청 및 저장할 컬럼 변경사항

 

먼저 개별 종목에서 주로 참고하는 지표와 달리 코스피, 코스닥 지수는 좀 더 참조하는 지표가 더 간단합니다.

따라서 저장할 컬럼 리스트인 column_dailychart 중에 필요없는 거래량, 거래대금, 상장주식수, 시가총액, 외국인 보유비율, 기관순매수, 기관누적순매수 항목을 삭제합니다.

 

그리고 요청할 필드항목도 'instStockChart.SetInputValue(5, (0, 2, 3, 4, 5))'와 같이 날짜와 시가, 고가, 저가, 종가 다섯가지만 가져오기 위해 (0, 2, 3, 4, 5)로 수정합니다.

 

마지막으로 row에 데이터를 입력하는 부분 'instStockChart.GetDataValue(0, i)' 에서도 가져오지 않는 항목에 대한 줄들을 삭제합니다.

 

...

column_dailychart = ['code', 'section', 'date', 'open', 'high', 'low', 'close']

...

instStockChart.SetInputValue(5, (0, 2, 3, 4, 5))

...

    for i in range(numData):
        row[0] =  value
        row[1] = key  # 코스피, 코스닥, ETF 여부
        row[2] = instStockChart.GetDataValue(0, i)  # 날짜
        row[3] = instStockChart.GetDataValue(1, i)  # 시가
        row[4] = instStockChart.GetDataValue(2, i)  # 고가
        row[5] = instStockChart.GetDataValue(3, i)  # 저가
        row[6] = instStockChart.GetDataValue(4, i)  # 종가
        rows.append(list(row))   
    
...

 

 


 

2. 반복변수 정의

 

개별종목을 불러올 때는 종목코드가 저장된 파일을 불러와서 for 문의 반복자로 활용했었는데, 코스피, 코스닥 지수도 동일하게 특정 종목코드를 입력하면 동일한 방식으로 주가정보를 가져올 수 있습니다.

 

주가지수에 해당하는 코드는 API 도움말의 'CpSvrNew7221S' 항목에 가면 리스트를 찾아볼 수 있는데요,

KOSPI, KOSDAQ 지수 뿐만 아니라 선물, 옵션 등 지수도 확인할 수 있습니다.

 

여기서 KOSPI 지수의 코드는 'U001', KOSDAQ 지수 코드는 'U201'로 확인됩니다.

 

따라서 KOSPI, KOSDAQ 지수에 대한 코드정보를 저장하는 dictionary 타입 변수, CPE_MARKET_KIND를 정의합니다.

 

 

...

CPE_MARKET_KIND = {'KOSPI':'U001',  'KOSDAQ':'U201'}

...

for key, value in CPE_MARKET_KIND.items():

  ...
            
    instStockChart.SetInputValue(0, value)

...
    
    # GetDataValue
    for i in range(numData):
        row[0] =  value
        row[1] = key  # 코스피, 코스닥 여부
        ...

 

그 다음 CPE_MARKET_KIND 변수를 가지고 for문을 반복하도록 합니다. key와 value를 모두 사용할 예정이므로 CPE_MARKET_KIND.itmes()로 반복하도록 하고,  instStockChart.SetInputValue(0, value)에는 코드를 나타내는 'value'로 수정합니다.

 

또한 전달받은 데이터를 row에 입력하는 부분도 'code' 필드에 해당하는 row[0]에는 value를 저장하고, 'section' 필드에 해당하는 row[1]에는 key를 저장하도록 합니다.

 

최종적으로 dataframe으로 저장된 코스피, 코스닥 지수 정보는 아래와 같습니다.

 

 

 


 

3. 지수정보 업데이트 코드

 

생성된 지수정보 csv파일에 향후 지수정보를 업데이트 할 때 코드는 전 글에서 개별종목 주가정보를 업데이트하는 코드에 위의 수정사항을 동일하게 반영해주면 되며, 수정한 코드는 아래와 같습니다.

 

##지수정보 가져오기  (업데이트)

import win32com.client
import pandas as pd 
import time
import datetime

column_dailychart = ['code', 'section', 'date', 'open', 'high', 'low', 'close']

dailychart_prev = pd.read_csv('dailychart_index.csv')

instStockChart = win32com.client.Dispatch("CpSysDib.StockChart")
nCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")

row = list(range(len(column_dailychart)))
rows = list()

CPE_MARKET_KIND = {'KOSPI':'U001',  'KOSDAQ':'U201'}


instStockChart.SetInputValue(1, ord('1'))
instStockChart.SetInputValue(2, (datetime.datetime.today() - datetime.timedelta(days=1)).strftime("%Y%m%d"))
instStockChart.SetInputValue(3, str(np.max(dailychart['date'])+1))
instStockChart.SetInputValue(5, (0, 2, 3, 4, 5))
instStockChart.SetInputValue(6, ord('D'))
instStockChart.SetInputValue(9, ord('1'))

for key, value in CPE_MARKET_KIND.items():

    remain_request_count =  nCpCybos.GetLimitRemainCount(1)
    print(key, value, '남은 요청 : ', remain_request_count)
    
    if remain_request_count == 0:
        print('남은 요청이 모두 소진되었습니다. 잠시 대기합니다.')

        while True:
            time.sleep(2)
            remain_request_count =  nCpCybos.GetLimitRemainCount(1)
            if  remain_request_count > 0:
                print('작업을 재개합니다. (남은 요청 : {0})'.format(remain_request_count))
                break
            print('대기 중...')
            
    instStockChart.SetInputValue(0, value)

    
    # BlockRequest
    instStockChart.BlockRequest()

    # GetHeaderValue
    numData = instStockChart.GetHeaderValue(3)
    numField = instStockChart.GetHeaderValue(1)

    # GetDataValue
    for i in range(numData):
        row[0] =  value
        row[1] = key  # 코스피, 코스닥 여부
        row[2] = instStockChart.GetDataValue(0, i)  # 날짜
        row[3] = instStockChart.GetDataValue(1, i)  # 시가
        row[4] = instStockChart.GetDataValue(2, i)  # 고가
        row[5] = instStockChart.GetDataValue(3, i)  # 저가
        row[6] = instStockChart.GetDataValue(4, i)  # 종가
        rows.append(list(row))  
    
    
print('데이터를 모두 불러왔습니다.')

dailychart= pd.DataFrame(data = rows, columns= column_dailychart)
dailychart = dailychart.append(dailychart_prev)
dailychart = dailychart.sort_values(by=['code','date'])
dailychart.to_csv('dailychart_index.csv', index=False)

print('모든 데이터를 저장하였습니다.')