본문 바로가기
개발 업무(코딩)-개발자였을때 썼던..

개발 업무..확장가능한 키움 open api(조회성)

by 주용사 2023. 1. 8.
728x90

Kiwoom.py에 추가할 화면 tr을 넣는다. KOA studio로 화면 목록 체크.

Kiwoom.py에 접속정보, 주고받는 함수 등이 담겨있다. https://wikidocs.net/ 참고사이트

10001 화면은 종목코드와 종목명만 받아오지만 확장가능하다.

#################################################################################################

Kiwoom.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
import time
import pandas as pd

TR_REQ_TIME_INTERVAL = 0.2

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

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

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

    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()

    def get_code_list_by_market(self, market):
        code_list = self.dynamicCall("GetCodeListByMarket(QString)", market)
        code_list = code_list.split(';')
        return code_list[:-1]

    def get_master_code_name(self, code):
        code_name = self.dynamicCall("GetMasterCodeName(QString)", code)
        return code_name

    def set_input_value(self, id, value):
        self.dynamicCall("SetInputValue(QString, QString)", id, value)

    def comm_rq_data(self, rqname, trcode, next, screen_no):
        ret = self.dynamicCall("CommRqData(QString, QString, int, QString", rqname, trcode, next, screen_no)
        self.tr_event_loop = QEventLoop()
        self.tr_event_loop.exec_()
        return ret

    def _comm_get_data(self, code, real_type, field_name, index, item_name):
        ret = self.dynamicCall("CommGetData(QString, QString, QString, int, QString", code,
                               real_type, field_name, index, item_name)
        return ret.strip()

    def _get_repeat_cnt(self, trcode, rqname):
        ret = self.dynamicCall("GetRepeatCnt(QString, QString)", trcode, rqname)
        return ret

    def _receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
        if next == '2':
            self.remained_data = True
        else:
            self.remained_data = False

        if rqname == "opt10081_req":
            self._opt10081(rqname, trcode)

        if rqname == "opt10086_req":
            self._opt10086(rqname, trcode)

        if rqname == "opt10001_req":
            self._opt10001(rqname, trcode)

        try:
            self.tr_event_loop.exit()
        except AttributeError:
            pass

    def _opt10081(self, rqname, trcode):
        data_cnt = self._get_repeat_cnt(trcode, rqname)

        for i in range(data_cnt):
            date = self._comm_get_data(trcode, "", rqname, i, "일자")
            open = self._comm_get_data(trcode, "", rqname, i, "시가")
            high = self._comm_get_data(trcode, "", rqname, i, "고가")
            low = self._comm_get_data(trcode, "", rqname, i, "저가")
            close = self._comm_get_data(trcode, "", rqname, i, "현재가")
            volume = self._comm_get_data(trcode, "", rqname, i, "거래량")
            val = self._comm_get_data(trcode, "", rqname, i, "거래대금")

            self.ohlcvv['date'].append(date)
            self.ohlcvv['open'].append(int(open))
            self.ohlcvv['high'].append(int(high))
            self.ohlcvv['low'].append(int(low))
            self.ohlcvv['close'].append(int(close))
            self.ohlcvv['volume'].append(int(volume))
            self.ohlcvv['val'].append(int(val))

    def _opt10086(self, rqname, trcode):
        data_cnt = self._get_repeat_cnt(trcode, rqname)

        for i in range(data_cnt):
            date = self._comm_get_data(trcode, "", rqname, i, "날짜")
            open = self._comm_get_data(trcode, "", rqname, i, "시가")
            high = self._comm_get_data(trcode, "", rqname, i, "고가")
            low = self._comm_get_data(trcode, "", rqname, i, "저가")
            close = self._comm_get_data(trcode, "", rqname, i, "종가")
            volume = self._comm_get_data(trcode, "", rqname, i, "거래량")

            self.day['date'].append(date)
            self.day['open'].append(int(open))
            self.day['high'].append(int(high))
            self.day['low'].append(int(low))
            self.day['close'].append(int(close))
            self.day['volume'].append(int(volume))

    def _opt10001(self, rqname, trcode):
        code = self._comm_get_data(trcode, "", rqname, 0, "종목코드")
        name = self._comm_get_data(trcode, "", rqname, 0, "종목명")

        self.base['code'].append(code)
        self.base['name'].append(name)

#################################################################################################

10001(base).py

import sys
from PyQt5.QtWidgets import *
import Kiwoom
import time
import pandas as pd

TR_REQ_TIME_INTERVAL = 0.2

def get_base(code):
    kiwoom.base = {'code': [], 'name': []}

    #filename = 'C:/Users/changjo/Documents/ki.txt'.format()
    #ff = open(filename, 'a', newline='')

    # opt10001 TR 요청
    kiwoom.set_input_value("종목코드", code)
    kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "1")

    #df = pd.DataFrame(kiwoom.base, columns=['code'], index=kiwoom.base['code'])
    df = pd.DataFrame(kiwoom.base, columns=['code', 'name']
                      , index=kiwoom.base['code'])

    #ff.write(df.to_string())  # 파일로 떨구기
    print(df)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    kiwoom = Kiwoom.Kiwoom()
    kiwoom.comm_connect()
    get_base("005930")
 

################################################################################################

10081(ohlcvv).py

import sys
from PyQt5.QtWidgets import *
import Kiwoom
import time
import pandas as pd

TR_REQ_TIME_INTERVAL = 0.2

def get_ohlcvv(code, start):
    kiwoom.ohlcvv = {'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': [], 'val': []}

    #filename = 'C:/Users/changjo/Documents/ki.txt'.format()
    #ff = open(filename, 'a', newline='')

    # opt10081 TR 요청
    kiwoom.set_input_value("종목코드", code)
    kiwoom.set_input_value("기준일자", start)
    kiwoom.set_input_value("수정주가구분", 1)
    kiwoom.comm_rq_data("opt10081_req", "opt10081", 0, "0101")

    while kiwoom.remained_data == True:
        time.sleep(TR_REQ_TIME_INTERVAL)
        kiwoom.set_input_value("종목코드", code)
        kiwoom.set_input_value("기준일자", start)
        kiwoom.set_input_value("수정주가구분", 1)
        kiwoom.comm_rq_data("opt10081_req", "opt10081", 2, "0101")

    df = pd.DataFrame(kiwoom.ohlcvv, columns=['open', 'high', 'low', 'close', 'volume', 'val'],
                          index=kiwoom.ohlcvv['date'])
    #ff.write(df.to_string())  # 파일로 떨구기
    print(df)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    kiwoom = Kiwoom.Kiwoom()
    kiwoom.comm_connect()
    get_ohlcvv("005930", "20200426")

################################################################################################

10086(day).py <- 일자별데이터에서는 이게 더 많은 정보를 담고있다. 그러나 기간이 짧다.

import sys
from PyQt5.QtWidgets import *
import Kiwoom
import time
import pandas as pd

TR_REQ_TIME_INTERVAL = 0.2

def get_day(code, start):
    kiwoom.day = {'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': []}

    #filename = 'C:/Users/chun/Documents/ki.txt'.format()
    #ff = open(filename, 'a', newline='')

    # opt10086 TR 요청
    kiwoom.set_input_value("종목코드", code)
    kiwoom.set_input_value("조회일자", start)
    kiwoom.set_input_value("표시구분", 1)
    kiwoom.comm_rq_data("opt10086_req", "opt10086", 0, "0101")

    while kiwoom.remained_data == True: #20200427 기준 20120309가 마지막 데이터
        time.sleep(TR_REQ_TIME_INTERVAL)
        kiwoom.set_input_value("종목코드", code)
        kiwoom.set_input_value("조회일자", start)
        kiwoom.set_input_value("표시구분", 1)
        ret = kiwoom.comm_rq_data("opt10086_req", "opt10086", 2, "0101")
        df = pd.DataFrame(kiwoom.day, columns=['open', 'high', 'low', 'close', 'volume'],
                          index=kiwoom.day['date'])
        #if int(kiwoom.day['date']) <= 20200325:
        #    break
        print(df)
        break
        #if ret != 0:
        #    break

    df = pd.DataFrame(kiwoom.day, columns=['open', 'high', 'low', 'close', 'volume'],
                          index=kiwoom.day['date'])
    #ff.write(df.to_string())  # 파일로 떨구기
    print(df)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    kiwoom = Kiwoom.Kiwoom()
    kiwoom.comm_connect()
    get_day("005930", "20200424")
728x90