Skip to content

Instantly share code, notes, and snippets.

@esstory
Created September 6, 2017 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save esstory/1230f1c6de80b11582a13200a45f31af to your computer and use it in GitHub Desktop.
Save esstory/1230f1c6de80b11582a13200a45f31af to your computer and use it in GitHub Desktop.
PLUS API EX - 파이썬 주식 잔고 조회 및 실시간 현재가 업데이트
import sys
from PyQt5.QtWidgets import *
import win32com.client
# 설명: 주식 계좌잔고 종목(최대 200개)을 가져와 현재가 실시간 조회하는 샘플
# CpEvent: 실시간 현재가 수신 클래스
# CpStockCur : 현재가 실시간 통신 클래스
# Cp6033 : 주식 잔고 조회
# CpMarketEye: 복수 종목 조회 서비스 - 200 종목 현재가를 조회 함.
# CpEvent: 실시간 이벤트 수신 클래스
class CpEvent:
def set_params(self, client):
self.client = client
def OnReceived(self):
code = self.client.GetHeaderValue(0) # 초
name = self.client.GetHeaderValue(1) # 초
timess = self.client.GetHeaderValue(18) # 초
exFlag = self.client.GetHeaderValue(19) # 예상체결 플래그
cprice = self.client.GetHeaderValue(13) # 현재가
diff = self.client.GetHeaderValue(2) # 대비
cVol = self.client.GetHeaderValue(17) # 순간체결수량
vol = self.client.GetHeaderValue(9) # 거래량
if (exFlag == ord('1')): # 동시호가 시간 (예상체결)
print("실시간(예상체결)", name, timess, "*", cprice, "대비", diff, "체결량", cVol, "거래량", vol)
elif (exFlag == ord('2')): # 장중(체결)
print("실시간(장중 체결)", name, timess, cprice, "대비", diff, "체결량", cVol, "거래량", vol)
# CpStockCur: 실시간 현재가 요청 클래스
class CpStockCur:
def Subscribe(self, code):
self.objStockCur = win32com.client.Dispatch("DsCbo1.StockCur")
handler = win32com.client.WithEvents(self.objStockCur, CpEvent)
self.objStockCur.SetInputValue(0, code)
handler.set_params(self.objStockCur)
self.objStockCur.Subscribe()
def Unsubscribe(self):
self.objStockCur.Unsubscribe()
# Cp6033 : 주식 잔고 조회
class Cp6033:
def __init__(self):
# 통신 OBJECT 기본 세팅
self.objTrade = win32com.client.Dispatch("CpTrade.CpTdUtil")
initCheck = self.objTrade.TradeInit(0)
if (initCheck != 0):
print("주문 초기화 실패")
return
# 주식 매수 주문
acc = self.objTrade.AccountNumber[0] # 계좌번호
accFlag = self.objTrade.GoodsList(acc, 1) # 주식상품 구분
print(acc, accFlag[0])
self.objRq = win32com.client.Dispatch("CpTrade.CpTd6033")
self.objRq.SetInputValue(0, acc) # 계좌번호
self.objRq.SetInputValue(1, accFlag[0]) # 상품구분 - 주식 상품 중 첫번째
self.objRq.SetInputValue(2, 50) # 요청 건수(최대 50)
# 실제적인 6033 통신 처리
def rq6033(self, retcode):
self.objRq.BlockRequest()
# 통신 및 통신 에러 처리
rqStatus = self.objRq.GetDibStatus()
rqRet = self.objRq.GetDibMsg1()
print("통신상태", rqStatus, rqRet)
if rqStatus != 0:
return False
cnt = self.objRq.GetHeaderValue(7)
print(cnt)
print("종목코드 종목명 신용구분 체결잔고수량 체결장부단가 평가금액 평가손익")
for i in range(cnt):
code = self.objRq.GetDataValue(12, i) # 종목코드
name = self.objRq.GetDataValue(0, i) # 종목명
retcode.append(code)
if len(retcode) >= 200: # 최대 200 종목만,
break
cashFlag = self.objRq.GetDataValue(1, i) # 신용구분
date = self.objRq.GetDataValue(2, i) # 대출일
amount = self.objRq.GetDataValue(7, i) # 체결잔고수량
buyPrice = self.objRq.GetDataValue(17, i) # 체결장부단가
evalValue = self.objRq.GetDataValue(9, i) # 평가금액(천원미만은 절사 됨)
evalPerc = self.objRq.GetDataValue(11, i) # 평가손익
print(code, name, cashFlag, amount, buyPrice, evalValue, evalPerc)
def Request(self, retCode):
self.rq6033(retCode)
# 연속 데이터 조회 - 200 개까지만.
while self.objRq.Continue:
self.rq6033(retCode)
print(len(retCode))
if len(retCode) >= 200:
break
# for debug
size = len(retCode)
for i in range(size):
print(retCode[i])
return True
# CpMarketEye : 복수종목 현재가 통신 서비스
class CpMarketEye:
def Request(self, codes, rqField):
# 연결 여부 체크
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
bConnect = objCpCybos.IsConnect
if (bConnect == 0):
print("PLUS가 정상적으로 연결되지 않음. ")
return False
# 관심종목 객체 구하기
objRq = win32com.client.Dispatch("CpSysDib.MarketEye")
# 요청 필드 세팅 - 종목코드, 종목명, 시간, 대비부호, 대비, 현재가, 거래량
# rqField = [0,17, 1,2,3,4,10]
objRq.SetInputValue(0, rqField) # 요청 필드
objRq.SetInputValue(1, codes) # 종목코드 or 종목코드 리스트
objRq.BlockRequest()
# 현재가 통신 및 통신 에러 처리
rqStatus = objRq.GetDibStatus()
rqRet = objRq.GetDibMsg1()
print("통신상태", rqStatus, rqRet)
if rqStatus != 0:
return False
cnt = objRq.GetHeaderValue(2)
for i in range(cnt):
rpCode = objRq.GetDataValue(0, i) # 코드
rpName = objRq.GetDataValue(1, i) # 종목명
rpTime= objRq.GetDataValue(2, i) # 시간
rpDiffFlag = objRq.GetDataValue(3, i) # 대비부호
rpDiff = objRq.GetDataValue(4, i) # 대비
rpCur = objRq.GetDataValue(5, i) # 현재가
rpVol = objRq.GetDataValue(6, i) # 거래량
print(rpCode, rpName, rpTime, rpDiffFlag, rpDiff, rpCur, rpVol)
return True
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PLUS API TEST")
self.setGeometry(300, 300, 300, 180)
self.isSB = False
self.objCur = []
btnStart = QPushButton("요청 시작", self)
btnStart.move(20, 20)
btnStart.clicked.connect(self.btnStart_clicked)
btnStop = QPushButton("요청 종료", self)
btnStop.move(20, 70)
btnStop.clicked.connect(self.btnStop_clicked)
btnExit = QPushButton("종료", self)
btnExit.move(20, 120)
btnExit.clicked.connect(self.btnExit_clicked)
def StopSubscribe(self):
if self.isSB:
cnt = len(self.objCur)
for i in range(cnt):
self.objCur[i].Unsubscribe()
print(cnt, "종목 실시간 해지되었음")
self.isSB = False
self.objCur = []
def btnStart_clicked(self):
self.StopSubscribe();
codes = []
obj6033 = Cp6033()
if obj6033.Request(codes) == False:
return
print("잔고 종목 개수:", len(codes))
# 요청 필드 배열 - 종목코드, 시간, 대비부호 대비, 현재가, 거래량, 종목명
rqField = [0, 1, 2, 3, 4, 10, 17] #요청 필드
objMarkeyeye = CpMarketEye()
if (objMarkeyeye.Request(codes, rqField) == False):
exit()
cnt = len(codes)
for i in range(cnt):
self.objCur.append(CpStockCur())
self.objCur[i].Subscribe(codes[i])
print("-------------------")
print(cnt , "종목 실시간 현재가 요청 시작")
self.isSB = True
def btnStop_clicked(self):
self.StopSubscribe()
def btnExit_clicked(self):
self.StopSubscribe()
exit()
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment