대신증권 CybosPlus API로 전체 주식 종목 저장하기 (+API 실행)

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

728x90

 

알고리즘 트레이딩이나 주가 분석을 위해서 가장 먼저 할 일이 주식 종목 리스트와 주가정보를 가져오는 것인데요. 

 

주식 데이터를 가져오는 방법으로 API나 크롤링 등 여러가지 방법이 있고, API는 대신증권, 이베스트투자증권, 키움증권이 있습니다. 한두 종목이나 한 달, 몇 달치의 소량 데이터를 가져올 때는 어떤 API를 사용해도 크게 관계없겠으나, 유가증권 전 종목을 몇 년 치 가져오기 올 때는 여러가지 장애들에 부딪치는데요. 대신증권 CybosPlus API가 가져오는 속도나 데이터 가공 용이성 등 여러가지 측면에서 장점이 있어서 과거 데이터를 대량으로 가져올 때 추천합니다.

 

이번 글에서는 대신증권 CybosPlus API를 활용해서 Python으로 KOSPI, KOSDAQ 전 종목 리스트를 가져오고 CSV 파일로 저장하는 코드를 알아봅니다.

 

 

CybosPlus API의 기본적인 활용 방법은 '파이썬으로 배우는 알고리즘 트레이딩 (개정판)' 또는 같은 책의 인터넷 버전에서 친절하게 설명되어있어서, 저는 이 사이트의 코드를 응용해서 작성하였습니다. 그래서 제가 따로 작성한 부분을 중심으로 설명드리며, 기본적인 API 구조나 명령어는 아래 사이트를 참고하시면 되겠습니다.

 

'파이썬으로 배우는 알고리즘 트레이딩 (개정판)' 인터넷 버전은 아래 위키독스 사이트 메인 화면에서 이 책이 메인에 나와있으니 클릭하면 보실 수 있습니다.

 

wikidocs.net

 

위키독스

온라인 책을 제작 공유하는 플랫폼 서비스

wikidocs.net

 

그리고 CybosPlus API를 사용할 때 함수나 각종 파라미터 정보 확인이 필요한데, 아래의 도움말 사이트에서 정보를 확인할 수 있으니 API를 활용할 때 수시로 참고하면 됩니다.

 

cybosplus.github.io/

 

CybosPlus Help for Python (비공식)

 

cybosplus.github.io

 

마지막으로 코드 개발환경은 아래와 같이 Anaconda로 파이썬을 설치하여 활용하였습니다. CybosPlus API가 요즘 컴퓨터 환경과 맞지 않게 python 32bit 버전만 지원하기 때문에, 32bit와 64bit 버전을 왔다갔다 하기 편리한 아나콘다를 활용합니다.

 

- OS : Windows 10

- 개발환경 : Anaconda 가상 Python 환경 (Anaconda Navigator 활용) 

- 개발도구 : Jupyter Notebook

- Python 버전 : 3.8 (32비트 버전 / 64비트 버전 두 가지)

 

 

 


 

1> 대신증권 가입 및 프로그램 설치

 

대신증권 CybosPlus API를 이용하려면 대신증권에 회원가입을 해야합니다.

매매 기능까지 구현하려면 계좌개설까지 해야하지만, 시세 조회만 하려는 목적이면 모의투자계정으로 가입하면 좀 더 간단하게 가입할 수 있습니다.

 

vt.daishin.com/ds/cybos/info/info.do?m=4102&p=5492&v=4630 

 

대신증권

모의투자란? 당사에서는 트레이딩 시스템(HTS,MTS)을 통하여 실제와 유사한 가상의 트레이딩 환경을 제공합니다. 고객님께서 이론적으로 습득하셨던 부분을 가상의 모의투자 시스템을 통해 투자

vt.daishin.com

가입 후에 모의투자 참가신청을 하시고 상시모의투자를 선택하시면 됩니다.

 

그 다음 아래 다운로드 센터에 들어가서 Cybos 5와 Cybos Plus 두 개를 다운받고 각각 설치합니다.

 

money2.daishin.com/E5/WTS/Customer/GuideTrading/DW_DownloadCenter.aspx?m=1101&p=2669&v=2248

 

 

Cybos 5를 실행하면 아래와 같은 화면이 나타나는데, 상단의 CYBOS plus를 선택하고 모의투자 계정으로 가입한 경우 우측 상단의 '모의투자' 글씨를 선택해서 초록색으로 만든다음, ID, 비번을 입력하고 로그인합니다.

 

로그인한다고 별 다른 화면이 나타나는 것은 아니고 API를 이용할 수 있는 상태가 되었다고 보시면 됩니다.

 

 

 


 

2> 파이썬 실행 (및 주의사항)

 

CybosPlus API를 이용하기 위해서는 파이썬 개발 프로그램(PyCharm, Jupyter Notebook 등)을 관리자 권한으로 실행하고, 32비트 버전 파이썬으로 실행해야 합니다. (중요!)

 

요즘은 대부분 64비트 Python 또는 Anaconda가 설치되어있을텐데, Anaconda 설치했을 시 64비트 버전으로 설치했더라도 32비트 버전의 Python 가상환경을 생성할 수 있으므로, 32비트 Python이나 Anaconda로 재설치할 필요가 없습니다.

 

Anaconda로 32비트 버전 Python 가상환경을 생성하는 방법은 아래 사이트의 글을 참고하여 따라하시면 금방 만들 수 있습니다.

 

baessi.tistory.com/125

 

아나콘다 가상 환경 설정(32bit 환경 설정) 파이참, 주피터에서 사용

파이썬을 사용하면서 64bit 환경에서 32bit를 사용하는 경우가 생깁니다. 오늘은 아나콘다에서 32bit 설치을 하고 사용하는 방법에 대해 설명해드리도록 하겠습니다. Anaconda 32bit 설치 자 기존에 아

baessi.tistory.com

아나콘다 내비게이터(Anaconda Navigator)를 실행하면 아래와 같이 개발환경과 도구를 선택하는 화면이 나오는데,

여기서 상단의 'Applications on' 문구 다음에 있는 리스트 단추를 눌러서 아까 만들었던 32비트 버전 Python 개발환경을 선택합니다. (저의 경우 py38_32 이름으로 만들었습니다.)

 

 

 

잠시 기다린 후 Jupyter Notebook을 선택하면 정상적으로 CybosPlus API를 활용하여 코딩할 수 있습니다.

 


 

3> 전체 종목정보 가져오기

 

KOSPI, KOSDAQ에 상장된 전 종목 데이터를 가져오기 위해서는 전 종목의 리스트를 먼저 가져와야 합니다.

 

먼저 '파이썬으로 배우는 알고리즘 트레이딩' 책에서는 주식 종목을 가져오는 코드가 아래와 같이 작성되어 있습니다.

import win32com.client

instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")
codeList = instCpCodeMgr.GetStockListByMarket(1)

for i, code in enumerate(codeList):
    secondCode = instCpCodeMgr.GetStockSectionKind(code)
    name = instCpCodeMgr.CodeToName(code)
    print(i, code, secondCode, name)

위의 코드는 GetStockListByMarket(1)을 통해 '1'번 파라미터에 해당하는 KOSPI 종목 전체의 리스트를 받아서 for문을 통해 종목 하나씩 화면에 출력하는 내용입니다.

 

여기서 제가 변화를 줄 부분은 다음과 같습니다.

 

1. KOSPI 뿐만 아니라 KOSDAQ 종목도 함께 불러온다.

2. 불러온 종목을 화면에 표시하는 대신 csv 파일로 저장한다.

3. KOSPI 종목 내 편성된 ETF 종목을 별도 유형으로 지정한다.

 

 

먼저 KOSPI 종목과 KOSDAQ 종목을 둘 다 가져오려면 위의 코드를 바로 밑에다가 복사해서 GetStockListByMarket(1)에서 1 대신 2로 바꿔주기만 하면 됩니다. 하지만 똑같은 코드를 복제해서 여러 군데 쓰는 것은 프로그래밍 관점에서 썩 바람직하지 않으므로 위의 for 문에 한 겹 더 for문을 만들어서 KOSPI, KOSDAQ에 대해 두 번 반복하도록 할 생각입니다.

 

#종목정보 가져오기(최초)

import win32com.client
import pandas as pd 

CPE_MARKET_KIND = {'KOSPI':1,  'KOSDAQ':2}

instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")

for key, value in CPE_MARKET_KIND.items():
    codeList = instCpCodeMgr.GetStockListByMarket(value)
    for code in codeList:
        name = instCpCodeMgr.CodeToName(code)
        sectionKind = instCpCodeMgr.GetStockSectionKind(code)

 

앞의 코드에서 두 줄이 추가되었는데, 하나는 KOSPI, KOSDAQ 키워드 별로 해당하는 파라미터 값을 명시해놓은 dictionary 타입의 CPE_MARKET_KIND 변수입니다. 그리고 원래 for 위에 이 CPE_MARKET_KIND 내 항목을 기준으로 반복하도록 for문을 하나 더 추가해줍니다.

 

그리고 원래 GetStockListByMarket(1) 여기에 숫자 1이 들어가 있던 자리를, value라는 변수로 치환해서, 한번은 1이 들어가고 다른 한 번은 2가 들어가서 KOSPI 종목 리스트와 KOSDAQ 종목 리스트를 각각 한 번씩 실행하도록 합니다.

 

rows = list()

for key, value in CPE_MARKET_KIND.items():
    codeList = instCpCodeMgr.GetStockListByMarket(value)
    for code in codeList:
        name = instCpCodeMgr.CodeToName(code)
        sectionKind = instCpCodeMgr.GetStockSectionKind(code)
        row = [code, name, key, sectionKind]
        rows.append(row)

 

다음으로 불러온 종목 정보를 list로 저장하기 위해 row와 row 변수를 추가합니다.

먼저 row에는 하나의 종목에 대해 1) 종목코드, 2) 종목명, 3) KOSPI, KOSDAQ 구분(key), 그리고 4) 종목의 추가 분류코드(sectionKind)를 저장하고, 이것을 rows.append(row)로 빈 리스트인 rows에 for문을 돌면서 하나씩 추가합니다.

 

import pandas as pd

stockitems = pd.DataFrame(data= rows, columns=['code','name', 'section','sectionKind'])
stockitems.loc[stockitems['sectionKind'] == 10, 'section'] =   'ETF'
stockitems.to_csv('stockitems.csv', index=False)

이렇게 코스피, 코스닥 전 종목을 rows에 저장한 다음, pandas 라이브러리의 dataframe 구조로 변환하여 csv로 저장하는 과정입니다. rows를 바로 csv로 저장하는 것도 가능하지만, 이렇게 할 경우 각 컬럼명을 저장할 수 없기 때문에 저는 이번에 개발하는 모든 데이터는 pandas의 데이터프레임 형태로 변환하여 활용할 예정입니다.

 

위 코드의 맨 윗줄을 통해 rows를 ['code', 'name', 'section', 'sectionKind'] 네 개 필드로 이루어진 데이터프레임으로 다시 만들어 stockitems 변수에 저장합니다.

그 다음 앞서 언급한 KOSPI, KOSDAQ 외에 ETF 분류를 별도로 추가하기 위해 두 번째 코드를 작성합니다. 도움말을 보시면 sectionKind가 '10'인 종목은 ETF라고 되어있습니다. 따라서 sectionKind == 10인 종목의 'section' 항목을 'ETF'라고 수정하였습니다. 그리고 마지막 줄을 통해 stockitems.csv 파일로 저장합니다.

 

 

위의 추가 및 변경사항을 반영하여 최종 작성한 코드는 아래와 같습니다.

 

#종목정보 가져오기(최초)

import win32com.client
import pandas as pd 

rows = list()

CPE_MARKET_KIND = {'KOSPI':1,  'KOSDAQ':2}
instCpCodeMgr = win32com.client.Dispatch("CpUtil.CpCodeMgr")

for key, value in CPE_MARKET_KIND.items():
    codeList = instCpCodeMgr.GetStockListByMarket(value)
    for code in codeList:
        name = instCpCodeMgr.CodeToName(code)
        sectionKind = instCpCodeMgr.GetStockSectionKind(code)
        row = [code, name, key, sectionKind]
        rows.append(row)

print('모든 종목을 불러왔습니다')

stockitems = pd.DataFrame(data= rows, columns=['code','name', 'section','sectionKind'])
stockitems.loc[stockitems['sectionKind'] == 10, 'section'] =   'ETF'
stockitems.to_csv('stockitems.csv', index=False)

print('파일을 저장하였습니다.')

 

※ 전 주식종목 리스트 데이터에 대한 유의사항

1. CpUtil.CpCodeMgr의 GetStockListByMarket() 함수는 호출한 시점에서 등록된 모든 종목을 불러오는 기능을 합니다. 예를 들어서 과거에 KOSPI, KOSDAQ 증시에 등록되었다가 상장폐지나 합병 등의 사유로 현재 거래소에 존재하지 않는 종목은 가져올 수 없습니다. 

2. 또한 불러온 종목의 거래소 구분(KOSPI, KOSDAQ 등) 또한 현재시점을 기준으로 가져오기 때문에, 위와 동일한 이유로 과거에는 코스닥 상장사였다가 현재는 코스피로 이전한 종목들(카카오, 네이버, NC소프트 등)은 코스피에서만 조회됩니다. 이 종목들은 과거 최초에는 코스닥에 상장했기 때문에, 과거 데이터에 대해 코스피, 코스닥 시장을 구분하여 분석 또는 트레이딩 테스트를 할 때 이러한 변경내역을 반영하면 좀 더 정확한 결과를 얻을 수 있습니다. (20년간 코스닥→코스피 이전 종목이 45개에 불과하므로 필요시 수동으로 변경이 가능합니다.)