Showing
1 changed file
with
193 additions
and
268 deletions
... | @@ -13,314 +13,239 @@ class OpenApi(QAxWidget): | ... | @@ -13,314 +13,239 @@ class OpenApi(QAxWidget): |
13 | super().__init__() | 13 | super().__init__() |
14 | 14 | ||
15 | # event_loop list | 15 | # event_loop list |
16 | - self.login_event_loop=None | 16 | + self.tr_event_loop=QEventLoop() |
17 | - self.detail_account_info_event_loop=QEventLoop() | 17 | + self.login_event_loop=QEventLoop() |
18 | - self.calculator_event_loop=QEventLoop() | ||
19 | 18 | ||
20 | # variable list | 19 | # variable list |
21 | self.account_no=None # 계좌번호 | 20 | self.account_no=None # 계좌번호 |
22 | - self.account_stock_dict={} # 보유종목 | 21 | + self.ohlcv = None # 거래정보(시가,종가,고가,저가,거래량) |
23 | - self.not_account_stock_dict={} # 미체결종목 | 22 | + self.remained_data=None # 다음페이지 존재여부 |
24 | - self.calc_data=[] # 종목분석용 | ||
25 | - | ||
26 | - # account variable list | ||
27 | - self.user_money=0 | ||
28 | - self.user_money_percent=0.5 | ||
29 | 23 | ||
30 | # screen number list | 24 | # screen number list |
31 | - self.screen_my_info="2000" | 25 | + self.screen_data_req="0101" # 거래 데이터 |
32 | - self.screen_calculation_stock="4000" | 26 | + |
27 | + self.create_instance() | ||
28 | + self._signal_slots() | ||
29 | + self.comm_connect() # 로그인 | ||
30 | + self.get_account_info() # 계좌정보 가져오기 | ||
31 | + | ||
32 | + # 주식일봉차트조회요청 | ||
33 | + def _opt10081(self,sRQName,sTrCode): | ||
34 | + QTest.qWait(TR_REQ_TIME_INTERVAL) | ||
35 | + | ||
36 | + cnt=self._get_repeat_cnt(sTrCode,sRQName) | ||
37 | + | ||
38 | + for i in range(cnt): | ||
39 | + date=self._get_comm_data(sTrCode,sRQName,i,"일자") | ||
40 | + open=self._get_comm_data(sTrCode,sRQName,i,"시가") | ||
41 | + high=self._get_comm_data(sTrCode,sRQName,i,"고가") | ||
42 | + low=self._get_comm_data(sTrCode,sRQName,i,"저가") | ||
43 | + close=self._get_comm_data(sTrCode,sRQName,i,"현재가") | ||
44 | + volume=self._get_comm_data(sTrCode,sRQName,i,"거래량") | ||
33 | 45 | ||
34 | - self._get_instance() | 46 | + self.ohlcv['date'].append(date) |
35 | - self._event_slot() | 47 | + self.ohlcv['open'].append(int(open)) |
36 | - self.comm_connect() | 48 | + self.ohlcv['high'].append(int(high)) |
37 | - self.account_info() # 계좌정보 가져오기 | 49 | + self.ohlcv['low'].append(int(low)) |
38 | - self.detail_account_info() # 예수금 가져오기 | 50 | + self.ohlcv['close'].append(int(close)) |
39 | - self.detail_account_mystock() # 계좌평가잔고내역 가져오기 | 51 | + self.ohlcv['volumn'].append(int(volume)) |
40 | - self.not_concluded_account() # 미체결 종목 조회 | ||
41 | 52 | ||
42 | - self.calculator_fnc() # 종목분석용용 | 53 | + # TR 요청을 처리하는 slot |
54 | + # param sScrNo: 스크린번호 | ||
55 | + # sRQName: 요청했을 때 지은 이름 | ||
56 | + # sTrCode: 요청 id, tr코드 | ||
57 | + # sRecordName: 레코드 이름 | ||
58 | + # sPrevNext: 다음 페이지가 있는지 여부. "2" : 다음페이지 존재, "0" or "" : 다음페이지 없음 | ||
59 | + def _receive_tr_data(self,sScrNo,sRQName,sTrCode,sRecordName,sPrevNext): | ||
60 | + if sPrevNext=='2': | ||
61 | + self.remained_data=True | ||
62 | + else: | ||
63 | + self.remained_data=False | ||
64 | + | ||
65 | + if sRQName=="opt10081": | ||
66 | + print("==============주식일봉차트조회요청================") | ||
67 | + self._opt10081(sRQName,sTrCode) | ||
68 | + elif sRQName=="opw0001_req": | ||
69 | + return | ||
70 | + elif sRQName=="opw00018_req": | ||
71 | + return | ||
72 | + elif sRQName=="opt10074_req": | ||
73 | + return | ||
74 | + elif sRQName=="opw00015_req": | ||
75 | + return | ||
76 | + elif sRQName=="opt10076_req": | ||
77 | + return | ||
78 | + elif sRQName=="opt10073_req": | ||
79 | + return | ||
43 | 80 | ||
44 | - #get ocx controller to use kiwoom open api | ||
45 | - def _get_instance(self): | ||
46 | try: | 81 | try: |
47 | - self.setControl("KHOPENAPI.KHOpenAPICtrl.1") | 82 | + self.tr_event_loop.exit() |
83 | + except AttributeError: | ||
84 | + pass | ||
85 | + | ||
86 | + # 특정 종목의 일자별 거래 데이터 조회 함수 | ||
87 | + # param : code - 종목코드 | ||
88 | + # start - 기준일자 | ||
89 | + # return : df - 특정종목의 일자별 거래 데이터 목록 | ||
90 | + def get_total_data(self,code,start): | ||
91 | + self.ohlcv = {'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': []} | ||
92 | + | ||
93 | + self._set_input_value("종목코드",code) | ||
94 | + self._set_input_value("기준일자",start) | ||
95 | + self._set_input_value("수정주가구분",1) | ||
96 | + self._comm_rq_data("opt10081_req","opt10081",0,self.screen_data_req) | ||
97 | + | ||
98 | + while self.remained_data: | ||
99 | + self._set_input_value("종목코드",code) | ||
100 | + self._set_input_value("기준일자",start) | ||
101 | + self._set_input_value("수정주가구분",1) | ||
102 | + self._comm_rq_data("opt10081_req","opt10081",2,self.screen_data_req) | ||
103 | + | ||
104 | + # 데이터가 없거나, date=''일 경우 empty list를 반환 | ||
105 | + if len(self.ohlcv)==0: | ||
106 | + return [] | ||
107 | + if self.ohlcv['date']=='': | ||
108 | + return [] | ||
109 | + | ||
110 | + # 데이터를 DataFrame형태로 저장 및 반환 | ||
111 | + df=DataFrame(self.ohlcv,columns=['open','high','low','close','volume'],index=self.ohlcv['date']) | ||
112 | + | ||
113 | + return df | ||
114 | + | ||
115 | + # 특정 종목의 특정 날짜의 시가,종가,고가,저가,거래량 중 특정한 데이터를 반환하는 함수 | ||
116 | + # param : code - 종목코드 | ||
117 | + # : date - 조회날짜 | ||
118 | + # : option - open(시가)/close(종가)/high(고가)/low(저가)/volume(거래량) | ||
119 | + # return : 조회한 데이터에 해당하는 값 | ||
120 | + # 값이 없거나, option이 오류일 경우 return False | ||
121 | + def get_oneday_option_data(self,code,date,option): | ||
122 | + self.ohlcv = {'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': []} | ||
123 | + | ||
124 | + self._set_input_value("종목코드",code) | ||
125 | + self._set_input_value("기준일자",date) | ||
126 | + self._set_input_value("수정주가구분",1) | ||
127 | + self._comm_rq_data("opt10081_req","opt10081",0,self.screen_data_req) | ||
128 | + | ||
129 | + if self.ohlcv['date']=="": | ||
130 | + return False | ||
131 | + | ||
132 | + df = DataFrame(self.ohlcv, columns=['open', 'high', 'low', 'close', 'volume'], index=self.ohlcv['date']) | ||
133 | + if option == 'open': | ||
134 | + return df.iloc[0, 0] | ||
135 | + elif option == 'high': | ||
136 | + return df.iloc[0, 1] | ||
137 | + elif option == 'low': | ||
138 | + return df.iloc[0, 2] | ||
139 | + elif option == 'close': | ||
140 | + return df.iloc[0, 3] | ||
141 | + elif option == 'volume': | ||
142 | + return df.iloc[0, 4] | ||
143 | + else: | ||
144 | + return False | ||
145 | + | ||
146 | + # 사용자의 계좌정보 저장 및 출력 | ||
147 | + def get_account_info(self): | ||
148 | + account=self.get_login_info("ACCNO") | ||
149 | + self.account_no=account.split(";")[0] | ||
150 | + print("======== 계좌번호 : ",self.account_no,"========") | ||
151 | + | ||
152 | + # 원하는 사용자 정보 반환 | ||
153 | + # param : tag - ACCNO - 보유계좌리스트 | ||
154 | + # ACCOUNT_CNT - 보유계좌 수 | ||
155 | + # USER_ID - 사용자 ID | ||
156 | + # USER_NAME - 사용자 이름 | ||
157 | + # KEY_BSECGB - 키보드 보안 해제 여부 (0 : 정상, 1: 해지) | ||
158 | + # FIREW_SECGB - 방화벽 설정여부 (0 : 미설정, 1: 설정, 2 : 해지) | ||
159 | + # GetServerGubun - 접속서버 구분 (1 : 모의투자, 나머지 : 실서버) | ||
160 | + # return : tag를 통해 요청한 정보(ret) 반환 | ||
161 | + def get_login_info(self,tag): | ||
162 | + try: | ||
163 | + ret=self.dynamicCall("GetLoginInfo(QString)",tag) | ||
164 | + return ret | ||
48 | except Exception as e: | 165 | except Exception as e: |
49 | print(e) | 166 | print(e) |
50 | sys.exit() | 167 | sys.exit() |
51 | 168 | ||
52 | - # event slot to use open api | 169 | + # 키움 api를 사용하기 위한 ocx controller 저장 |
53 | - def _event_slot(self): | 170 | + def create_instance(self): |
54 | try: | 171 | try: |
55 | - self.OnEventConnect.connect(self.login_slot) # for login | 172 | + self.setControl("KHOPENAPI.KHOpenAPICtrl.1") |
56 | - self.OnReceiveTrData.connect(self.trdata_slot) # for tr data | ||
57 | except Exception as e: | 173 | except Exception as e: |
58 | print(e) | 174 | print(e) |
59 | sys.exit() | 175 | sys.exit() |
60 | 176 | ||
61 | - # login event slot | 177 | + # event처리를 위한 slot |
62 | - # param code : if login success, code=0 | 178 | + def _signal_slots(self): |
63 | - def login_slot(self,code): | ||
64 | try: | 179 | try: |
65 | - result=errCode.errors(code) | 180 | + self.OnEventConnect.connect(self._login_slot) |
66 | - if code==0: | 181 | + self.OnReceiveTrData.connect(self._receive_tr_data) |
67 | - print("Connected - ",result[0],result[1]) | ||
68 | - else: | ||
69 | - print("Failed to connect",result[0],result[1]) | ||
70 | - self.login_event_loop.exit() | ||
71 | except Exception as e: | 182 | except Exception as e: |
72 | print(e) | 183 | print(e) |
73 | sys.exit() | 184 | sys.exit() |
74 | 185 | ||
75 | - # try login | 186 | + # 수동 로그인설정인 경우 로그인창을 출력해서 로그인을 시도 |
187 | + # 자동로그인 설정인 경우 로그인창 출력없이 로그인을 시도 | ||
76 | def comm_connect(self): | 188 | def comm_connect(self): |
77 | try: | 189 | try: |
78 | self.dynamicCall("CommConnect()") | 190 | self.dynamicCall("CommConnect()") |
79 | - self.login_event_loop = QEventLoop() # wait for login complete | ||
80 | self.login_event_loop.exec_() | 191 | self.login_event_loop.exec_() |
81 | except Exception as e: | 192 | except Exception as e: |
82 | print(e) | 193 | print(e) |
83 | sys.exit() | 194 | sys.exit() |
84 | 195 | ||
85 | - # get user information | 196 | + # 로그인 이벤트 처리 slot |
86 | - # param tag: ACCNO - 보유계좌리스트 | 197 | + # param : code - 로그인 성공 시 0 |
87 | - # ACCOUNT_CNT - 보유계좌 수 | 198 | + # 실패 시 에러코드 출력 |
88 | - # USER_ID - 사용자 ID | 199 | + def _login_slot(self,code): |
89 | - # USER_NAME - 사용자 이름 | ||
90 | - # KEY_BSECGB - 키보드 보안 해제 여부 (0 : 정상, 1: 해지) | ||
91 | - # FIREW_SECGB - 방화벽 설정여부 (0 : 미설정, 1: 설정, 2 : 해지) | ||
92 | - # GetServerGubun - 접속서버 구분 (1 : 모의투자, 나머지 : 실서버) | ||
93 | - # return: tag를 통해 요청한 정보(ret) 반환 | ||
94 | - def get_login_info(self,tag): | ||
95 | try: | 200 | try: |
96 | - ret=self.dynamicCall("GetLoginInfo(QString)",tag) | 201 | + result=errCode.errors(code) |
97 | - return ret | 202 | + if code==0: |
203 | + print("Connected",result[1]) | ||
204 | + else: | ||
205 | + print("Failed to connect",result[1]) | ||
206 | + self.login_event_loop.exit() | ||
98 | except Exception as e: | 207 | except Exception as e: |
99 | print(e) | 208 | print(e) |
100 | sys.exit() | 209 | sys.exit() |
101 | 210 | ||
102 | - # print user account information | 211 | + # 조회요청시 TR의 Input값을 지정하는 함수 |
103 | - def account_info(self): | 212 | + # param : sId - TR에 명시된 Input이름 |
213 | + # svalue - Input이름으로 지정한 값 | ||
214 | + def _set_input_value(self,sId,sValue): | ||
104 | try: | 215 | try: |
105 | - account_number=self.get_login_info("ACCNO") | 216 | + self.dynamicCall("SetInputValue(QString, QString)", sId, sValue) |
106 | - self.account_no=account_number.split(";")[0] | 217 | + except Exception as e: |
107 | - print("계좌번호 : ",self.account_no) | ||
108 | - except AttributeError as e: | ||
109 | print(e) | 218 | print(e) |
110 | sys.exit() | 219 | sys.exit() |
111 | 220 | ||
112 | - # detail information about deposit | 221 | + # 조회요청함수 |
113 | - def detail_account_info(self): | 222 | + # param : sRQName - 사용자 구분명 |
114 | - self.dynamicCall("SetInputValue(String,String)","계좌번호",self.account_no) | 223 | + # sTrCode - 조회하려는 TR이름 |
115 | - self.dynamicCall("SetInputValue(String,String)","비밀번호",'0000') | 224 | + # nPrevNext - 연속조회여부 |
116 | - self.dynamicCall("SetInputValue(String,String)","비밀번호입력매체구분",'00') | 225 | + # sScreenNo - 화면번호 |
117 | - self.dynamicCall("SetInputValue(String,String)","조회구분",'2') | 226 | + def _comm_rq_data(self,sRQName,sTrData,nPrevNext,sScrNo): |
118 | - self.dynamicCall("CommRqData(String,String,int,String)","예수금상세현황요청","opw00001","0",self.screen_my_info) | 227 | + self.dynamicCall("CommRqData(QString, QString, int, QString", sRQName, sTrData, nPrevNext, sScrNo) |
119 | - | 228 | + self.tr_event_loop.exec_() |
120 | - self.detail_account_info_event_loop.exec_() | 229 | + |
121 | - | 230 | + # OnReceiveTRData()이벤트가 호출될때 조회데이터를 얻어오는 함수 |
122 | - # detail information about account | 231 | + # param : sTrCode - TR 이름 |
123 | - def detail_account_mystock(self,sPreNext="0"): | 232 | + # sRecordName - 레코드이름 |
124 | - self.dynamicCall("SetInputValue(QString,QString)","계좌번호",self.account_no) | 233 | + # nIndex - TR반복부 |
125 | - self.dynamicCall("SetInputValue(QString,QString)","비밀번호",'0000') | 234 | + # sItemName - TR에서 얻어오려는 출력항목이름 |
126 | - self.dynamicCall("SetInputValue(QString,QString)","비밀번호입력매체구분",'00') | 235 | + def _get_comm_data(self,sTrCode,sRecordName,nIndex,sItemName): |
127 | - self.dynamicCall("SetInputValue(QString,QString)","조회구분",'2') | 236 | + ret = self.dynamicCall("GetCommData(QString, QString, int, QString", sTrCode, sRecordName, nIndex, sItemName) |
128 | - self.dynamicCall("CommRqData(QString,QString,int,QString)","계좌평가잔고내역요청","opw00018",sPreNext,"2000") | 237 | + return ret.strip() |
129 | - | 238 | + |
130 | - self.detail_account_info_event_loop.exec_() | 239 | + # 조회수신한 멀티데이터의 갯수(반복)을 얻는다 |
131 | - | 240 | + # param : sTrCode - tr이름 |
132 | - # detail information about outstanding order | 241 | + # sRecordName - 레코드 이름 |
133 | - def not_concluded_account(self,sPrevNext="0"): | 242 | + def _get_repeat_cnt(self,sTrCode,sRecordName): |
134 | - self.dynamicCall("SetInputValue(QString,QString)","계좌번호",self.account_no) | 243 | + try: |
135 | - self.dynamicCall("SetInputValue(QString,QString)","체결구분",'1') | 244 | + ret=self.dynamicCall("GetRepeatCnt(QString, QString)",sTrCode,sRecordName) |
136 | - self.dynamicCall("SetInputValue(QString,QString)","매매구분",'0') | 245 | + return ret |
137 | - self.dynamicCall("CommRqData(QString,QString,int,QString)","실시간미체결요청",'opt10075',sPrevNext,self.screen_my_info) | 246 | + except Exception as e: |
138 | - | 247 | + print(e) |
139 | - self.detail_account_info_event_loop.exec_() | 248 | + sys.exit() |
140 | - | ||
141 | - # slot receiving tr request | ||
142 | - # param sScrNo: 스크린번호 | ||
143 | - # param sRQName: 요청했을 때 지은 이름 | ||
144 | - # param sTrCode: 요청 id, tr코드 | ||
145 | - # param sRecordName: 레코드 이름 | ||
146 | - # param sPrevNext: 다음 페이지가 있는지 여부. "2" : 다음페이지 존재, "0" or "" : 다음페이지 없음 | ||
147 | - def trdata_slot(self,sScrNo,sRQName,sTrCode,sRecordName,sPrevNext): | ||
148 | - if sRQName=="예수금상세현황요청": | ||
149 | - deposit=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,0,"예수금") | ||
150 | - possible=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,0,"출금가능금액") | ||
151 | - order_possible=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,0,"주문가능금액") | ||
152 | - | ||
153 | - self.user_money=int(deposit)*self.user_money_percent | ||
154 | - self.user_money=self.user_money/4 | ||
155 | - | ||
156 | - print("예수금 : ",int(deposit)) | ||
157 | - print("출금가능금액 : ",int(possible)) | ||
158 | - print("주문가능금액 : ",int(order_possible)) | ||
159 | - | ||
160 | - self.detail_account_info_event_loop.exit() | ||
161 | - | ||
162 | - elif sRQName=="계좌평가잔고내역요청": | ||
163 | - total_buy_money = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, 0, "총매입금액") | ||
164 | - total_profit_rate=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,0,"총수익률(%)") | ||
165 | - print("총매입금액 : ",int(total_buy_money)) | ||
166 | - print("총수익률(%) : ",float(total_profit_rate)) | ||
167 | - | ||
168 | - rows=self.dynamicCall("GetRepeatCnt(QString,QString)",sTrCode,sRQName) # 보유종목수 반환 | ||
169 | - cnt=0 | ||
170 | - for i in range(rows): | ||
171 | - code=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"종목번호") | ||
172 | - code=code.strip()[1:] | ||
173 | - | ||
174 | - code_nm = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "종목명") | ||
175 | - stock_quantity=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"보유수량") | ||
176 | - buy_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"매입가") | ||
177 | - learn_rate=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"수익률(%)") | ||
178 | - current_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"현재가") | ||
179 | - total_chegual_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"매입금액") | ||
180 | - possible_quantity=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"매매가능수량") | ||
181 | - | ||
182 | - if code in self.account_stock_dict: | ||
183 | - pass | ||
184 | - else: | ||
185 | - self.account_stock_dict.update({code:{}}) | ||
186 | - | ||
187 | - code_nm=code_nm.strip() | ||
188 | - buy_price=int(buy_price.strip()) | ||
189 | - learn_rate=float(learn_rate.strip()) | ||
190 | - current_price=int(current_price.strip()) | ||
191 | - total_chegual_price=int(total_chegual_price) | ||
192 | - possible_quantity=int(possible_quantity) | ||
193 | - | ||
194 | - acd=self.account_stock_dict[code] | ||
195 | - | ||
196 | - acd.update({"종목명":code_nm}) | ||
197 | - acd.update({"보유수량":stock_quantity}) | ||
198 | - acd.update({"매입가":buy_price}) | ||
199 | - acd.update({"수익률(%)":learn_rate}) | ||
200 | - acd.update({"현재가":current_price}) | ||
201 | - acd.update({"매입금액":total_chegual_price}) | ||
202 | - acd.update({"매매가능수량":possible_quantity}) | ||
203 | - | ||
204 | - cnt+=1 | ||
205 | - | ||
206 | - print("계좌 종목 : ",self.account_stock_dict) | ||
207 | - print("계좌 종목 수 : ",cnt) | ||
208 | - | ||
209 | - if sPrevNext=="2": | ||
210 | - self.detail_account_mystock(sPreNext="2") # If the next page exists, repeat the process | ||
211 | - else: | ||
212 | - self.detail_account_info_event_loop.exit() | ||
213 | - | ||
214 | - elif sRQName=="실시간미체결요청": | ||
215 | - rows=self.dynamicCall("GetRepeatCnt(QString,QString)",sTrCode,sRQName) | ||
216 | - for i in range(rows): | ||
217 | - code=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"종목번호") | ||
218 | - code=code.strip() | ||
219 | - code_nm = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "종목명") | ||
220 | - order_no = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "주문번호") | ||
221 | - order_status = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "주문상태") # 접수, 확인, 체결 | ||
222 | - order_quantity = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "주문수량") | ||
223 | - order_price = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "주문가격") | ||
224 | - order_gubun = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "주문구분") # 매도, 매수, | ||
225 | - not_quantity= self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "미체결수량") | ||
226 | - ok_quantity = self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, i, "체결량") | ||
227 | - | ||
228 | - code_nm=code_nm.strip() | ||
229 | - order_no=int(order_no.strip()) | ||
230 | - order_status=order_status.strip() | ||
231 | - order_quantity=int(order_quantity.strip()) | ||
232 | - order_price=int(order_price.strip()) | ||
233 | - order_gubun=order_gubun.lstrip("+").lstrip('-') | ||
234 | - not_quantity=int(not_quantity.strip()) | ||
235 | - ok_quantity=int(ok_quantity.strip()) | ||
236 | - | ||
237 | - if order_no in self.not_account_stock_dict: | ||
238 | - pass | ||
239 | - else: | ||
240 | - self.not_account_stock_dict[order_no]={} | ||
241 | - | ||
242 | - nasd=self.not_account_stock_dict[order_no] | ||
243 | - | ||
244 | - nasd.update({"종목코드":code}) | ||
245 | - nasd.update({"주문명":code_nm}) | ||
246 | - nasd.update({"주분번호":order_no}) | ||
247 | - nasd.update({"주문상태":order_status}) | ||
248 | - nasd.update({"주문수량":order_quantity}) | ||
249 | - nasd.update({"주문가격":order_price}) | ||
250 | - nasd.update({"주문구분":order_gubun}) | ||
251 | - nasd.update({"미체결수량":not_quantity}) | ||
252 | - nasd.update({"체결량":ok_quantity}) | ||
253 | - | ||
254 | - print("미체결 종목",self.not_account_stock_dict[order_no]) | ||
255 | - | ||
256 | - self.detail_account_info_event_loop.exit() | ||
257 | - | ||
258 | - elif sRQName=="주식일봉차트조회": | ||
259 | - code=self.dynamicCall("GetCommData(QString,QString,int,QString)", sTrCode, sRQName, "0", "종목코드") | ||
260 | - code=code.strip() | ||
261 | - print(code," 일봉데이터 요청") | ||
262 | - | ||
263 | - cnt=self.dynamicCall("GetRepeatCnt(QString,QString)",sTrCode,sRQName) | ||
264 | - print("데이터 일수", cnt) | ||
265 | - | ||
266 | - # 한 번 조회시 600일치까지 조회 가능 | ||
267 | - for i in range(cnt): | ||
268 | - data=[] | ||
269 | - | ||
270 | - current_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"현재가") # 종가 | ||
271 | - value=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"거래량") | ||
272 | - trading_value=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"거래대금") | ||
273 | - date=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"일자") | ||
274 | - start_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"시가") | ||
275 | - high_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"고가") | ||
276 | - low_price=self.dynamicCall("GetCommData(QString,QString,int,QString)",sTrCode,sRQName,i,"저가") | ||
277 | - | ||
278 | - data.append("") | ||
279 | - data.append(current_price.strip()) | ||
280 | - data.append(value.strip()) | ||
281 | - data.append(trading_value.strip()) | ||
282 | - data.append(date.strip()) | ||
283 | - data.append(start_price.strip()) | ||
284 | - data.append(high_price.strip()) | ||
285 | - data.append(low_price.strip()) | ||
286 | - | ||
287 | - self.calc_data.append(data.copy()) | ||
288 | - | ||
289 | - print(len(self.calc_data)) | ||
290 | - | ||
291 | - if sPrevNext=="2": | ||
292 | - self.day_kiwoom_db(code=code,sPrevNext=sPrevNext) | ||
293 | - else: | ||
294 | - self.calculator_event_loop.exit() | ||
295 | - | ||
296 | - # 종목 코드를 반환 | ||
297 | - def get_code_list_by_market(self,market_code): | ||
298 | - code_list=self.dynamicCall("GetCodeListByMarket(QString)",market_code) | ||
299 | - code_list=code_list.split(";")[:-1] | ||
300 | - return code_list | ||
301 | - | ||
302 | - # 종목 분석 실행용 함수 | ||
303 | - def calculator_fnc(self): | ||
304 | - code_list=self.get_code_list_by_market("10") | ||
305 | - print("코스닥 갯수",len(code_list)) | ||
306 | - | ||
307 | - for idx,code in enumerate(code_list): | ||
308 | - self.dynamicCall("DisconnectRealData(QString)",self.screen_calculation_stock) | ||
309 | - print("%s / %s : KOSDAQ Stock Code : %s is updating..."%(idx+1,len(code_list),code)) | ||
310 | - self.day_kiwoom_db(code=code) | ||
311 | - | ||
312 | - def day_kiwoom_db(self,code=None, date=None, sPrevNext="0"): | ||
313 | - | ||
314 | - QTest.qWait(TR_REQ_TIME_INTERVAL) | ||
315 | - | ||
316 | - self.dynamicCall("SetInputValue(QString,QString)","종목코드",code) | ||
317 | - self.dynamicCall("SetInputValue(QString,QString)","수정주가구분","1") | ||
318 | - if date!=None: | ||
319 | - self.dynamicCall("SetInputValue(QString,QString)","기준일자",date) | ||
320 | - self.dynamicCall("CommRqData(QString,QString,int,QString)","주식일봉차트조회","opt10081",sPrevNext,self.screen_calculation_stock) | ||
321 | - | ||
322 | - self.calculator_event_loop.exec_() | ||
323 | - | ||
324 | 249 | ||
325 | if __name__ == "__main__": | 250 | if __name__ == "__main__": |
326 | app = QApplication(sys.argv) | 251 | app = QApplication(sys.argv) | ... | ... |
-
Please register or login to post a comment