키움 OPEN API 주식 자동화

 

 

이전 글 보러 가기

 

01_시작

02_기본설정

03_pykiwoom vs. 직접코딩

04_키움 open api 로그인 하기

05_키움 OPEN API에 TR 요청하기(feat. 예수금과 계좌잔고 받아오기)

06_키움 KOA 설치하기

07_키움 KOA 이해하기

08_키움 KOA 이해하기_2

09_키움 OPEN API 계좌평가 잔고 가져오기

10_키움 OPEN API 일봉데이터 가져오기_1

 

 

 

이전 글에서 일봉데이터를 가져오기 위한 배경에 대해 학습했다. 이제 코드에 대해 알아보자. 코드 작성을 위한 전반적인 도움은 지난 글에서 설명한 유튜브 "프로그램 동산" 채널을 도움을 받았다.

 

 

먼저 조회할 종목 리스트를 만들어보자. 앞서 살펴본 바와 같이 키움 KOA에서 종목정보 관련 함수인 "GetCodeListByMarket()"를 활용할 수 있다.

 

 

키움 KOA 종목 리스트 만들기(GetCodeListByMarket)

 

GetCodeListByMarket()는 시장 구분 값만 파라미터로 보내주면, 해당 시장의 종목코드를 세미콜론(';)으로 구분하여 보내준다.

 

 

"0 장내"는 거래소에 상장되어 있는 주식과 채권 등을 모두 의미한다. 코스피(KOSPI), 코스닥(KOSDAQ) 등을 모두 포함한다.

 

"10 코스닥"은 미국의 벤처기업으로 구성된 시장인 나스닥을 본떠 만든 시장으로 벤처기업과 유망 중소기업을 위한 시장이다.

 

3 ELW, 8 ETF, 50, KONEX, 4 뮤추얼펀드, 5, 신주인수권, 6, 리츠, 9 하이얼펀드, 30 K-OTC 는 아직 별 관심이 없어서 PASS. 

 

 

from PyQt5.QtTest import *  # 일봉조회 타이머 걸기

# 종목 목록 가져오기
def get_code_list_by_market(self, market_code):
    code_list = self.dynamicCall("GetCodeListByMarket(QString)", market_code)
    code_list = code_list.split(";")[:-1]
    return code_list

# 종목 분석 실행용 함수
def calculator_fnc(self):
    code_list = self.get_code_list_by_market("10") # 10: 코스탁
    print("코스닥 갯수 %s" % len(code_list))

    for idx, code in enumerate(code_list):
        self.dynamicCall("DisconnectRealData(QString)", "4000")  # 스크린 연결 끊기
        print("%s / %s : KOSDAQ Stock Code : %s is updating..." % (idx+1, len(code_list), code))
        self.day_kiwoom_db(code=code)
        
# 일봉 가져오기
def day_kiwoom_db(self, code=None, date=None, sPrevNext="0"):
    QTest.qWait(3600) # 3.6초 delay
    self.dynamicCall("SetInputValue(QString, QString)", "종목코드", code)
    self.dynamicCall("SetInputValue(QString, QString)", "수정주가구분", "1")

# date 빈값은 오늘. None이 아니면 날짜를 입력하도록
    if date != None:
        self.dynamicCall("SetInputValue(QString, QString)", "기준일자", date)
    self.dynamicCall("CommRqData(QString, QString, int, QString)", "주식일봉차트조회", "opt10081", sPrevNext, self.screen_calculation_stock) #TR 서버로 전송
        self.calculator_event_loop.exec_()

 

종목 목록을 가져오기 위한 함수를 "get_code_list_by_market"로 만들고, market_code를 GetCodeListByMarket() 함수로 넘겨준다. 앞서 살펴본 바와 같이 GetCodeListByMarket() 함수는 종목코드를 세미콜론(;)으로 구분하여 넘겨주므로, 세미콜론을 지우기 위해 ".split(";")"을 사용한다. 끝에 [:-1]을 해준 이유는 끝자리에 남아있는 세미콜론을 지워주기 위함이다.

 

"get_code_list_by_market" 함수는 code_list를 return 해 준다.

 

 

calculator_fnc 라는 함수를 만들어서 

1. 위에서 만든 "get_code_list_by_market" 함수에 market_code를 "10"으로 넘겨주고

2. code_list 개수를 프린트하고

3. code_list에서 하나씩 빼와서

4. DisconnectRealData로 스크린 연결을 끊어주고 (이건 안 해도 됨)

5. 진행 상황을 프린트하고

6. 가지고 있는 code_list 하나를 "day_kiwoom_db"로 보내준다.

 

 

"day_kiwoom_db"라는 함수를 만들어서

1. code는 위에서 만든 "calculator_fnc"에서 넘겨받고

2. date는 빈 값으로 두고(빈 값은 오늘을 의미함)

3. sPrevNext는 일단 0으로 설정 (0은 "이전" 버튼을 누르지 않는 것임)

4. Qtest.qwait(3600)으로 이번 조회 후 다음 조회하기까지 3.6초를 기다려 준다. 기다림 없이 조회하면 키움 서버 과부하 방지를 위해 오류를 반환한다.

5. CommRqData로 데이터를 요청한다.

6. calculator_event_loop를 실행해준다.

 

 

 

def trdata_slot(self, sScrNo, sRQName, sTrCode, sRecordName, sPrevNext):


    if sRQName == "주식일봉차트조회":
        code = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, 0, "종목코드")
        code = code.strip()
        print("%s 일봉데이터 요청" % code)

        # 조회된 row 출력
        cnt = self.dynamicCall("GetRepeatCnt(QString, QString)", sTrCode, sRQName)
        print(cnt)

        # 조회 자료 리스트 만들기
        # GetCommDataEx 매소드 사용 검토
        # data = self.dynamicCall("GetCommDataEx(QString, QString)", sTrCode, sRQName)
        # [['', '현재가', ...., '저가', ''] .... ['', '현재가', ...., '저가', '']]
        # [['', '현재가', '거래량', '거래대금', '날짜', '시기', '고가', '저가', '']]
        for i in range(cnt):
            data = []
            current_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "현재가") # 종가
            volume = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래량")
            trading_value = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "거래대금")
            date = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "일자")
            staring_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "시가")
            high_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "고가")
            low_price = self.dynamicCall("GetCommData(QString, QString, int, QString)", sTrCode, sRQName, i, "저가")

			data.append("")
            data.append(current_price.strip())
            data.append(volume.strip())
            data.append(trading_value.strip())
            data.append(date.strip())
            data.append(staring_price.strip())
            data.append(high_price.strip())
            data.append(low_price.strip())
            data.append("")

			self.calcul_data.append(data.copy())

		print(len(self.calcul_data))
        
        
        # 일봉 600일 이상치 가져오기(페이지 넘기기)
        if sPrevNext == "2":
            self.day_kiwoom_db(code=code, sPrevNext=sPrevNext)
        else:
            print("총 일수 %s" % len(self.calcul_data))
            pass_success = False
        
            self.calculator_event_loop.exit()

 

 

trdata_slot 함수로 준비된 데이터를 활용해서 요청한다.

중간중간에 print를 활용해서 진행상황을 출력하도록 해야 오류 생성 시 디버깅이 가능하다.

 

일봉데이터를 요청하면 다음과 같은 리스트 형태로 반환된다.

[['', '현재가', '거래량', '거래대금', '날짜', '시기', '고가', '저가', '']]

 

반환된 값을 하나씩 data 리스트에 담아준다.

 

 

 

일봉을 조회하는 opt10081 TR은 한번 조회 시 600일치의 데이터를 보내준다. 600일 이전의 데이터를 가져오기 위해서는 sPrevNext를 "2"로 넘겨줘야 한다.

 

 

600일 이전의 데이터를 모두 받아왔으면, "calculator_event_loop"를 끊어준다.

 

 

 

파이썬을 학습하며 남기는 블로그입니다.
질문, 지적, 조언은 항상 환영합니다.

 

 

 

2021.01.18. 코리.

 

 

 

키움 OPEN API 일봉데이터 가져오기

 

 

이전 글 보러 가기

 

01_시작

02_기본설정

03_pykiwoom vs. 직접코딩

04_키움 open api 로그인 하기

05_키움 OPEN API에 TR 요청하기(feat. 예수금과 계좌잔고 받아오기)

06_키움 KOA 설치하기

07_키움 KOA 이해하기

08_키움 KOA 이해하기_2

09_키움 OPEN API 계좌평가 잔고 가져오기

 

 

 

이전까지 키움 OPEN API에 대한 기본적인 조회와 기능을 알아봤다면, 이제 데이터를 가져오는 방법이다. 그 시작으로 일봉데이터를 가져오는 방법을 학습한다.

 

 

영웅문 삼성전자 일봉 조회

 

 

영웅문에서 일봉차트를 조회하면 위와 같은 결과를 볼 수 있다. 보기에는 복잡해 보이는 저 차트를 그리는 데이터는 생각보다 간단한다.

 

종목의 시가, 종가, 저가, 고가, 거래량. 5가지 데이터만 있으면 캔들 차트를 그릴 수 있다.

 

 

일봉차트

 

 

시가, 종가, 고가, 저가 데이터로 일봉차트를 그릴 수 있고, 이동평균선(보라색, 파란색, 노란색 선)은 과거 20일, 60일, 120일 등의 평균 가격으로 그릴 수 있다. 

 

즉, 일봉데이터를 가져온다는 말은, 하루의 시가, 종가, 고가, 저가, 거래량 데이터를 가지고 온다는 말이다.

 

 

 

영웅문 일봉 조회, 600일

 

일봉차트를 조회하면 600일치만 가지고 온다. 위 차트에서 마지막 날짜가 2018년이다. 데이터 분석을 위해서는 더 많은 날짜의 데이터가 필요하다.

 

 

영웅문 일봉 조회, 9541일

 

과거 차트 조회 버튼을 계속 눌러주면 600일씩 늘어난다. 삼성전자의 경우, 9541일까지인 1985년까지 조회된다.

코드에서도 과거 자료가 있는 경우, 과거 차트 조회 버튼을 계속 눌러줘야 한다.

 

 

삼성전자 일봉 과거 데이터

 

과거 조회 버튼을 누를수록 화면에 전체 일봉 수(9541)가 늘어나는 것을 확인할 수 있다.

 

그러므로 "09_계좌평가 잔고 가져오기"에서 살펴본 "sPrevNext"를 이번에도 사용해야 한다. 

 

 

 

 

다음으로 조회할 종목의 리스트는 만들어야 한다. 시장 구분별로 장내, 코스닥, ELW, ETF, KONEX 등으로 구분할 수 있으며, 시장 구분에 대한 파라미터와 함께 데이터를 요청할 수 있다.

 

키움 OPEN API - KOA 종목 목록 가져오기 

 

키움 KOA에서 종목정보 관련 함수인 "GetCodeListByMarket()"를 제공한다. 시장 구분 값을 마라메터로 함께 제공하면 된다. 학습에서는 코스닥 구분 값이 10번을 사용한다.

 

 

 

키움 KOA 주식일봉차트조회

 

키움 KOA의 TR목록에서 opt10081번으로 주식 일봉 차트조회 요청을 할 수 있다. 위에서 살펴본 바와 같이, 한 번에 600개 데이터가 조회된다는 안내가 있다.

 

넘겨야 할 파라미터는 "종목코드, 기준일자, 수정주가구분" 3가지이다.

  - 종목코드는 위에서 살펴본 "GetCodeListByMarket()" 함수로 확보한다.

  - 날짜는 오늘을 기준으로 하려면 공란으로 둔다. 

  - 수정주가구분은 0과 1로 구분되는데, 1번이 수정주가구분이다. 삼성전자 주가가 2018년에 약 250만원이었는데, 이를 약 50:1로 액면분할하며 주가가 53,000원이 되었다. 수정주가구분을 0으로 주면 2018년 주가는 250만원, 현재 주가는 9만원으로 조회된다. 액면분할 등을 바로잡아 놓은 주가가 수정주가이다.

 

 

3가지 파라미터를 넘기면 받을 수 있는 데이터는 다음의 15개이다.

 

0. 종목코드

1. 현재가

2. 거래량

3. 거래대금

4. 일자

5. 시가

6. 고가

7. 저가

8. 수정주가구분

9. 수정비율

10. 대업종구분

11. 소업종구분

12. 종목정보

13. 수정주가이벤트

14. 전일종가

 

0~7번까지의 8개 데이터는 제공되는데, 8~14번까지의 7개 데이터는 조회/제공되지 않는다.

 

 

 

일봉데이터 조회 코드를 짜기 위한 기본 내용은 여기까지 이고, 코드는 다음 글에서 소개한다.

 

 

 

파이썬을 학습하며 남기는 블로그입니다.
질문, 지적, 조언은 항상 환영합니다.

 

 

2021.01.14. 코리.

 

 

+ Recent posts