ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CREON PLUS API 활용] BlockRequest 와 Request
    개발/파이썬 2018.12.11 20:38

    크레온 플러스 API를 이용해서 통신하는 방법은 다음 2가지가 있습니다


    • BlockRequest 방식 - 가장 간단한 데이터 요청
    • Request 호출 후 Received 이벤트를 수신 받기 

    아래 코드는 두 가지 방식으로 현재가를 통신하는 코드 입니다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    import pythoncom
    from PyQt5.QtWidgets import *
    import win32com.client
     
    import win32event
     
    g_objCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr')
     
    StopEvent = win32event.CreateEvent(None, 00, 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)
     
     
     
    cs


    두 번째 방법에서는 이전에 올린 메시지 펌프를 이용해서 이벤트를 대기하도록 했습니다. 

    2018/12/08 - [개발/파이썬] - 파이썬 윈도우 메시지 펌프 처리 예제

    두 가지 방법은 장단점이 있습니다.

    • BlockRequest 방식 - 호출이 단순. 단, 실시간 시세 이벤트를 수신 받아 호출 할 경우 또 다시 시세 발생으로 재귀 호출 될 수 있음. 완전히 회피하기 위해서는 Request 방식을 사용해야 함. 
    • Request 호출 후 Received 이벤트를 수신 받기 - 호출과 수신 코드가 분리 되어 코딩이 BlockRequest 보다 어려움(위 코드는 메시지 펌프를 이용했으나 PYQT 같은 자체 메시지 펌프를 가진 윈도우에서는 Received 이벤트 처리 이후를 함수 호출로 처리하는 식으로 개발 해야 함.


    목적에 따라 각자 필요한 함수를 이용하면 되겠습니다. 



    댓글 1

Designed by black7375.