CYBOS Plus

[파이썬] 실시간 분차트 데이터 만들기

상품종류
주식
언어종류
파이썬
작성일
2018/01/10
조회수
25391
실시간 시세를 받아, 1분 차트 데이터를 만드는 예제입니다. 
예제에서는 코스피 200 에 속하는 200 종목을 실시간으로 요청한 후 받은 시세를 기준으로 1분 차트 데이터를 만듭니다.
(200 종목 분 차트 데이터 생성)

■ 분 차트  기준 : 14:10분 봉의 겨우 14:09:00~14:09:59초 사이에 들어온 데이터를 하나의 봉으로 만듭니다 
■ 예제에서는 시세 수신이 있을 경우에만 데이터를 추가하여 분데이터를 만듭니다. (해당 시간 체결이 없을 경우에는 분 데이터를 채우지 않음)
■ 과거 데이터 조회 없이 예제 실행 이후 들어온 데이터로만 분 차트를 만드는 예제입니다.


※ 주의사항: 본 예제는 PLUS 활용을 돕기 위해 예제로만 제공됩니다.  또한 제공된 코드에는 장 운영 시간 변경 등의 예외 코드가 반영 되어 있지 않습니다.

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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
import sys
from PyQt5.QtWidgets import *
import win32com.client
import ctypes
 
################################################
# PLUS 공통 OBJECT
g_objCodeMgr = win32com.client.Dispatch('CpUtil.CpCodeMgr')
g_objCpStatus = win32com.client.Dispatch('CpUtil.CpCybos')
g_objCpTrade = win32com.client.Dispatch('CpTrade.CpTdUtil')
 
 
################################################
# PLUS 실행 기본 체크 함수
def InitPlusCheck():
    # 프로세스가 관리자 권한으로 실행 여부
    if ctypes.windll.shell32.IsUserAnAdmin():
        print('정상: 관리자권한으로 실행된 프로세스입니다.')
    else:
        print('오류: 일반권한으로 실행됨. 관리자 권한으로 실행해 주세요')
        return False
 
    # 연결 여부 체크
    if (g_objCpStatus.IsConnect == 0):
        print("PLUS가 정상적으로 연결되지 않음. ")
        return False
 
    # # 주문 관련 초기화
    # if (g_objCpTrade.TradeInit(0) != 0):
    #     print("주문 초기화 실패")
    #     return False
 
    return True
 
 
################################################
# CpEvent: 실시간 이벤트 수신 클래스
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 == 'stockcur':
            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('2'):
                return
 
            item = {}
            item['code'= code
            item['time'= timess
            item['diff'= diff
            item['cur'= cprice
            item['vol'= vol
 
            # 현재가 업데이트
            self.caller.$업데이트$CurData(item)
 
 
            return
 
 
################################################
# plus 실시간 수신 base 클래스
class CpPublish:
    def __init__(self, name, serviceID):
        self.name = name
        self.obj = win32com.client.Dispatch(serviceID)
        self.bIsSB = False
 
    def Subscribe(self, var, caller):
        if self.bIsSB:
            self.Unsubscribe()
 
        if (len(var) > 0):
            self.obj.SetInputValue(0, var)
 
        handler = win32com.client.WithEvents(self.obj, CpEvent)
        handler.set_params(self.obj, self.name, caller)
        self.obj.Subscribe()
        self.bIsSB = True
 
    def Unsubscribe(self):
        if self.bIsSB:
            self.obj.Unsubscribe()
        self.bIsSB = False
 
 
################################################
# CpPBStockCur: 실시간 현재가 요청 클래스
class CpPBStockCur(CpPublish):
    def __init__(self):
        super().__init__('stockcur''DsCbo1.StockCur')
 
 
class CMi$엔차$tData:
    def __init__(self):
        self.minDatas = {}
        self.objCur = {}
 
    def stop(self):
        for k,v in self.objCur.items() :
            v.Unsubscribe()
 
 
    def addCode(self, code):
        if (code in self.minDatas) :
            return
 
        self.minDatas[code] = []
        self.objCur[code] = CpPBStockCur()
        self.objCur[code].Subscribe(code, self)
 
 
 
    def $업데이트$CurData(self, item):
        code = item['code']
        time  = item['time']
        cur = item['cur']
        self.makeMi$엔차$t(code, time, cur)
 
 
    def makeMi$엔차$t(self, code, time, cur) :
        hh, mm = divmod(time, 10000)
        mm, tt = divmod(mm, 100)
        mm += 1
        if (mm == 60) :
            hh += 1
            mm = 0
 
        hhmm = hh * 100 + mm
        if hhmm > 1530 :
            hhmm = 1530
        bFind = False
        minlen =len(self.minDatas[code])
        if (minlen > 0) :
            # 0 : 시간 1 : 시가 2: 고가 3: 저가 4: 종가
            if (self.minDatas[code][-1][0== hhmm) :
                item = self.minDatas[code][-1]
                bFind = True
                item[4= cur
                if (item[2< cur):
                    item[2= cur
                if (item[3> cur):
                    item[3= cur
 
        if bFind ==  False :
            self.minDatas[code].append([hhmm, cur, cur, cur, cur])
 
#        print(code, self.minDatas[code])
        return
 
    def print(self, code):
        print('====================================================-')
        print('분데이터 print', code, g_objCodeMgr.CodeToName(code))
        print('시간,시가,고가,저가,종가')
        for item in self.minDatas[code] :
            hh, mm = divmod(item[0], 100)
            print("%02d:%02d,%d,%d,%d,%d" %(hh, mm, item[1], item[2], item[3], item[4]))
 
 
 
# print(code, self.minDatas[code])
 
 
 
################################################
# 테스트를 위한 메인 화면
class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()
 
        # plus 상태 체크
        if InitPlusCheck() == False:
            exit()
 
        self.minData = CMi$엔차$tData()
 
        # 코스피 200 종목 가져와 추가
        self.codelist = g_objCodeMgr.GetGroupCodeList(180)
        for code in self.codelist :
            print(code, g_objCodeMgr.CodeToName(code))
            self.minData.addCode(code)
 
 
        self.setWindowTitle("주식 분 차트 생성")
        self.setGeometry(300300300180)
 
        nH  = 20
 
        btnPrint = QPushButton('print', self)
        btnPrint.move(20, nH)
        btnPrint.clicked.connect(self.btnPrint_clicked)
        nH += 50
 
 
        btnExit = QPushButton('종료', self)
        btnExit.move(20, nH)
        btnExit.clicked.connect(self.btnExit_clicked)
        nH += 50
 
 
    def btnPrint_clicked(self):
        for i in range(len(self.codelist)):
            self.minData.print(self.codelist[i])
            if i > 10: break
        return
 
 
    def btnExit_clicked(self):
        self.minData.stop()
        exit()
        return
 
 
 
if __name__ == "__main__":
    app = QApplication($시스.$argv)
    myWindow = MyWindow()
    myWindow.show()
    app.$이엑스이씨$_()
 
 
cs
첨부파일
의견(0)

첨부파일을 PDF뷰어로 확인 하실수 있으며, PDF뷰어 미설치 고객께서는 우측 다운로드를 통해 설치 후 이용 가능 합니다.

PDF뷰어 다운로드

인쇄