본문 바로가기
Python, API

[XINGAPI] 해외선물 실시간 주문접수/응답/체결 정보 가져오기 - TC1/TC2/TC3

by 오늘밤날다 2022. 6. 30.

 

 

지난 포스팅에서 실시간 체결정보(OVC)를 가져오는 코드를 구성해봤는데 

실제로 주문이 발생했을 경우 각각 접수(TC1), 응답(TC2), 체결(TC3)의 실시간 정보를 가져오는 코드를 추가해봤다.

 

2022.06.29 - [코딩] - [XINGAPI] 해외선물 실시간체결정보 가져오기 - OVC

 

[XINGAPI] 해외선물 실시간체결정보 가져오기 - OVC

XINGAPI로 실시간데이터를 가져오는 코드를 구성해봤다. 일단 Devcenter를 실행한 후 Real 목록에 있는 항목 중 원하는 것들을 골라서 코드를 구성하면 된다. 해외선물은 아래와 같이 7개의 항목이 있

toniteifly.tistory.com

 

 

DevCenter를 실행해보면 아래와 같이 Real목록에서 TC1 ~ TC3가 있는데 

당연한 것이겠지만 별도로 입력할 정보가 없기 때문에 InBlock항목이 없는데

이 부분을 어떻게 SetFieldData로 처리해야되는지 약간 애먹었지만 

결론적으로는 ResFileName만 지정하고 SetFieldData를 생략하고 AdviseRealData 함수를 실행하면 된다.

 

TC1, TC2, TC3

 

 

# 전체 코드 (OVC + TC1, TC2, TC3)

 

새로 추가할 Real 항목을 수신하기 위한 클래스를 각각 만들어줬고

TC1, TC2 그리고 TC3를 한꺼번에 요청하기 위한 req_realtime_order 함수를 추가했다.

 

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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
 
from PyQt5.QtWidgets import QApplication
from PyQt5.QAxContainer import QAxWidget
import sys
import win32com.client
import pythoncom
 
 
# 로그인용 EventHandler
class XASessionEventHandler:
    login_state = 0
 
    def OnLogin(self, code, msg):
        print(code, msg)
        if code == "0000":
            XASessionEventHandler.login_state = 1
        else:
            pass
 
 
class XARealHandler_OVC:
    def OnReceiveRealData(self, type):
        outblock = {'종목코드''symbol''체결일자(현지)''ovsdate''체결일자(한국)''kordate''체결시간(현지)''trdtm''체결시간(한국)''kortm',
                        '체결가격''curpr''전일대비''ydiffpr''전일대비기호''ydiffSign',
                        '시가''open''고가''high''저가''low''등락율''chgrate',
                        '건별체결수량''trdq''누적체결수량''totq'}
 
        # 데이터 가져오기
        ret_outblock = {}
        for item in outblock:
            ret_outblock[item] = main.XAreal_OVC.GetFieldData("OutBlock", outblock[item])
        print(type, ret_outblock)
 
 
class XARealHandler_TC1:
    def OnReceiveRealData(self, type):
        outblock = {'라인일련번호''lineseq''KEY''key''조작자ID''user''서비스ID''svc_id''주문일자''ordr_dt',
                    '지점번호''brn_cd''주문번호''ordr_no''원주문번호''orgn_ordr_no''모주문번호''mthr_ordr_no',
                    '계좌번호''ac_no''종목코드''is_cd''매도매수유형''s_b_ccd''정정취소유형''ordr_ccd',
                    '주문유형코드''ordr_typ_cd''주문기간코드''ordr_typ_prd_ccd''주문적용시작일자''ordr_aplc_strt_dt',
                    '주문적용종료일자''ordr_aplc_end_dt''주문가격''ordr_prc''주문조건가격''cndt_ordr_prc',
                    '주문수량''ordr_q''주문시간''ordr_tm',
                    '사용자ID''userid''만기행사유무''xrc_rsv_tcp_code'}
 
        # 데이터 가져오기
        ret_outblock = {}
        for item in outblock:
            ret_outblock[item] = main.XAreal_TC1.GetFieldData("OutBlock", outblock[item])
        print(type, ret_outblock)
 
 
class XARealHandler_TC2:
    def OnReceiveRealData(self, type):
        outblock = {'라인일련번호''lineseq''KEY''key''조작자ID''user''서비스ID''svc_id''주문일자''ordr_dt',
                    '지점번호''brn_cd''주문번호''ordr_no''원주문번호''orgn_ordr_no''모주문번호''mthr_ordr_no',
                    '계좌번호''ac_no''종목코드''is_cd''매도매수유형''s_b_ccd''정정취소유형''ordr_ccd',
                    '주문유형코드''ordr_typ_cd''주문기간코드''ordr_typ_prd_ccd''주문적용시작일자''ordr_aplc_strt_dt',
                    '주문적용종료일자''ordr_aplc_end_dt''주문가격''ordr_prc''주문조건가격''cndt_ordr_prc',
                    '주문수량''ordr_q''주문시간''ordr_tm',
                    '호가확인수량''cnfr_q''호가거부사유코드''rfsl_cd',
                    '호가거부사유코드명''text''사용자ID''user_id'}
 
        # 데이터 가져오기
        ret_outblock = {}
        for item in outblock:
            ret_outblock[item] = main.XAreal_TC2.GetFieldData("OutBlock", outblock[item])
        print(type, ret_outblock)
 
 
class XARealHandler_TC3:
    def OnReceiveRealData(self, type):
        outblock = {'라인일련번호''lineseq''KEY''key''조작자ID''user''서비스ID''svc_id''주문일자''ordr_dt',
                    '지점번호''brn_cd''주문번호''ordr_no''원주문번호''orgn_ordr_no''모주문번호''mthr_ordr_no',
                    '계좌번호''ac_no''종목코드''is_cd''매도매수유형''s_b_ccd''정정취소유형''ordr_ccd',
                    '체결수량''ccls_q''체결가격''ccls_prc''체결번호''ccls_no''체결시간''ccls_tm',
                    '매입평균단가''avg_byng_uprc''매입금액''byug_amt''청산손익''clr_pl_amt''위탁수수료''ent_fee',
                    '매입잔고수량''fcm_fee''사용자ID''userid''현재가격''now_prc''통화코드''crncy_cd',
                    '만기일자''mtrt_dt''주문상품구분코드1''ord_prdt_tp_code''주문상품구분코드2''exec_prdt_tp_code',
                    '스프레드종목여부''sprd_base_isu_yn''FILLER1''filler1''FILLER2''filler2''스프레드종목코드''sprd_is_cd'}
 
        # 데이터 가져오기
        ret_outblock = {}
        for item in outblock:
            ret_outblock[item] = main.XAreal_TC3.GetFieldData("OutBlock", outblock[item])
        print(type, ret_outblock)
 
 
class Main(QAxWidget):
    def __init__(self):
        super().__init__()
 
        # RealDataHandler 등록
        self.XAreal_OVC = win32com.client.DispatchWithEvents("XA_DataSet.XAReal", XARealHandler_OVC)
        self.XAreal_TC1 = win32com.client.DispatchWithEvents("XA_DataSet.XAReal", XARealHandler_TC1)
        self.XAreal_TC2 = win32com.client.DispatchWithEvents("XA_DataSet.XAReal", XARealHandler_TC2)
        self.XAreal_TC3 = win32com.client.DispatchWithEvents("XA_DataSet.XAReal", XARealHandler_TC3)
 
    def connect(self):
        id = ""
        passwd = ""
        cert_passwd = ""
 
        instXASession = win32com.client.DispatchWithEvents("XA_Session.XASession", XASessionEventHandler)
        instXASession.ConnectServer("demo.ebestsec.co.kr"20001)
        instXASession.Login(id, passwd, cert_passwd, 00)
 
        while XASessionEventHandler.login_state == 0:
            pythoncom.PumpWaitingMessages()
 
    def req_realtime_price(self, symbol):
        self.XAreal_OVC.ResFileName = 'C:/eBEST/xingAPI/Res/OVC.res'
        self.XAreal_OVC.SetFieldData("InBlock""symbol", symbol)
        self.XAreal_OVC.AdviseRealData()
 
    def req_realtime_order(self):
        # TC1
        self.XAreal_TC1.ResFileName = 'C:/eBEST/xingAPI/Res/TC1.res'
        self.XAreal_TC1.AdviseRealData()
 
        # TC2
        self.XAreal_TC2.ResFileName = 'C:/eBEST/xingAPI/Res/TC2.res'
        self.XAreal_TC2.AdviseRealData()
 
        # TC3
        self.XAreal_TC3.ResFileName = 'C:/eBEST/xingAPI/Res/TC3.res'
        self.XAreal_TC3.AdviseRealData()
 
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = Main()
    main.connect()
    main.req_realtime_price('HMHN22')
    main.req_realtime_order()
 
    app.exec_()
 
cs

 

코드를 실행한 후에 모의투자HTS를 켜서 주문을 실행하면 아래와 같이 정상적으로 데이터가 수신된다.

아래에서는 TC1과 TC3 정보만 넘어오는데 몇 가지 테스트를 해본 결과 TC2는 주문이 거부된 경우에만 수신되는 듯하다.

 

 

# 모의투자서버와 실서버의 수신 데이터 차이

 

TC3 정보를 가지고 잔고처리를 하다가 매수 및 매도 포지션 방향이 모의투자 서버와 실서버가 다른 것을 발견했다.

모의투자 서버에서는 매도포지션일 경우 '매입잔고수량'이 음수로 표시되지만 실서버는 일관되게 양수로 표현된다.

포지션 방향은 '매입잔고수량'의 부호로 판단하면 안 되고 '매도매수유형'으로 판단해야 한다.

('2'는 매수포지션, '1'은 매도포지션)

 

  매도포지션 진입시 TC3 Data
실서버 {'라인일련번호': '0', 'KEY': '######', '조작자ID': '######', '서비스ID': 'CH01', '주문일자': '20220630', '지점번호': '202', '주문번호': '5858', '원주문번호': '0', '모주문번호': '5858', '계좌번호': '######', '종목코드': 'HMHN22', '매도매수유형': '1', '정정취소유형': '1', '체결수량': '1', '체결가격': '21915.00000000000', '체결번호': '0000002678', '체결시간': '125430373', '매입평균단가': '21915.00000000000', '매입금액': '219150.00000000', '청산손익': '0.00', '위탁수수료': '40.00', '매입잔고수량': '1', '사용자ID': '######', '현재가격': '21916.00000000000', '통화코드': 'HKD', '만기일자': '20220728', '주문상품구분코드1': 'F', '주문상품구분코드2': 'F', '스프레드종목여부': '', 'FILLER1': '', 'FILLER2': '', '스프레드종목코드': ''}
모의투자
서버
{'라인일련번호': '0', 'KEY': '######', '조작자ID': '######', '서비스ID': 'CH01', '주문일자': '20220630', '지점번호': '001', '주문번호': '1992', '원주문번호': '0', '모주문번호': '1992', '계좌번호': '######', '종목코드': 'HMHN22', '매도매수유형': '1', '정정취소유형': '1', '체결수량': '1', '체결가격': '21973.00000000000', '체결번호': '0000002416', '체결시간': '141714404', '매입평균단가': '21973.00000000000', '매입금액': '219730.00000000', '청산손익': '0.00', '위탁수수료': '0.00', '매입잔고수량': '-1', '사용자ID': '######', '현재가격': '21928.00000', '통화코드': 'HKD', '만기일자': '20220728', '주문상품구분코드1': 'F', '주문상품구분코드2': 'F', '스프레드종목여부': '', 'FILLER1': '', 'FILLER2': '', '스프레드종목코드': ''}