이하영

collector_api

1 +from collections import OrderedDict
2 +from sqlalchemy import Integer, Text
3 +import numpy
4 +import pathlib
5 +import os
6 +import time
7 +from PyQt5.QtWidgets import *
8 +from pandas import DataFrame
9 +
10 +from open_api import *
11 +from daily_buy_list import *
12 +
13 +# open_api를 이용하여 데이터베이스에 정보를 저장하는 클래스
14 +class collector_api():
15 + def __init__(self):
16 + self.open_api = open_api()
17 + self.engine_bot = self.open_api.engine_bot
18 + self.variable_setting()
19 +
20 + # 변수설정
21 + def variable_setting(self):
22 + self.open_api.py_gubun = "collector" # 용도를 저장하는 변수. collector : 데이터 저장 / trader : 종목 거래
23 + self.dc = daily_crawler(self.open_api.cf.real_db_name, self.open_api.cf.real_daily_craw_db_name,
24 + self.open_api.cf.real_daily_buy_list_db_name)
25 + self.dbl = daily_buy_list()
26 +
27 + # 콜렉팅을 실행하는 함수
28 + def code_update_check(self):
29 + logger.debug("code_update_check function")
30 + query = "select jango_data_db_check, possessed_item, today_profit, final_chegyul_check, " \
31 + "db_to_buy_list,today_buy_list, daily_crawler , min_crawler, daily_buy_list from setting_data limit 1"
32 +
33 + rows = self.engine_bot.execute(query).fetchall()
34 +
35 + # 잔고/보유종목 업데이트 확인
36 + if rows[0][0] != self.open_api.today or rows[0][1] != self.open_api.today:
37 + self.py_check_balance()
38 + self.open_api.set_invest_unit()
39 +
40 + # possessed_item(현재 보유종목) 테이블 업데이트
41 + if rows[0][1] != self.open_api.today:
42 + self.open_api.db_to_possesed_item()
43 + self.open_api.setting_data_possesed_item()
44 +
45 + # 당일 종목별 실현 손익 내역 테이블 업데이트
46 + if rows[0][2] != self.open_api.today:
47 + self.db_to_today_profit_list()
48 +
49 + # daily_craw 데이터베이스 업데이트
50 + if rows[0][6] != self.open_api.today:
51 + self.daily_crawler_check()
52 +
53 + # daily_buy_list 데이터베이스 업데이트
54 + if rows[0][8] != self.open_api.today:
55 + self.daily_buy_list_check()
56 +
57 + # 매수/매도 후 daily_buy_list 데이터베이스 업데이트
58 + if rows[0][3] != self.open_api.today:
59 + self.open_api.chegyul_check() # 매수 후 all_stocks에 저장되지 않은 종목 처리
60 + self.open_api.final_chegyul_check() # # 매도 후 all_stocks에 sell_date가 업데이트 되지 않은 항목 처리
61 +
62 + # 다음날 매수 종목 테이블(realtime_daily_buy_list) 업데이트
63 + if rows[0][5] != self.open_api.today:
64 + self.realtime_daily_buy_list_check()
65 +
66 + # min_craw db (분별 데이터) 업데이트
67 + if rows[0][7] != self.open_api.today:
68 + self.min_crawler_check()
69 +
70 + logger.debug("collecting 작업을 모두 정상적으로 마쳤습니다.")
71 +
72 + # cmd 콘솔창 종료
73 + os.system("@taskkill /f /im cmd.exe")
74 +
75 + # 매수 종목 설정 함수
76 + def realtime_daily_buy_list_check(self):
77 + # daily_buy_list 데이터베이스에 오늘 날짜의 테이블이 존재하는 경우, realtime_daily_buy_list 테이블 생성
78 + if self.open_api.sf.is_date_exist(self.open_api.today):
79 + self.open_api.sf.get_date_for_simul()
80 + self.open_api.sf.db_to_realtime_daily_buy_list(self.open_api.today, self.open_api.today, len(self.open_api.sf.date_rows))
81 +
82 + # all_stocks 테이블을 오늘 일자 데이터로 업데이트 한다.
83 + self.open_api.sf.update_all_db_by_date(self.open_api.today)
84 + self.open_api.rate_check()
85 + # realtime_daily_buy_list(매수 리스트) 테이블 세팅을 완료 후, setting_data의 today_buy_list에 오늘 날짜를 저장
86 + query = "UPDATE setting_data SET today_buy_list='%s' limit 1"
87 + self.engine_bot.execute(query % (self.open_api.today))
88 +
89 + else:
90 + logger.debug(
91 + """daily_buy_list DB에 {} 테이블이 없습니다. realtime_daily_buy_list 테이블을 생성 할 수 없습니다.
92 + 아래 내역을 확인하세요.
93 + 1. 장이 열리지 않은 날 혹은 15시 30분 ~ 23시 59분 사이에 콜렉터를 돌리지 않은 경우
94 + 2. 콜렉터를 오늘 날짜 까지 돌리지 않아 daily_buy_list의 오늘 날짜 테이블이 없는 경우
95 + """.format(self.open_api.today))
96 +
97 + # daily_buy_list 데이터베이스에 테이블이 존재하는지 확인하는 함수
98 + def is_table_exist_daily_buy_list(self, date):
99 + query = "select 1 from information_schema.tables where table_schema ='daily_buy_list' and table_name = '%s'"
100 + rows = self.open_api.engine_daily_buy_list.execute(query % (date)).fetchall()
101 +
102 + if len(rows) == 1:
103 + return True
104 + elif len(rows) == 0:
105 + return False
106 +
107 + # min_craw 데이터베이스에 테이블이 존재하는지 확인하는 함수
108 + def is_table_exist(self, db_name, table_name):
109 + query = "select 1 from information_schema.tables where table_schema ='{}' and table_name = '{}'"
110 + rows = self.open_api.engine_craw.execute(query.format(db_name, table_name)).fetchall()
111 + if len(rows) == 1:
112 + return True
113 + elif len(rows) == 0:
114 + return False
115 +
116 + # daily_buy_list 테이블 생성 및 데이터 저장하는 함수
117 + def daily_buy_list_check(self):
118 + self.dbl.daily_buy_list()
119 +
120 + query = "UPDATE setting_data SET daily_buy_list='%s' limit 1"
121 + self.engine_bot.execute(query % (self.open_api.today))
122 +
123 + # min_craw 데이터베이스 생성 함수
124 + def db_to_min_craw(self):
125 + query = "select code,code_name,check_min_crawler from stock_item_all"
126 + target_code = self.open_api.engine_daily_buy_list.execute(query).fetchall()
127 + num = len(target_code)
128 +
129 + query = "UPDATE stock_item_all SET check_min_crawler='%s' WHERE code='%s'"
130 +
131 + for i in range(num):
132 + # check_item이 0이 아니면 다음 항목 처리
133 + if int(target_code[i][2]) != 0:
134 + continue
135 +
136 + code = target_code[i][0]
137 + code_name = target_code[i][1]
138 +
139 + logger.debug("++++++++++++++" + str(code_name) + "++++++++++++++++++++" + str(i + 1) + '/' + str(num))
140 +
141 + check_item_gubun = self.set_min_crawler_table(code, code_name)
142 +
143 + self.open_api.engine_daily_buy_list.execute(query % (check_item_gubun, code))
144 +
145 + # 당일 daily_craw 데이터베이스의 업데이트 내역을 확인하고, 업데이트를 실행하는 함수
146 + def db_to_daily_craw(self):
147 + query = "select code,code_name,check_daily_crawler from stock_item_all"
148 +
149 + target_code = self.open_api.engine_daily_buy_list.execute(query).fetchall()
150 + num = len(target_code)
151 + query = "UPDATE stock_item_all SET check_daily_crawler='%s' WHERE code='%s'"
152 +
153 + # check_daily_crawler : daily_craw 데이터베이스를 업데이트 했는지 확인하는 변수
154 + # 1: 당일 업데이트 완료 / 3 : 과거에 업데이트 완료 / 0 : 업데이트 전 / 4 : daily_buy_list에 내용 변동을 업데이트 필요
155 + # check_daily_crawler이 1,3이 아닌 경우 업데이트 실행
156 + for i in range(num):
157 + if int(target_code[i][2]) in (1, 3):
158 + continue
159 +
160 + code = target_code[i][0]
161 + code_name = target_code[i][1]
162 +
163 + logger.debug("++++++++++++++" + str(code_name) + "++++++++++++++++++++" + str(i + 1) + '/' + str(num))
164 +
165 + check_item_gubun = self.set_daily_crawler_table(code, code_name)
166 +
167 + self.open_api.engine_daily_buy_list.execute(query % (check_item_gubun, code))
168 +
169 + # min_crawler 데이터베이스에 콜렉팅을 완료했는지 확인하는 함수
170 + def min_crawler_check(self):
171 + self.db_to_min_craw()
172 +
173 + query = "UPDATE setting_data SET min_crawler='%s' limit 1"
174 + self.engine_bot.execute(query % (self.open_api.today))
175 +
176 + # daily_crawler 데이터베이스에 콜렉팅을 완료했는지 확인하는 함수
177 + def daily_crawler_check(self):
178 + self.db_to_daily_craw()
179 + logger.debug("daily_crawler success !!!")
180 +
181 + sql = "UPDATE setting_data SET daily_crawler='%s' limit 1"
182 + self.engine_JB.execute(sql % (self.open_api.today))
183 +
184 + # 틱(1분 별) 데이터를 가져오는 함수
185 + def set_min_crawler_table(self, code, code_name):
186 + df = self.open_api.get_total_data_min(code, code_name, self.open_api.today)
187 +
188 + df_temp = DataFrame(df,
189 + columns=['date', 'check_item', 'code', 'code_name', 'd1_diff_rate',
190 + 'close', 'open', 'high','low','volume', 'sum_volume',
191 + 'clo5', 'clo10', 'clo20', 'clo60','clo120',
192 + "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate", "clo60_diff_rate",
193 + "clo120_diff_rate",
194 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60', 'yes_clo120',
195 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120'
196 + ])
197 +
198 + df_temp = df_temp.sort_values(by=['date'], ascending=True)
199 +
200 + df_temp['code'] = code
201 + df_temp['code_name'] = code_name
202 + d1_diff_rate = round((df_temp['close'] - df_temp['close'].shift(1)) / df_temp['close'].shift(1) * 100, 2)
203 + df_temp['d1_diff_rate'] = d1_diff_rate.replace(numpy.inf, numpy.nan)
204 +
205 + clo5 = df_temp['close'].rolling(window=5).mean()
206 + clo10 = df_temp['close'].rolling(window=10).mean()
207 + clo20 = df_temp['close'].rolling(window=20).mean()
208 + clo60 = df_temp['close'].rolling(window=60).mean()
209 + clo120 = df_temp['close'].rolling(window=120).mean()
210 + df_temp['clo5'] = round(clo5, 2)
211 + df_temp['clo10'] = round(clo10, 2)
212 + df_temp['clo20'] = round(clo20, 2)
213 + df_temp['clo60'] = round(clo60, 2)
214 + df_temp['clo120'] = round(clo120, 2)
215 +
216 + df_temp['clo5_diff_rate'] = round((df_temp['close'] - clo5) / clo5 * 100, 2)
217 + df_temp['clo10_diff_rate'] = round((df_temp['close'] - clo10) / clo10 * 100, 2)
218 + df_temp['clo20_diff_rate'] = round((df_temp['close'] - clo20) / clo20 * 100, 2)
219 + df_temp['clo60_diff_rate'] = round((df_temp['close'] - clo60) / clo60 * 100, 2)
220 + df_temp['clo120_diff_rate'] = round((df_temp['close'] - clo120) / clo120 * 100, 2)
221 +
222 + df_temp['yes_clo5'] = df_temp['clo5'].shift(1)
223 + df_temp['yes_clo10'] = df_temp['clo10'].shift(1)
224 + df_temp['yes_clo20'] = df_temp['clo20'].shift(1)
225 + df_temp['yes_clo60'] = df_temp['clo60'].shift(1)
226 + df_temp['yes_clo120'] = df_temp['clo120'].shift(1)
227 +
228 + df_temp['vol5'] = df_temp['volume'].rolling(window=5).mean()
229 + df_temp['vol10'] = df_temp['volume'].rolling(window=10).mean()
230 + df_temp['vol20'] = df_temp['volume'].rolling(window=20).mean()
231 + df_temp['vol60'] = df_temp['volume'].rolling(window=60).mean()
232 + df_temp['vol120'] = df_temp['volume'].rolling(window=120).mean()
233 +
234 + # 분별 테이블이 존재한다면, 가장 최근의 분 데이터 이후의 값을 저장
235 + if self.open_api.craw_table_exist:
236 + df_temp = df_temp[df_temp.date > self.open_api.craw_db_last_min]
237 +
238 + # 추가할 내역이 없다면, check_item_gubun=3
239 + if len(df_temp) == 0:
240 + time.sleep(0.03)
241 + check_item_gubun = 3
242 + return check_item_gubun
243 +
244 + df_temp[['close', 'open', 'high', 'low', 'volume', 'sum_volume', 'clo5', 'clo10', 'clo20', 'clo60','clo120',
245 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
246 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120']] = \
247 + df_temp[
248 + ['close', 'open', 'high', 'low', 'volume', 'sum_volume', 'clo5', 'clo10', 'clo20', 'clo60', 'clo120',
249 + 'yes_clo5', 'yes_clo10', 'yes_clo20','yes_clo60', 'yes_clo120',
250 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120']].fillna(0).astype(int)
251 +
252 + temp_date = self.open_api.craw_db_last_min
253 + sum_volume = self.open_api.craw_db_last_min_sum_volume
254 +
255 + for i in range(len(df_temp),-1,-1):
256 + try:
257 + temp_index = i
258 +
259 + # 데이터가 하루 이상 차이날 경우, sum_volume 초기화
260 + if ((int(df_temp.loc[temp_index, 'date']) - int(temp_date)) > 9000):
261 + sum_volume = 0
262 +
263 + temp_date = df_temp.loc[temp_index, 'date']
264 + # 분별로 sum_volume값 누적 저장
265 + sum_volume += df_temp.loc[temp_index, 'volume']
266 + df_temp.loc[temp_index, 'sum_volume'] = sum_volume
267 +
268 + except Exception as e:
269 + logger.critical(e)
270 +
271 + df_temp.to_sql(name=code_name, con=self.open_api.engine_craw, if_exists='append')
272 + # 콜렉팅하다가 max_api_call 횟수까지 가게 된 경우
273 + # 이후 콜렉팅 하지 못한 정보를 가져오기 위해 check_item_gubun=0
274 + if self.open_api.rq_count == cf.max_api_call - 1:
275 + check_item_gubun = 0
276 + # 정상완료한 경우 check_item_gubun=1
277 + else:
278 + check_item_gubun = 1
279 + return check_item_gubun
280 +
281 + # daily_crawler(종목별 일일 데이터) 테이블 생성 및 내역을 추가하는 함수
282 + # daily_crawler 테이블 업데이트 후, daily_buy_list(일별 종목 데이터) 테이블 생성 및 내역 추가
283 + def set_daily_crawler_table(self, code, code_name):
284 + df = self.open_api.get_total_data(code, code_name, self.open_api.today)
285 + oldest_row = df.iloc[-1] # 가장 최신 데이터
286 + check_row = None
287 +
288 + check_dc_query = "UPDATE daily_buy_list.stock_item_all SET check_daily_crawler = '4' WHERE code = '{}'"
289 +
290 + # 특정 종목명(code_name)의 테이블이 존재하는 경우
291 + if self.engine_bot.dialect.has_table(self.open_api.engine_daily_craw, code_name):
292 + query=f"select * from '{code_name}' where date='{oldest_row['date']}' limit 1"
293 + check_row = self.open_api.engine_daily_craw.execute(query).fetchall()
294 + # 종목명 테이블이 존재하지 않는 경우, 종목 리스트(stock_item_all) 테이블에 check_daily_crawler=4 업데이트
295 + else:
296 + self.engine_bot.execute(check_dc_query.format(code))
297 +
298 + # 종목 테이블에 저장된 가장 최신의 데이터가 실제 가장 최신 데이터와 같지 않다면 다시 테이블 삭제 후 다시 생성
299 + if check_row and check_row[0]['close'] != oldest_row['close']:
300 + # 테이블 삭제
301 + logger.info('daily_craw와 min_craw 삭제 중..')
302 + commands = [
303 + f"DROP TABLE IF EXISTS daily_craw.'{code_name}'",
304 + f"DROP TABLE IF EXISTS min_craw.'{code_name}"
305 + ]
306 +
307 + for com in commands:
308 + self.open_api.engine_daily_buy_list.execute(com)
309 + logger.info('삭제 완료')
310 +
311 + # 테이블 생성
312 + df = self.open_api.get_total_data(code, code_name, self.open_api.today)
313 + self.engine_bot.execute(check_dc_query.format(code))
314 +
315 + query=f"select check_daily_crawler from daily_buy_list.stock_item_all where code='{code}'"
316 + check_daily_crawler = self.engine_bot.execute(query).fetchall()[0].check_daily_crawler
317 +
318 + df_temp = DataFrame(df,
319 + columns=['date', 'check_item', 'code', 'code_name', 'd1_diff_rate',
320 + 'close', 'open', 'high','low','volume',
321 + 'clo5', 'clo10', 'clo20', 'clo60', 'clo120',
322 + "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate", "clo60_diff_rate",
323 + "clo120_diff_rate",
324 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60', 'yes_clo120',
325 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120', 'vol80'
326 + ])
327 +
328 + df_temp = df_temp.sort_values(by=['date'], ascending=True)
329 +
330 + df_temp['code'] = code
331 + df_temp['code_name'] = code_name
332 + df_temp['d1_diff_rate'] = round(
333 + (df_temp['close'] - df_temp['close'].shift(1)) / df_temp['close'].shift(1) * 100, 2)
334 +
335 + clo5 = df_temp['close'].rolling(window=5).mean()
336 + clo10 = df_temp['close'].rolling(window=10).mean()
337 + clo20 = df_temp['close'].rolling(window=20).mean()
338 + clo60 = df_temp['close'].rolling(window=60).mean()
339 + clo120 = df_temp['close'].rolling(window=120).mean()
340 + df_temp['clo5'] = clo5
341 + df_temp['clo10'] = clo10
342 + df_temp['clo20'] = clo20
343 + df_temp['clo60'] = clo60
344 + df_temp['clo120'] = clo120
345 +
346 + df_temp['clo5_diff_rate'] = round((df_temp['close'] - clo5) / clo5 * 100, 2)
347 + df_temp['clo10_diff_rate'] = round((df_temp['close'] - clo10) / clo10 * 100, 2)
348 + df_temp['clo20_diff_rate'] = round((df_temp['close'] - clo20) / clo20 * 100, 2)
349 + df_temp['clo60_diff_rate'] = round((df_temp['close'] - clo60) / clo60 * 100, 2)
350 + df_temp['clo120_diff_rate'] = round((df_temp['close'] - clo120) / clo120 * 100, 2)
351 +
352 + df_temp['yes_clo5'] = df_temp['clo5'].shift(1)
353 + df_temp['yes_clo10'] = df_temp['clo10'].shift(1)
354 + df_temp['yes_clo20'] = df_temp['clo20'].shift(1)
355 + df_temp['yes_clo60'] = df_temp['clo60'].shift(1)
356 + df_temp['yes_clo120'] = df_temp['clo120'].shift(1)
357 +
358 + df_temp['vol5'] = df_temp['volume'].rolling(window=5).mean()
359 + df_temp['vol10'] = df_temp['volume'].rolling(window=10).mean()
360 + df_temp['vol20'] = df_temp['volume'].rolling(window=20).mean()
361 + df_temp['vol60'] = df_temp['volume'].rolling(window=60).mean()
362 + df_temp['vol120'] = df_temp['volume'].rolling(window=120).mean()
363 +
364 + # daily_craw테이블이 존재할 경우, 저장되어있는 날짜 이후의 값을 저장
365 + if self.engine_bot.dialect.has_table(self.open_api.engine_daily_craw, code_name):
366 + df_temp = df_temp[df_temp.date > self.open_api.get_daily_craw_db_last_date(code_name)]
367 +
368 + # 데이터가 없거나 이미 데이터 콜렉팅을 완료한 경우, check_item_gubun=3으로 설정
369 + if len(df_temp) == 0 and check_daily_crawler != '4':
370 + time.sleep(0.03)
371 + check_item_gubun = 3
372 + return check_item_gubun
373 +
374 + df_temp[['close', 'open', 'high', 'low', 'volume', 'clo5', 'clo10', 'clo20', 'clo60','clo120',
375 + 'yes_clo5', 'yes_clo10', 'yes_clo20','yes_clo60', 'yes_clo80','yes_clo120',
376 + 'vol5', 'vol10', 'vol20', 'vol40', 'vol60', 'vol80', 'vol100', 'vol120']] = \
377 + df_temp[
378 + ['close', 'open', 'high', 'low', 'volume', 'clo5', 'clo10', 'clo20','clo60','clo120',
379 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
380 + 'vol5', 'vol10', 'vol20', 'vol40', 'vol60', 'vol80', 'vol100', 'vol120']].fillna(0).astype(int)
381 +
382 + df_temp.to_sql(name=code_name, con=self.open_api.engine_daily_craw, if_exists='append')
383 +
384 + # check_daily_crawler 가 4 인 경우는 액면분할, 증자 등으로 인해 daily_buy_list 업데이트를 해야하는 경우
385 + # 업데이트 완료 후 check_item_gubun=1
386 + if check_daily_crawler == '4':
387 + logger.info(f'daily_craw.{code_name} 업데이트 완료 {code}')
388 + logger.info('daily_buy_list 업데이트 중..')
389 +
390 + query="SELECT table_name as tname FROM information_schema.tables " \
391 + "WHERE table_schema ='daily_buy_list' AND table_name REGEXP '[0-9]{8}"
392 + dbl_dates = self.open_api.engine_daily_buy_list.execute(query).fetchall()
393 +
394 + for row in dbl_dates:
395 + logger.info(f'{code} {code_name} - daily_buy_list.`{row.tname}` 업데이트')
396 + try:
397 + new_data = df_temp[df_temp['date'] == row.tname]
398 + except IndexError:
399 + continue
400 + query=f"delete from '{row.tname}' where code={code}"
401 + self.open_api.engine_daily_buy_list.execute(query)
402 + new_data.to_sql(name=row.tname, con=self.open_api.engine_daily_buy_list, if_exists='append')
403 +
404 + logger.info('daily_buy_list 업데이트 완료')
405 +
406 + check_item_gubun = 1
407 + return check_item_gubun
408 +
409 + # today_profit_list 테이블 생성 및 내역 추가 함수
410 + def db_to_today_profit_list(self):
411 + self.open_api.reset_opt10073_output()
412 +
413 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
414 + self.open_api.set_input_value("시작일자", self.open_api.today)
415 + self.open_api.set_input_value("종료일자", self.open_api.today)
416 +
417 + self.open_api.comm_rq_data("opt10073_req", "opt10073", 0, "0328")
418 +
419 + while self.open_api.remained_data:
420 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
421 + self.open_api.comm_rq_data("opt10073_req", "opt10073", 2, "0328")
422 +
423 + today_profit_item_temp = {'date': [], 'code': [], 'code_name': [], 'amount': [], 'today_profit': [],
424 + 'earning_rate': []}
425 +
426 + today_profit_item = DataFrame(today_profit_item_temp,
427 + columns=['date', 'code', 'code_name', 'amount', 'today_profit',
428 + 'earning_rate'])
429 +
430 + item_count = len(self.open_api.opt10073_output['multi'])
431 + for i in range(item_count):
432 + row = self.open_api.opt10073_output['multi'][i]
433 + today_profit_item.loc[i, 'date'] = row[0] # 날짜
434 + today_profit_item.loc[i, 'code'] = row[1] # 종목코드
435 + today_profit_item.loc[i, 'code_name'] = row[2] # 종목명
436 + today_profit_item.loc[i, 'amount'] = int(row[3]) # 보유수량
437 + today_profit_item.loc[i, 'today_profit'] = float(row[4]) # 당일실현손익
438 + today_profit_item.loc[i, 'earning_rate'] = float(row[5]) # 수익률
439 +
440 + if len(today_profit_item) > 0:
441 + today_profit_item.to_sql('today_profit_list', self.engine_bot, if_exists='append')
442 + query = "UPDATE setting_data SET today_profit='%s' limit 1"
443 + self.engine_bot.execute(query % (self.open_api.today))
444 +
445 + # jango 테이블 생성 및 내역 추가 함수
446 + def db_to_jango(self):
447 + self.total_invest = self.open_api.change_format(
448 + str(int(self.open_api.d2_deposit_before_format) + int(self.open_api.total_purchase_price)))
449 + jango_temp = {'id': [], 'date': [], 'total_asset': [], 'today_profit': [], 'total_profit': [],
450 + 'total_invest': [], 'd2_deposit': [],
451 + 'today_purchase': [], 'today_evaluation': [],
452 + 'today_invest': [], 'today_rate': [],
453 + 'estimate_asset': []}
454 +
455 + jango_col_list = ['date',
456 + 'today_earning_rate','total_evaluation',
457 + 'total_profit', 'total_invest',
458 + 'total_valuation','total_purchase','total_rate','today_profit','estimate_asset','d2_deposit',
459 + 'volume_limit','sell_point','invest_limit_rate', 'invest_unit','limit_money',
460 + 'total_profitcut','total_losscut','total_profitcut_count', 'total_losscut_count',
461 + 'today_buy_count','total_sell_count','total_possess_count']
462 +
463 + jango = DataFrame(jango_temp,
464 + columns=jango_col_list,
465 + index=jango_temp['id'])
466 +
467 + jango.loc[0, 'date'] = self.open_api.today # 날짜
468 + jango.loc[0, 'total_evaluation'] = self.open_api.change_total_eval_price # 총평가금액
469 + jango.loc[0, 'total_profit'] = self.open_api.total_profit # 실현손익
470 + jango.loc[0, 'total_invest'] = self.total_invest # 총투자금액
471 + jango.loc[0, 'total_valuation'] = self.open_api.change_total_eval_profit_loss_price # 총평가손익금액
472 + jango.loc[0, 'total_purchase'] = self.open_api.change_total_purchase_price # 총매입금액
473 +
474 + jango.loc[0, 'total_rate'] = float(self.open_api.change_total_earning_rate) / self.open_api.mod_gubun # 총수익률
475 + jango.loc[0, 'today_profit'] = self.open_api.today_profit # 당일매도손익
476 + jango.loc[0, 'estimate_asset'] = self.open_api.change_estimated_deposit # 추정예탁자산
477 + jango.loc[0, 'd2_deposit'] = self.open_api.d2_deposit # 예수금
478 + jango.loc[0, 'volume_limit'] = self.open_api.sf.volume_limit
479 +
480 + jango.loc[0, 'sell_point'] = self.open_api.sf.sell_point # 매도기준수익률
481 + jango.loc[0, 'invest_limit_rate'] = self.open_api.sf.invest_limit_rate # 매수기준수익률
482 + jango.loc[0, 'invest_unit'] = self.open_api.invest_unit # 투자기준금액
483 + jango.loc[0, 'limit_money'] = self.open_api.sf.limit_money # 잔고에 남겨둘 최소금액
484 +
485 + # 당일 익절 금액(today_profitcut), 당일 손절 금액(today_losscut)
486 + if self.is_table_exist(self.open_api.db_name, "today_profit_list"):
487 + query = "select sum(today_profit) from today_profit_list where today_profit >='%s' and date = '%s'"
488 + rows = self.engine_bot.execute(query % (0, self.open_api.today)).fetchall()
489 + if rows[0][0] is not None:
490 + jango.loc[0, 'total_profitcut'] = int(rows[0][0])
491 + else:
492 + jango.loc[0,'total_profitcut']=0
493 +
494 + query = "select sum(today_profit) from today_profit_list where today_profit < '%s' and date = '%s'"
495 + rows = self.engine_bot.execute(query % (0, self.open_api.today)).fetchall()
496 + if rows[0][0] is not None:
497 + jango.loc[0, 'total_losscut'] = int(rows[0][0])
498 + else:
499 + jango.loc[0, 'total_losscut'] = 0
500 +
501 + # 총 익절 종목 수(total_profitcut_count)
502 + query = "select count(*) " \
503 + "from (select code from all_stocks where sell_rate >='%s' and sell_date like '%s' group by code)"
504 + rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall()
505 + jango.loc[0, 'total_profitcut_count'] = int(rows[0][0])
506 +
507 + # 총 손절 종목 수(total_losscut_count)
508 + query = "select count(*) " \
509 + "from (select code from all_stocks where sell_rate < '%s' and sell_date like '%s' group by code)"
510 + rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall()
511 + jango.loc[0, 'total_losscut_count'] = int(rows[0][0])
512 +
513 + # jango_data 테이블 생성 및 데이터 추가
514 + jango.to_sql('jango_data', self.engine_bot, if_exists='append')
515 +
516 + query = "select date from jango_data"
517 + rows = self.engine_bot.execute(query).fetchall()
518 +
519 + for i in range(len(rows)):
520 + # 당일 수익률 (today_earning_rate)
521 + query = "update jango_data set " \
522 + "today_earning_rate =round(today_profit / total_invest * '%s',2) WHERE date='%s'"
523 + self.engine_bot.execute(query % (100, rows[i][0]))
524 +
525 + # 당일 구매 종목 수 (today_buy_count)
526 + query = "UPDATE jango_data SET " \
527 + "today_buy_count=" \
528 + "(select count(*) from (select code from all_stocks where buy_date like '%s' group by code)) " \
529 + "WHERE date='%s'"
530 + self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
531 +
532 + # 총 매수 종목 수 (total_sell_count)
533 + query = "UPDATE jango_data SET " \
534 + "total_sell_count=" \
535 + "(select count(*) from " \
536 + "(select code from all_stocks a where sell_date!='0' group by code) temp)"\
537 + "WHERE date='%s'"
538 + self.engine_bot.execute(query % (rows[i][0]))
539 +
540 + # 총 보유 종목 수 (total_possess_count)
541 + query = "UPDATE jango_data SET " \
542 + "today_buy_total_possess_count=" \
543 + "(select count(*) from (select code from all_stocks where sell_date = '0' group by code )) " \
544 + "WHERE date='%s'"
545 + self.engine_bot.execute(query % (rows[i][0]))
546 +
547 + query = "UPDATE setting_data SET jango_data_db_check='%s' limit 1"
548 + self.engine_bot.execute(query % (self.open_api.today))
549 +
550 + # 계좌정보 확인 함수
551 + def py_check_balance(self):
552 + logger.debug("py_check_balance!!!")
553 +
554 + # 예수금상세현황
555 + self.open_api.reset_opw00018_output()
556 +
557 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
558 + self.open_api.set_input_value("비밀번호입력매체구분", 00)
559 + self.open_api.set_input_value("조회구분", 1)
560 + self.open_api.comm_rq_data("opw00001_req", "opw00001", 0, "2000")
561 +
562 + # 계좌평가잔고내역
563 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
564 + self.open_api.comm_rq_data("opw00018_req", "opw00018", 0, "2000")
565 +
566 + while self.open_api.remained_data:
567 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
568 + self.open_api.comm_rq_data("opw00018_req", "opw00018", 2, "2000")
569 +
570 + # 일자별실현손익
571 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
572 + self.open_api.set_input_value("시작일자", "20170101")
573 + self.open_api.set_input_value("종료일자", self.open_api.today)
574 +
575 + self.open_api.comm_rq_data("opt10074_req", "opt10074", 0, "0329")
576 + while self.open_api.remained_data:
577 + self.open_api.set_input_value("계좌번호", self.open_api.account_number)
578 + self.open_api.set_input_value("시작일자", "20170101")
579 + self.open_api.set_input_value("종료일자", "20180930")
580 +
581 + # 구분 = 0:전체, 1:입출금, 2:입출고, 3:매매, 4:매수, 5:매도, 6:입금, 7:출금, A:예탁담보대출입금, F:환전
582 + self.open_api.set_input_value("구분", "0")
583 + self.open_api.comm_rq_data("opt10074_req", "opt10074", 2, "0329")
584 +
585 + self.db_to_jango()
......
...@@ -41,7 +41,7 @@ def setup_sql_mod(dbapi_connection): ...@@ -41,7 +41,7 @@ def setup_sql_mod(dbapi_connection):
41 event.listen(Pool,'connect',setup_sql_mod) 41 event.listen(Pool,'connect',setup_sql_mod)
42 event.listen(Pool,'first_connect',setup_sql_mod) 42 event.listen(Pool,'first_connect',setup_sql_mod)
43 43
44 -class Open_Api(QAxWidget): 44 +class open_api(QAxWidget):
45 def __init__(self): 45 def __init__(self):
46 super().__init__() 46 super().__init__()
47 47
......