Skip to content

Instantly share code, notes, and snippets.

@mr-yoo
Created November 30, 2021 18:53
Show Gist options
  • Save mr-yoo/aaa0d4e2e32982f86e0f4240f9539617 to your computer and use it in GitHub Desktop.
Save mr-yoo/aaa0d4e2e32982f86e0f4240f9539617 to your computer and use it in GitHub Desktop.
키움증권 코드 구조-2 (싱글톤 버그 있음)
import sys
from enum import Enum
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
class KiwoomBase(metaclass=Singleton):
def __init__(self):
self.ocx = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1")
self.ocx.OnEventConnect.connect(self._handler_login)
self.ocx.dynamicCall("CommConnect()")
self.loop = QEventLoop()
self.loop.exec()
def _handler_login(self, err):
self.loop.exit()
class KiwoomTr(KiwoomBase):
"""Kiwoom TR을 처리하는 Base 클래스
- 해당 클래스를 상속받는 클래스는 반드시 event
"""
def __init__(self):
super().__init__()
def CommRqData(self, rqname, trcode, next, screen):
self.ocx.dynamicCall("CommRqData(QString, QString, int, QString)", rqname, trcode, next, screen)
def SetInputValue(self, id, value):
self.ocx.dynamicCall("SetInputValue(QString, QString)", id, value)
def GetCommData(self, trcode, rqname, index, item):
data = self.ocx.dynamicCall("GetCommData(QString, QString, int, QString)", trcode, rqname, index, item)
return data.strip()
def GetRepeatCnt(self, trcode, rqname):
ret = self.ocx.dynamicCall("GetRepeatCnt(QString, QString)", trcode, rqname)
return ret
class KiwoomTrSingle(KiwoomTr):
def __init__(self, **kwargs):
super().__init__()
self.params = kwargs
self.ocx.OnReceiveTrData.connect(self._handler)
def get(self, reqData=None):
if reqData != None:
self.reqData = reqData
for key, val in self.params.items():
self.SetInputValue(key, val)
cname = self.__class__.__name__
self.CommRqData(cname, cname, 0, cname[-4:])
self.loop = QEventLoop()
self.loop.exec()
return self.__data
def _handler(self, screen, rqname, trcode, record, next):
self.__data = {}
for item in self.reqData:
self.__data[item] = self.GetCommData(trcode, rqname, 0, item)
self.loop.exit()
class KiwoomTrMulti(KiwoomTr):
def __init__(self, **kwargs):
super().__init__()
self.params = kwargs
self.ocx.OnReceiveTrData.connect(self._handler)
def get(self, reqData=None):
if reqData != None:
self.reqData = reqData
for key, val in self.params.items():
self.SetInputValue(key, val)
cname = self.__class__.__name__
self.CommRqData(cname, cname, 0, cname[-4:])
self.loop = QEventLoop()
self.loop.exec()
return self.__data
def _handler(self, screen, rqname, trcode, record, next):
self.__data = []
cnt = self.GetRepeatCnt(trcode, rqname)
for i in range(cnt):
sub = {}
for item in self.reqData :
sub[item] = self.GetCommData(trcode, rqname, i, item)
self.__data.append(sub)
self.loop.exit()
class opt10001(KiwoomTrSingle):
"""주식기본정보요청
Usage:
> r = opt10001(종목코드="005930")
> r.get()
{'PER': '18.56', 'PBR': '1.81'}
> r.get(["결산월", "당기순이익"])
{'결산월': '12', '당기순이익': '264078'}
"""
reqData = ["PER", "PBR"]
def __init__(self, **kwargs):
super().__init__(**kwargs)
class opt10002(KiwoomTrSingle):
"""주식거래원요청
Usage:
> r = opt10011(신주인수구분="00")
> r.get()
[{'종목코드': 'J00004217', '종목명': 'KR모터스 1WR', '현재가': '89'}, {'종목코드': 'J00064217', '종목명': '동아쏘시오홀딩스 2WR', '현재가': '-5950'}, ... ]
"""
reqData = ["종목코드", "종목명", "현재가"]
def __init__(self, **kwargs):
super().__init__(**kwargs)
class opt10011(KiwoomTrMulti):
reqData = ["종목코드", "종목명", "현재가"]
def __init__(self, **kwargs):
super().__init__(**kwargs)
if __name__ == "__main__":
app = QApplication(sys.argv)
r = opt10002(종목코드="005930")
print(r.get())
print(r.get(["결산월", "당기순이익"]))
r = opt10011(신주인수구분="00")
print(r.get())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment