ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [키움API]파이썬 주식 종가정보 불러오기1: 종목코드 목록 입수
    금융퀀트/(퀀트)증권사API활용(키움) 2023. 11. 24. 07:06
    반응형

    종목리스트 입수 함수 확인

    이제 아래 그림 1의 "기간별 종가 데이터 입수" 버튼 기능을 만들어보자.(버튼 이름의 뜻이 명확하지 않아서 바꿨다.) 

    그림1: 작업대상 버튼

    주식 종목의 기간별 종가 데이터 입수 작업은 "주식코드의 입수 및 목록화 -> 기준일자의 주식코드별 종가 데이터 수집 -> 일자를 바꿔가면서 종가 데이터 반복 수집-> DB저장"으로 나눌 수 있다. 먼저 주식코드의 입수 및 목록화부터 진행해 보자. 키움 API 개발 가이드를 보면 아래 그림 2와 같이 GetCodeListByMarket이라는 함수를 써서 주식코드 목록을 받을 수 있다는 것을 확인할 수 있다.

    그림2:  GetCodeListByMarket API함수 안

    여기에서 함수에 패러미터로 "0"을 넣으면 장내, "3"을 넣으면 ELW, "4"를 넣으면 뮤추얼펀드 등이 나오는 방식이다. 

    코스피 종목 리스트 불러오기

    아래 코드와 같이 "btn_dataget"이라는 버튼에 btn_datagetFunc 라는 함수를 연결해 주고, btn_datagetFunc 안에서 키움 API로 종목정보 목록을 요청하는 GetCodeListByMarket이라는 구조로 코드를 짜면 된다.

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QAxContainer import *
    from PyQt5 import uic
    
    #UI파일 연결
    form_class = uic.loadUiType("UI 파일의 경로 입력")[0]
    
    # PyQt5의 QMainWindow 클래스와 UI 폼 클래스를 상속받은 사용자 지정 클래스 정의
    class KiwoomAPIform(QMainWindow, form_class):
        def __init__(self):
        	# 부모 클래스의 초기화 메서드 호출
            super().__init__()
            # UI 폼을 현재 창에 설정
            self.setupUi(self)
            # 창의 제목 설정
            self.setWindowTitle("KiwoomTest")
            
            # 키움 API Active X 호출
            self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
            
            # 로그인 버튼 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_login"이어야 함)
            self.btn_login.clicked.connect(self.btn_loginFunc)
            # 데이터 입수 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_dataget"이어야 함)
            self.btn_dataget.clicked.connect(self.btn_datagetFunc)
        
    	...(생략)...
        # btn_datagetFunc 함수
        def btn_datagetFunc(self):
        	# 아래 GetCodeListByMarket 함수를 호출해서 API로 종목정보 받아옴(패러미터로 "0")
            data = self.GetCodeListByMarket("0")
            # 입수된 데이터가 있으면 상태창에 Success!!, 아니면 Failed 반환
            if data is not None and len(data) > 0:
                self.drawresult("Success!!")
            else:
                self.drawresult("Failed")
            print(data)
     
        # drawresult 함수
        def drawresult(self, data: object):
        	# 화면에서 "txt_result"라는 오브젝트를 찾은 뒤 txt_result로 객체화
            txt_result = self.findChild(QTextEdit, "txt_result")
            # txt_result에 data를 받아서 data를 set 함
            txt_result.setPlainText(str(data))
    	
        ...(생략)...
        
        # GetCodeListByMarket 함수 
        def GetCodeListByMarket(self, mkcode: str):
        	# 키움 API로 종목 정보 입수
            return self.ocx.dynamicCall("GetCodeListByMarket(Qstring)", mkcode)
        
    if __name__ == "__main__":
    	# PyQt5 어플리케이션 생성
        app = QApplication(sys.argv)
        # KiwoomAPIform 클래스의 인스턴스 생성
        window = KiwoomAPIform()
        # 창을 화면에 표시
        window.show()
        # 어플리케이션 실행 및 이벤트 루프 시작
        sys.exit(app.exec_())

     

    위 코드를 실행할 때 주의할 점은 반드시 화면상 로그인 버튼을 통해서 로그인을 한 이후에 데이터를 입수해야 한다는 점이다.( [키움API]python API로그인(Qt Designer 사용) 참조)

    입수된 종목 리스트 가공

    코드를 실행하면 아래 그림 3과 같은 데이터가 print 된다. API 함수를 통해서 종목정보를 받아오면 종목코드를 ";"로 구분해서 하나의 통문자열로 데이터를 뿌려주는 것이다. 이런 데이터로는 n 번째 종목코드를 뽑아낼 수도 없고, 조작도 힘들어서 입수된 데이터를 적어도 List 형식으로는 바꿔주는 작업이 필요하다.

    그림 3: 종목코드 입수 API를 그대로 요청했을 때 결과

    기본적인 방법은 종목코드가 세미콜론(;)을 기준으로 나눠져 있기 때문에 split(";") 함수를 써서 세미콜론(;)을 기준으로 list를 만드는 것이다. 주의할 점은 데이터 마지막이 "900140;" 로(세미콜론으로 끝남) 끝나므로 세미콜론을 기준으로 list를 만들 경우 리스트에 빈 항목이 하나 생기기 때문에 "데이터의 마지막이 공란(if data[-1] == "") 이면 데이터를 마지막 직전항까지로 재정의(data[:-1]) 아니면 그대로 data 갖다 쓰는 조건문"을 추가해 준다. 완성된 코드는 아래와 같다.

    import sys
    from PyQt5.QtWidgets import *
    from PyQt5.QAxContainer import *
    from PyQt5 import uic
    
    #UI파일 연결
    form_class = uic.loadUiType("UI 파일의 경로 입력")[0]
    
    # PyQt5의 QMainWindow 클래스와 UI 폼 클래스를 상속받은 사용자 지정 클래스 정의
    class KiwoomAPIform(QMainWindow, form_class):
        def __init__(self):
        	# 부모 클래스의 초기화 메서드 호출
            super().__init__()
            # UI 폼을 현재 창에 설정
            self.setupUi(self)
            # 창의 제목 설정
            self.setWindowTitle("KiwoomTest")
            
            # 키움 API Active X 호출
            self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
            
            # 로그인 버튼 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_login"이어야 함)
            self.btn_login.clicked.connect(self.btn_loginFunc)
            # 데이터 입수 클릭 시 작동 함수 정의(UI 생성시 오브젝트 명이 "btn_dataget"이어야 함)
            self.btn_dataget.clicked.connect(self.btn_datagetFunc)
        
    	...(생략)...
        # btn_datagetFunc 함수
        def btn_datagetFunc(self):
        	# 아래 GetCodeListByMarket 함수를 호출해서 API로 종목정보 받아옴(패러미터로 "0")
            data = self.GetCodeListByMarket("0")
            # 세미콜론을 기준으로 데이터를 List 형식으로 변경
            data = data.split(";")
            # 마지막항이 비어있으면 직전항까지만 List로 사용하도록 data 를 재정의
            data = data[:-1] if data[-1] == "" else data
            # 입수된 데이터가 있으면 상태창에 Success!!, 아니면 Failed 반환
            if data is not None and len(data) > 0:
                self.drawresult("Success!!")
            else:
                self.drawresult("Failed")
            print(data)
     
        # drawresult 함수
        def drawresult(self, data: object):
        	# 화면에서 "txt_result"라는 오브젝트를 찾은 뒤 txt_result로 객체화
            txt_result = self.findChild(QTextEdit, "txt_result")
            # txt_result에 data를 받아서 data를 set 함
            txt_result.setPlainText(str(data))
    	
        ...(생략)...
        
        # GetCodeListByMarket 함수 
        def GetCodeListByMarket(self, mkcode: str):
        	# 키움 API로 종목 정보 입수
            return self.ocx.dynamicCall("GetCodeListByMarket(Qstring)", mkcode)
        
    if __name__ == "__main__":
    	# PyQt5 어플리케이션 생성
        app = QApplication(sys.argv)
        # KiwoomAPIform 클래스의 인스턴스 생성
        window = KiwoomAPIform()
        # 창을 화면에 표시
        window.show()
        # 어플리케이션 실행 및 이벤트 루프 시작
        sys.exit(app.exec_())

     

    최종적으로 아래와 같이 결과가 출력되면 정상이다.

    그림4: API 요청 결과를 List로 가공한 결

     

    반응형
Designed by Tistory.