크레온 플러스 API를 이용해서 통신하는 방법은 다음 2가지가 있습니다
- BlockRequest 방식 - 가장 간단한 데이터 요청
- Request 호출 후 Received 이벤트를 수신 받기
아래 코드는 두 가지 방식으로 현재가를 통신하는 코드 입니다.
import pythoncom from PyQt5.QtWidgets import * import win32com.client import win32event g_objCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr') StopEvent = win32event.CreateEvent(None, 0, 0, None) class CpEvent: def set_params(self, client, name, caller): self.client = client # CP 실시간 통신 object self.name = name # 서비스가 다른 이벤트를 구분하기 위한 이름 self.caller = caller # callback 을 위해 보관 def OnReceived(self): # 실시간 처리 - 현재가 주문 체결 if self.name == 'stockmst': print('recieved') win32event.SetEvent(StopEvent) return class CpCurReply: def __init__(self, objEvent): self.name = "stockmst" self.obj = objEvent def Subscribe(self): handler = win32com.client.WithEvents(self.obj, CpEvent) handler.set_params(self.obj, self.name, None) def MessagePump(timeout): waitables = [StopEvent] while 1: rc = win32event.MsgWaitForMultipleObjects( waitables, 0, # Wait for all = false, so it waits for anyone timeout, #(or win32event.INFINITE) win32event.QS_ALLEVENTS) # Accepts all input if rc == win32event.WAIT_OBJECT_0: # Our first event listed, the StopEvent, was triggered, so we must exit print('stop event') break elif rc == win32event.WAIT_OBJECT_0 + len(waitables): # A windows message is waiting - take care of it. (Don't ask me # why a WAIT_OBJECT_MSG isn't defined < WAIT_OBJECT_0...!). # This message-serving MUST be done for COM, DDE, and other # Windowsy things to work properly! print('pump') if pythoncom.PumpWaitingMessages(): break # we received a wm_quit message elif rc == win32event.WAIT_TIMEOUT: print('timeout') return pass else: print('exception') raise RuntimeError("unexpected win32wait return value") code = 'A005930' ############################################################## #1. BlockRequest print('#####################################') objStockMst = win32com.client.Dispatch("DsCbo1.StockMst") objStockMst.SetInputValue(0, code) objStockMst.BlockRequest() print('BlockRequest 로 수신 받은 데이터') item = {} item['종목명']= g_objCodeMgr.CodeToName(code) item['현재가'] = objStockMst.GetHeaderValue(11) # 종가 item['대비'] = objStockMst.GetHeaderValue(12) # 전일대비 print(item) print('') ############################################################## # 2. Request --> 메시지 펌프 --> OnReceived 이벤트 수신 print('#####################################') objReply = CpCurReply(objStockMst) objReply.Subscribe() code = 'A005930' objStockMst.SetInputValue(0, code) objStockMst.Request() MessagePump(10000) item = {} item['종목명']= g_objCodeMgr.CodeToName(code) item['현재가'] = objStockMst.GetHeaderValue(11) # 종가 item['대비'] = objStockMst.GetHeaderValue(12) # 전일대비 print(item)
두 번째 방법에서는 이전에 올린 메시지 펌프를 이용해서 이벤트를 대기하도록 했습니다.
2018/12/08 - [개발/파이썬] - 파이썬 윈도우 메시지 펌프 처리 예제
두 가지 방법은 장단점이 있습니다.
- BlockRequest 방식 - 호출이 단순. 단, 실시간 시세 이벤트를 수신 받아 호출 할 경우 또 다시 시세 발생으로 재귀 호출 될 수 있음. 완전히 회피하기 위해서는 Request 방식을 사용해야 함.
- Request 호출 후 Received 이벤트를 수신 받기 - 호출과 수신 코드가 분리 되어 코딩이 BlockRequest 보다 어려움(위 코드는 메시지 펌프를 이용했으나 PYQT 같은 자체 메시지 펌프를 가진 윈도우에서는 Received 이벤트 처리 이후를 함수 호출로 처리하는 식으로 개발 해야 함.
목적에 따라 각자 필요한 함수를 이용하면 되겠습니다.
'개발 > 파이썬' 카테고리의 다른 글
[파이썬] 웹 페이지 스크랩 하기(BeautifulSoup 이용) (2) | 2019.10.20 |
---|---|
[파이썬] 함수 호출 CALL BY VALUE/CALL BY REFERENCE (2) | 2019.10.06 |
파이썬의 for 루프 (1) | 2019.06.16 |
파이썬 윈도우 메시지 펌프 처리 예제 (0) | 2018.12.08 |
[CREON PLUS API 활용] MACD 매매 시그널 실시간 구하기(5분 차트 이용) (0) | 2018.11.23 |
파이썬 리턴값 편리 기능 (0) | 2018.11.18 |
댓글