들어가며
이번 예제에서는 PyQt5를 사용하여 윈도우UI를 구성하여 프로그램을 실행한다. 내가 이 블로그에 글을 쓰기 시작하며 생각했던 주식 매매 프로그램은 PC가 서버 역할을 해 자동으로 주식을 매매/매수하고 모바일로 거래내역에 대한 알림을 받는 형태의 모델이었기 때문에 윈도우UI는 사용할 일이 없다. 따라서 본 예제에서 PyQt5 관련 사항은 분석하지 않기로 한다.
코드
import sys
from PyQt5.QtWidgets import *
import win32com.client
class CpEvent:
instance = None
def OnReceived(self):
# time = CpEvent.instance.GetHeaderValue(3) # 시간
timess = CpEvent.instance.GetHeaderValue(18) # 초
exFlag = CpEvent.instance.GetHeaderValue(19) # 예상체결 플래그
cprice = CpEvent.instance.GetHeaderValue(13) # 현재가
diff = CpEvent.instance.GetHeaderValue(2) # 대비
cVol = CpEvent.instance.GetHeaderValue(17) # 순간체결수량
vol = CpEvent.instance.GetHeaderValue(9) # 거래량
if (exFlag == ord('1')): # 동시호가 시간 (예상체결)
print("실시간(예상체결)", timess, "*", cprice, "대비", diff, "체결량", cVol, "거래량", vol)
elif (exFlag == ord('2')): # 장중(체결)
print("실시간(장중 체결)", timess, cprice, "대비", diff, "체결량", cVol, "거래량", vol)
class CpStockCur:
def Subscribe(self, code):
self.objStockCur = win32com.client.Dispatch("DsCbo1.StockCur")
win32com.client.WithEvents(self.objStockCur, CpEvent)
self.objStockCur.SetInputValue(0, code)
CpEvent.instance = self.objStockCur
self.objStockCur.Subscribe()
def Unsubscribe(self):
self.objStockCur.Unsubscribe()
class CpStockMst:
def Request(self, code):
# 연결 여부 체크
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
bConnect = objCpCybos.IsConnect
if (bConnect == 0):
print("PLUS가 정상적으로 연결되지 않음. ")
return False
# 현재가 객체 구하기
objStockMst = win32com.client.Dispatch("DsCbo1.StockMst")
objStockMst.SetInputValue(0, code) # 종목 코드 - 삼성전자
objStockMst.BlockRequest()
# 현재가 통신 및 통신 에러 처리
rqStatus = objStockMst.GetDibStatus()
rqRet = objStockMst.GetDibMsg1()
print("통신상태", rqStatus, rqRet)
if rqStatus != 0:
return False
# 현재가 정보 조회
code = objStockMst.GetHeaderValue(0) # 종목코드
name = objStockMst.GetHeaderValue(1) # 종목명
time = objStockMst.GetHeaderValue(4) # 시간
cprice = objStockMst.GetHeaderValue(11) # 종가
diff = objStockMst.GetHeaderValue(12) # 대비
open = objStockMst.GetHeaderValue(13) # 시가
high = objStockMst.GetHeaderValue(14) # 고가
low = objStockMst.GetHeaderValue(15) # 저가
offer = objStockMst.GetHeaderValue(16) # 매도호가
bid = objStockMst.GetHeaderValue(17) # 매수호가
vol = objStockMst.GetHeaderValue(18) # 거래량
vol_value = objStockMst.GetHeaderValue(19) # 거래대금
print("코드 이름 시간 현재가 대비 시가 고가 저가 매도호가 매수호가 거래량 거래대금")
print(code, name, time, cprice, diff, open, high, low, offer, bid, vol, vol_value)
return True
class MyWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("PLUS API TEST")
self.setGeometry(300, 300, 300, 150)
self.isRq = False
self.objStockMst = CpStockMst()
self.objStockCur = CpStockCur()
btn1 = QPushButton("요청 시작", self)
btn1.move(20, 20)
btn1.clicked.connect(self.btn1_clicked)
btn2 = QPushButton("요청 종료", self)
btn2.move(20, 70)
btn2.clicked.connect(self.btn2_clicked)
btn3 = QPushButton("종료", self)
btn3.move(20, 120)
btn3.clicked.connect(self.btn3_clicked)
def StopSubscribe(self):
if self.isRq:
self.objStockCur.Unsubscribe()
self.isRq = False
def btn1_clicked(self):
testCode = "A000660"
if (self.objStockMst.Request(testCode) == False):
exit()
# 하이닉스 실시간 현재가 요청
self.objStockCur.Subscribe(testCode)
print("빼기빼기================-")
print("실시간 현재가 요청 시작")
self.isRq = True
def btn2_clicked(self):
self.StopSubscribe()
def btn3_clicked(self):
self.StopSubscribe()
exit()
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
app.exec_()
실행결과
실행결과 아래와 같은 어플리케이션이 실행된다.
요청 시작 버튼을 클릭한 경우, 아래와 같은 문자열이 출력되는데 '실시간 현재가 요청 시작' 이후 대상 종목인 SK하이닉스의 실시간 현재가가 출력되어야 하지만 장 마감시간 이후에 프로그램을 실행했기 때문에 출력되는 내용 없이 실시간 요청만 진행하고 있는 상태다. 요청 종료를 누르면 프로그램 내부적으로 요청을 종료하지만 별도로 출력되는 내용은 없다.
장이 열려있어 거래가 진행중인 시간이라면 아래와 같이 출력된다. 아래는 CREON 홈페이지에서 캡쳐한 내용이다.
'빼기빼기================-' 문자열 부분이 다른데 아마도 CREON 측에서 예제 소스를 잘못 올린 것 같다. 코드를 작성한 사람이 임시로 본인이 알아볼 수 있도록 빼기빼기라고 작성한 것 같다ㅋㅋ
분석내용
MyWindow, CpStockMst, CpStockCur, CpEvent 클래스를 구현했다. 사실 이번 예제에서 CREON API 사용 관련 내용은 CpStockCur 클래스만 분석해도 될 것으로 보이지만.. 기왕 하는김에 예제 구조도 함께 정리해보기로 했다.
- MyWindow
- 윈도우UI 구현하여 사용자로부터 요청시작/종료 명령을 입력받는다.
- MyWindow 객체가 생성되는 순간 객체 내부에 CpStockMst, CpStockCur 객체를 생성한다.
- '요청 시작' 시 동작
- CpStockMst 객체의 Request 메소드를 호출하여 대상 종목의 현재가 정보 출력
- CpStockCur 객체의 Suscribe 메소드를 호출하여 현재가 요청을 시작
- 실시간 요청 진행여부 Flag값 True로 변경
- '요청 종료'시 동작
- CpStockCur 객체의 Unsubscribe 메소드를 호출하여 요청 종료
- 실시간 요청 진행여부 Flag값 False로 변경
- '종료'시 동작
- 그레이스풀 셧다운을 위한 '요청 종료'시 동작 수행
- 프로그램 종료
- CpStockMst
- 이전에 분석한 적 있는 현재가 조회 예제와 동일한 내용으로, 대상 종목의 현재가 정보를 읽는 역할을 한다.
- 다음 글의 내용을 참고하면 된다.
- https://bbdad.tistory.com/14?category=536957
CREON API (Python) 주식 현재가 조회
코드 import win32com.client # 연결 여부 체크 objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") bConnect = objCpCybos.IsConnect if (bConnect == 0): print("PLUS가 정상적으로 연결되지 않음. ") ex..
bbdad.tistory.com
- CpStockCur
- DsCbo1.StockCur COM객체를 사용하여 주식 현재가 정보를 CREON으로부터 구독(Subscribe)/구독해제(Unsubscribe)한다.
- CpStockCur 클래스는 멤버변수 없이 Subscribe, Unsubscribe 두개의 메소드만으로 구성되어 있다.
- Unsubscribe는 단순히 StockCur COM객체의 Unsubscribe 메소드를 호출하며 해당 메소드는 당연하게도 CREON으로부터의 구독을 해제하는 기능이다.
- Subscribe에서는 아래와 같은 동작을 한다.
- StockCur 객체로부터 발생하는 이벤트를 처리할 클래스를 등록한다.
win32com.client.WithEvents(self.objStockCur, CpEvent)
- StockCur 객체의 SetInputValue 메소드를 호출하여 구독 대상 종목을 설정한다. 첫번째 파라미터는 0 고정값을 사용하며 두번째 파라미터는 대상 종목의 종목코드값이다.
- StockCur 객체의 Subscribe 메소드를 호출하여 구독(Subscribe)을 시작한다.
- StockCur 객체로부터 발생하는 이벤트를 처리할 클래스를 등록한다.
- CpEvent
- StockCur 객체에 접근하기 위한 멤버변수인 instance와 이벤트를 처리하는 메소드인 OnReceived로 구성되어 있다. 어차피 StockCur 객체만 접근할 멤버변수인데 instance라는 변수명을 쓰니까 좀 헷갈리는 것 같다... stockCur 정도로 짓는게 가독성이 더 좋은것 같다는 생각이 든다.
- OnReceived 메소드는 구독상태인 StockCur 객체에서 이벤트가 발생하는 경우 호출되는데, 여기서 이벤트란 StockCur 객체에 접근해서 읽을 수 있는 주식 현재가의 업데이트이다. 여하튼, 이벤트가 발생하면 instance라는 변수명의 StockCur 객체의 정보를 읽어 체결 내역을 출력한다.
- StockCur 객체의 GetHeaderValue 메소드를 통해 정보를 읽는데 이는 이전 예제의 COM객체들과 특별히 다른 내용은 없다. 파라미터 상세값은 아래 참조 란을 참고하길 바란다.
참고
DsCbo1.StockCur 도움말 참조
크레온플러스 도움말 - 크레온
설명주식/업종/ELW시세데이터를수신합니다통신종류Subscribe/Publish관련 RQ/RP StockMst ,Elw관련CYBOS [7021현재가] [7024 시간대별체결]등의실시간데이타모듈위치cpdib.dll Method object.SetInputValue(type,value) type
money2.creontrade.com
'알고리즘 트레이딩 > CREON API 예제 분석' 카테고리의 다른 글
CREON API (Python) 주식 현금 매도주문 (0) | 2022.03.01 |
---|---|
CREON API (Python) 주식 현금 매수주문 (0) | 2022.02.24 |
CREON API (Python) 주식 일자별 조회 (0) | 2022.02.16 |
CREON API (Python) 주식 현재가 조회 (0) | 2022.02.15 |
CREON API (Python) 종목정보 구하는 예제 (0) | 2022.02.04 |
댓글