관리 메뉴

Storage Gonie

2. [키움증권 API] 종목코드 및 종목명 가져오기 본문

툴 사용법/키움증권 API

2. [키움증권 API] 종목코드 및 종목명 가져오기

Storage Gonie 2019. 8. 2. 00:53
반응형

사용되는 메소드

Open API 개발가이드 문서에 나오는 메소드들 중, 총 3가지를 이용한다.

 

CommConnect : 로그인 윈도우를 실행하며, 성공하든 실패하든 OnEventConnect 이벤트를 발생시킨다.

GetCodeListByMarket : 시장구분에 따른 종목코드들을  ';'로 구분자로 하여 모두 반환한다.

GetMasterCodeName : 종목코드 1개의 종목 한글명을 반환한다.

 

CommConnect 메소드

 

GetCodeListByMarket 메소드

 

GetMasterCodeName 메소드 명세

사용되는 이벤트

OnEventConnect CommConnect 메소드로 로그인창을 호출한 뒤, 로그인 시도를 했을 때 발생되는 이벤트

 

코드설명

1) 키움증권의 OpenAPI 를 사용하려면
      COM 오브젝트를 생성하여 사용하거나,
      COM 오브젝트의 메소드를 상속받아야 한다.
      아래는 각각의 방법에 대한 설명이며, 유저인터페이스를 따로 두고싶지 않은 경우에
      두 번째 방법이 더 좋은 방법이라 생각된다.

 

QAxWidget 클래스의 생성자에 ProgID인 "KHOPENAPI.KHOpenAPICtrl.1" 를 넘겨주어 QAxWidget 객체를 생성하고

   이를 본 클래스의 __init__ 메소드에서 멤버변수로 추가해주는 방법이다.

   이 후 dynamicCall, setControl, OnEventConnect 같은 것들을 사용하기 위해서는 위에서 생성한 객체를 통해
   접근하게 된다. 이에대한 코드는 아래와 같다.

   self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")

 

- 본 클래스를 QAxWidget의 상속을 받아 만들고 QAxWidget 클래스에게서 상속받은 setControl 메소드에

   ProgID인 "KHOPENAPI.KHOpenAPICtrl.1" 를 인자로 주어 상속받은 메소드를 객체 없이 사용할 수 있게 하는 방법.

   이에대한 코드는 아래와 같다.

class Kiwoom(QAxWidget):
    def __init__(self):
        super().__init__()
        self._create_kiwoom_instance()

    def _create_kiwoom_instance(self):
        self.setControl("KHOPENAPI.KHOpenAPICtrl.1")

 

2) 상속받은 OnEventConnect.connect 메소드를 이용하여 로그인 결과 이벤트를 받으면 처리하는 콜백함수를 등록하고,
      로그인창을 띄우고 이벤트 루프를 실행하는 comm_connect 함수를 정의함. 
      이 때 아래의 코드에서 유심히 볼 것이 있는데, 이벤트루프를 사용한 것을 볼 수 있다.

      이벤트 루프를 사용하지 않으면 로그인창을 띄우고 바로 다음 코드를 진행하게 되어
      비동기 방식으로 인해 직관적이지 못한 프로그램의 흐름이 만들어 질 수 있다.

      따라서, 로그인 창을 실행시킬 땐 이벤트 루프를 실행시켜 프로그램의 흐름을 일시적으로 중단시키고
      이벤트만 받아들일 수 있는 상태로 뒀다가 로그인 상태를 확인한 뒤 이벤트 루프를 종료시켜주는 것이다.

class Kiwoom(QAxWidget):
    def __init__(self):
        self._set_signal_slots()

    def _set_signal_slots(self):
        self.OnEventConnect.connect(self._event_connect)

    def comm_connect(self):
        self.dynamicCall("CommConnect()")     # 로그인창 띄우기
        self.login_event_loop = QEventLoop()  # 이벤트 루프 생성
        self.login_event_loop.exec_()         # 프로그램 흐름을 일시중지하고 이벤트만 처리할 수 있는 상태로 만듬

    def _event_connect(self, err_code):
        if err_code == 0:
            print("connected")
        else:
            print("disconnected")

        self.login_event_loop.exit()          # 로그인 창을 띄우면서 만든 이벤트 루프를 종료시킴

 

전체코드

import sys
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *


class Kiwoom(QAxWidget):  # QAxWidget 클래스로부터 dynamicCall, setControl, OnEventConnect 를 상속받음
    def __init__(self):
        super().__init__()
        self._create_kiwoom_instance()  # 키움증권 OpenAPI 를 정상적으로 사용할 수 있도록 처리함
        self._set_signal_slots()        # 이벤트 처리메소드 등록

    def _create_kiwoom_instance(self):
        self.setControl("KHOPENAPI.KHOpenAPICtrl.1")      # 이거 대신 obj = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") 가능

    def _set_signal_slots(self):
        self.OnEventConnect.connect(self._event_connect)  # 콜백함수 등록

    def _event_connect(self, err_code):
        if err_code == 0:
            print("로그인 성공")
        else:
            print("로그인 에러코드 : " + str(err_code))

        self.login_event_loop.exit()

    def comm_connect(self):
        self.dynamicCall("CommConnect()")    # 로그인창 띄우기
        self.login_event_loop = QEventLoop() # 이벤트 루프 생성
        self.login_event_loop.exec_()        # 프로그램 흐름을 일시중지하고 이벤트만 처리할 수 있는 상태로 만듬

    def get_all_codes_names(self):
        ret = self.dynamicCall("GetCodeListByMarket(QString)", ["0"])  # 맨뒤 인자는 시장구분, 모든 코드들을 가져옴
        kospi_code_list = ret.split(';')
        kospi_code_name_list = []

        for code in kospi_code_list:
            name = self.dynamicCall("GetMasterCodeName(QString)", [code])  # 맨뒤는 종목코드, 코드에 따른 종목명을 가져옴
            kospi_code_name_list.append(code + " : " + name)

        for item in kospi_code_name_list:
            print(item)


if __name__ == "__main__":
    '''
    Kiwoom 클래스는 QAxWiget 클래스를 상속받았기 때문에
    Kiwoom 클래스에 대한 인스턴스를 생성하려면 먼저 QApplication 클래스의 인스턴스를 생성해야함
    '''
    app = QApplication(sys.argv)
    kiwoom = Kiwoom()
    kiwoom.comm_connect()
    kiwoom.get_all_codes_names()
    sys.exit(app.exec_())

실행결과

출처 : https://wikidocs.net/5755

 

위키독스

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

wikidocs.net

 

반응형
Comments