이하영

open_api 함수 추가

...@@ -237,8 +237,7 @@ class Simulator_Func: ...@@ -237,8 +237,7 @@ class Simulator_Func:
237 columns=['id', 'order_num', 'code', 'code_name', 'rate', 'purchase_rate', 237 columns=['id', 'order_num', 'code', 'code_name', 'rate', 'purchase_rate',
238 'purchase_price','present_price', 'valuation_price','valuation_profit', 238 'purchase_price','present_price', 'valuation_price','valuation_profit',
239 'holding_amount', 'buy_date', 'item_total_purchase','chegyul_check', 239 'holding_amount', 'buy_date', 'item_total_purchase','chegyul_check',
240 - 'invest_unit','sell_date', 'sell_price', 'sell_rate', 'rate_std', 240 + 'invest_unit','sell_date', 'sell_price', 'sell_rate',
241 - 'rate_std_mod_val','rate_std_htr', 'rate_htr','rate_std_mod_val_htr',
242 'yes_close', 'close', 'd1_diff_rate', 'd1_diff', 241 'yes_close', 'close', 'd1_diff_rate', 'd1_diff',
243 'open', 'high','low','volume', 242 'open', 'high','low','volume',
244 'clo5', 'clo10', 'clo20', 'clo60','clo120', 243 'clo5', 'clo10', 'clo20', 'clo60','clo120',
...@@ -1191,4 +1190,31 @@ class Simulator_Func: ...@@ -1191,4 +1190,31 @@ class Simulator_Func:
1191 # 매도 리스트가 존재하지 않는다면 매수만 진행 1190 # 매도 리스트가 존재하지 않는다면 매수만 진행
1192 else: 1191 else:
1193 if self.check_balance(): 1192 if self.check_balance():
1194 - self.auto_trade_buy_stock(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday)
...\ No newline at end of file ...\ No newline at end of file
1193 + self.auto_trade_buy_stock(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday)
1194 +
1195 + # daily_buy_list 데이터베이스에서 가장 최근의 날짜 테이블을 가져오는 함수
1196 + def get_recent_daily_buy_list_date(self):
1197 + query="select TABLE_NAME from information_schema.tables " \
1198 + "where table_schema = 'daily_buy_list' and TABLE_NAME like '%s' order by table_name desc limit 1"
1199 + row = self.engine_daily_buy_list.execute(query % ("20%%")).fetchall()
1200 +
1201 + if len(row) == 0:
1202 + return False
1203 + return row[0][0]
1204 +
1205 + # 최근 daily_buy_list의 날짜 테이블에서 code에 해당하는 데이터만 가져오는 함수
1206 + def get_daily_buy_list_by_code(self,code,date):
1207 + query = f"select * from `{date}` where code = '{code}' group by code"
1208 +
1209 + daily_buy_list = self.engine_daily_buy_list.execute(query).fetchall()
1210 +
1211 + df_daily_buy_list = DataFrame(daily_buy_list,
1212 + columns=['index', 'index2', 'date', 'check_item',
1213 + 'code', 'code_name', 'd1_diff', 'd1_diff_rate',
1214 + 'close', 'open','high', 'low', 'volume',
1215 + 'clo5', 'clo10', 'clo20', 'clo60', 'clo120',
1216 + "clo5_diff_rate", "clo10_diff_rate", "clo20_diff_rate",
1217 + "clo60_diff_rate", "clo120_diff_rate",
1218 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
1219 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120'])
1220 + return df_daily_buy_list
......
1 -from Open_Api import *
2 -from collections import OrderedDict
3 -from pandas import DataFrame
4 -import time
5 -
6 -from Daily_Info import *
7 -from Stock_Info import *
8 -import config
9 -
10 -class Collector_Api():
11 - def __init__(self):
12 - self.open_api=Open_Api()
13 - self.engine_bot=self.open_api.engine_bot
14 - self.set_variable()
15 -
16 - # 변수 설정
17 - def set_variable(self):
18 - self.open_api.use="collector"
19 - self.stock_info=Stock_Info(config.real_bot_name,config.real_dailyInfo_name,config.real_stockInfo_name)
20 - self.daily_info=Daily_Info()
21 -
22 - def code_update_check(self):
23 - query="select code_update,balance_to_db,posses_stocks,today_profit,contract_check,db_to_daily_info," \
24 - "today_buy_list,stock_info,min_info,daily_info from setting_data"
25 - result=self.engine_bot.execute(query).fetchall()
26 -
27 - today=self.open_api.today
28 -
29 - # 오늘 날짜에 종목리스트가 업데이트 되지 않았다면 업데이트를 실행
30 - if result[0][0]!=today:
31 - self.open_api.get_balance()
32 - self.get_code_list()
33 -
34 - # 계좌정보 업데이트
35 - if result[0][1]!=today or result[0][2]!=today:
36 - self.check_balance()
37 - self.open_api.set_per_invest()
38 -
39 - # 현재 보유종목 테이블 업데이트
40 - if result[0][2]!=today:
41 - self.open_api.get_posses_item()
42 - self.open_api.setting_data_posses_stock()
43 -
44 - # 수익률 테이블 업데이트
45 - if result[0][3]!=today:
46 - self.update_today_profit_list()
47 -
48 - # stock_info 테이블 업데이트
49 - if result[0][7]!=today:
50 - self.check_stock_info()
51 -
52 - if result[0][9]!=today:
53 - self.check_daily_info()
54 -
55 - if result[0][4]!=today:
56 - self.open_api.check_contract()
57 - self.open_api.final_check_contract()
58 -
59 - if result[0][6]!=today:
60 - self.realtime_daily_info_check()
61 -
62 -
63 - # 코스피, 코스닥 리스트 확인 및 데이터베이스 업데이트
64 - def get_code_list(self):
65 - self.stock_info.get_item_kospi()
66 - self.stock_info.get_item_kosdaq()
67 -
68 - stock_data=OrderedDict(
69 - kospi=self.stock_info.kospi_list,
70 - kosdaq=self.stock_info.kosdaq_list
71 - )
72 -
73 - for s_type,data in stock_data.items():
74 - stock_data[s_type]=self.create_stock_table(data,s_type)
75 -
76 - stock_all=stock_data['kospi'].append(stock_data['kosdaq'],ignore_index=True)
77 - self.create_stock_table(stock_all,"all")
78 - query="update setting_data set code_update='%s'"
79 - self.engine_bot.execute(query%(self.open_api.today))
80 -
81 - # kospi, kosdaq 주식 종목을 저장하는 테이블 생성
82 - def create_stock_table(self,data,type):
83 - checking=['kospi','kosdaq']
84 - stock_df=DataFrame()
85 - stock_df['code']=data['code']
86 - stock_list=list()
87 - # 주식 code를 이용하여 실제 kiwoom 증권에서 사용하는 주식이름으로 변경
88 - for kind in data.itertuples():
89 - kiwoom_name=self.open_api.dynamicCall("GetMasterCodeName(QString)",kind.code).strip()
90 - stock_list.append(kiwoom_name)
91 - stock_df['code_name']=stock_list
92 - stock_df['check_item']=0
93 -
94 - if type in checking:
95 - stock_df=stock_df[stock_df['code_name'].map(len)>0]
96 -
97 - if type=="all":
98 - stock_df['check_stock']="0"
99 - stock_df['check_min']="0"
100 -
101 - # 데이터 타입을 설정
102 - # code, code_name 칼럼은 Text. check_item 칼럼은 Integer
103 - dtypes=dict(zip(list(stock_df.columns),[Text]*len(stock_df.columns)))
104 - dtypes['check_item']=Integer
105 -
106 - table_name='stock_'+str(type)
107 - stock_df.to_sql(table_name,self.open_api.engine_daily,if_exists='replace',dtype=dtypes)
108 - return stock_df
109 -
110 - def check_balance(self):
111 - self.open_api.reset_opw00018_output()
112 - # 예수금 상세현황 요청
113 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
114 - self.open_api.set_input_value("비밀번호입력매체구분",00)
115 - self.open_api.set_input_value("조회구분",1)
116 - self.open_api.comm_rq_data("opw00001_req","opw00001",0,"2000")
117 - # 계좌평가 잔고내역 요청
118 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
119 - self.open_api.comm_rq_data("opw00018_req","opw00018",0,"2000")
120 - while self.open_api.remained_data:
121 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
122 - self.open_api.comm_rq_data("opw00018_req","opw00018",2,"2000")
123 - # 일자별 실현손익 요청
124 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
125 - self.open_api.set_input_value("시작일자","20170101")
126 - self.open_api.set_input_value("종료일자",self.open_api.today)
127 - self.open_api.comm_rq_data("opt10074_req","opt10074",0,"0329")
128 - while self.open_api.remained_data:
129 - self.open_api.set_input_value("계좌번호", self.open_api.account_no)
130 - self.open_api.set_input_value("시작일자", "20170101")
131 - self.open_api.set_input_value("종료일자", self.open_api.today)
132 - self.open_api.set_input_value("구분","0")
133 - self.open_api.comm_rq_data("opt10074_req", "opt10074", 2, "0329")
134 -
135 - self.create_balance_table()
136 -
137 - # balance_data 테이블 생성
138 - def create_balance_table(self):
139 - self.total_invest=int(self.open_api.deposit)+int(self.open_api.total_purchase)
140 - balance_data={'id':[],'date':[],'total_asset':[],'today_profit':[],"total_profit":[],
141 - 'total_invest':[],'deposit':[],'total_purchase':[],'total_evaluation':[],'today_invest':[],
142 - 'today_rate':[],'estimated_asset':[]}
143 -
144 - balance_cols=['date','today_earning_rate','total_asset','deposit',
145 - 'today_profit','total_profit','today_invest','total_invest',
146 - 'total_purchase','today_evaluation','today_sell_count',
147 - 'today_rate','estimated_asset','sell_point','per_invest','limit_money',
148 - 'today_buy_count','today_sell_count','total_posses_count','today_buy_price','today_sell_price'
149 - ]
150 -
151 - balance=DataFrame(balance_data,columns=balance_cols,index=balance_data['id'])
152 -
153 - balance.loc[0,'date']=self.open_api.today
154 - balance.loc[0,'today_profit']=self.open_api.today_profit
155 - balance.loc[0,'total_profit']=self.open_api.total_profit
156 - balance.loc[0,'total_invest']=self.open_api.total_invest
157 - balance.loc[0,'deposit']=self.open_api.deposit
158 - balance.loc[0,'total_purchase']=self.open_api.total_purchase
159 - balance.loc[0,'total_evaluation']=self.open_api.total_evaluated_price
160 - balance.loc[0,'today_invest']=self.open_api.total_valuation
161 - balance.loc[0,'today_rate']=float(self.open_api.earning_rate/self.open_api.mod_classify)
162 - balance.loc[0,'estimate_asset']=self.open_api.estimated_deposit
163 - balance.loc[0,'sell_point']=self.open_api.simul_api.sell_point
164 - balance.loc[0,'per_invest']=self.open_api.per_invest
165 - balance.loc[0,'limit_money']=self.open_api.simul_api.limit_money
166 -
167 - # balance_data 테이블 생성
168 - balance.to_sql('balance_data', self.engine_bot, if_exists='append')
169 -
170 - query = "select date from balance_data"
171 - rows = self.engine_bot.execute(query).fetchall()
172 -
173 - for i in range(len(rows)):
174 - # today_earning_rate
175 - query = "update balance_data " \
176 - "set " \
177 - "today_earning_rate =round(today_profit / total_invest * '%s',2) WHERE date='%s'"
178 - self.engine_bot.execute(query % (100, rows[i][0]))
179 - # today_buy_count
180 - query = "UPDATE balance_data " \
181 - "SET " \
182 - "today_buy_count=" \
183 - "(select count(*) " \
184 - "from " \
185 - "(select code from transaction_history where buy_date like '%s' group by code )) " \
186 - "WHERE date='%s'"
187 - self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
188 - # today_sell_count
189 - query="UPDATE balance_data " \
190 - "SET " \
191 - "today_sell_count=" \
192 - "(select count(*) " \
193 - "from " \
194 - "(select code from transaction_history" \
195 - "where buy_date like '%s' and sell_date is not null group by code) temp) " \
196 - "WHERE date='%s'"
197 - self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
198 - # today_sell_price
199 - query="UPDATE balance_data " \
200 - "SET" \
201 - "today_sell_price=" \
202 - "(select sum(*) " \
203 - "from " \
204 - "(select sell_price from transaction_history " \
205 - "where sell_date like '%s')" \
206 - "where date='%s'"
207 - self.engine_bot.execute(query%(rows[i][0])+"%%",rows[i][0])
208 - # today_buy_price
209 - query="UPDATE balance_data " \
210 - "SET" \
211 - "today_sell_price=" \
212 - "(select sum(*) " \
213 - "from " \
214 - "(select purchase_price from transaction_history " \
215 - "where sell_date like '%s')" \
216 - "where date='%s'"
217 - self.engine_bot.execute(query%(rows[i][0])+"%%",rows[i][0])
218 - # total_posses_count
219 - query="UPDATE balance_data " \
220 - "SET" \
221 - "total_posses_count=" \
222 - "(select count(*) " \
223 - "from" \
224 - "transaction_history where sell_date is Null)" \
225 - "where date='%s'"
226 - self.engine_bot.execute(query%(rows[i][0]))
227 -
228 - sql = "UPDATE setting_data SET balance_to_db='%s' limit 1"
229 - self.engine_bot.execute(sql % (self.open_api.today))
230 -
231 - def is_table_exist(self,db_name,table_name):
232 - query="select 1 from information_schema.tables where table_schema='{}' and table_name='{}'"
233 - result=self.open_api.engine_minute.execute(query.format(db_name,table_name)).fetchall()
234 - if len(result)==1:
235 - return True
236 - else:
237 - return False
238 -
239 - def update_today_profit_list(self):
240 - self.open_api.reset_opt10073_output()
241 -
242 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
243 - self.open_api.set_input_value("시작일자",self.open_api.today)
244 - self.open_api.set_input_value("종료일자",self.open_api.today)
245 - self.open_api.comm_rq_data("opt10073_req","opt10073",0,"0328")
246 -
247 - while self.open_api.remained_data:
248 - self.open_api.set_input_value("계좌번호",self.open_api.account_no)
249 - self.open_api.comm_rq_data("opt10073_req","opt10073",2,"0328")
250 -
251 - today_profit_item_temp = {'date': [], 'code': [], 'code_name': [], 'amount': [], 'today_profit': [],
252 - 'earning_rate': []}
253 -
254 - today_profit_item = DataFrame(today_profit_item_temp,
255 - columns=['date', 'code', 'code_name', 'amount', 'today_profit',
256 - 'earning_rate'])
257 -
258 - item_count = len(self.open_api.opt10073_output['multi'])
259 - for i in range(item_count):
260 - row = self.open_api.opt10073_output['multi'][i]
261 - today_profit_item.loc[i, 'date'] = row[0]
262 - today_profit_item.loc[i, 'code'] = row[1]
263 - today_profit_item.loc[i, 'code_name'] = row[2]
264 - today_profit_item.loc[i, 'amount'] = int(row[3])
265 - today_profit_item.loc[i, 'today_profit'] = float(row[4])
266 - today_profit_item.loc[i, 'earning_rate'] = float(row[5])
267 -
268 - if len(today_profit_item) > 0:
269 - today_profit_item.to_sql('today_profit_list', self.engine_bot, if_exists='append')
270 - query = "UPDATE setting_data SET today_profit='%s' limit 1"
271 - self.engine_bot.execute(query % (self.open_api.today))
272 -
273 - def check_stock_info(self):
274 - self.update_daily_info()
275 - query="update setting_data set daily_info='%s'"
276 - self.engine_bot.execute(query%(self.open_api.today))
277 -
278 - def update_daily_info(self):
279 - query="select code,code_name,check_stock from stock_all"
280 - code_list=self.open_api.engine_daily.execute(query).fetchall()
281 - num=len(code_list)
282 - query="update stock_all set check_stock='%s' where code='%s'"
283 - for i in range(num):
284 - if int(code_list[i][2] in (1,3)):
285 - continue
286 -
287 - code=code_list[i][0]
288 - code_name=code_list[i][1]
289 -
290 - check_item_sort=self.set_stock_info_table(code,code_name)
291 -
292 - self.open_api.engine_daily.execute(query%(check_item_sort,code))
293 -
294 - # stock_info 데이터베이스에 테이블 생성 및 추가
295 - def set_stock_info_table(self,code,code_name):
296 - df=self.open_api.get_date_data(code,code_name,self.open_api.today)
297 -
298 - df=DataFrame(df,
299 - columns=['date', 'check_item', 'code', 'code_name', 'd1_diff_rate',
300 - 'close', 'open', 'high','low','volume',
301 - 'clo5', 'clo10', 'clo20', 'clo60','clo120',
302 - 'pre_clo5', 'pre_clo10', 'pre_clo20', 'pre_clo60','pre_clo120',
303 - 'vol5', 'vol10', 'vol20', 'vol60','vol120'])
304 -
305 - df=df.sort_values(by=['date'],ascending=True)
306 -
307 - df['code']=code
308 - df['code_name']=code_name
309 - df['d1_diff_rate']=float((df['close']-df['close'].shift(1))/df['close'].shift(1)*100)
310 -
311 - df['clo5']=df['close'].rolling(window=5).mean()
312 - df['clo10']=df['close'].rolling(window=10).mean()
313 - df['clo20']=df['close'].rolling(window=20).mean()
314 - df['clo60']=df['close'].rolling(window=60).mean()
315 - df['clo120']=df['close'].rolling(window=120).mean()
316 -
317 - df['pre_col5']=df['clo5'].shift(1)
318 - df['pre_col10']=df['clo10'].shift(1)
319 - df['pre_col20']=df['clo20'].shift(1)
320 - df['pre_col60']=df['clo60'].shift(1)
321 - df['pre_col120']=df['clo120'].shift(1)
322 -
323 - df['vlo5']=df['volume'].rolling(window=5).mean()
324 - df['vlo10']=df['volume'].rolling(window=10).mean()
325 - df['vlo20']=df['volume'].rolling(window=20).mean()
326 - df['vlo60']=df['volume'].rolling(window=60).mean()
327 - df['vlo120']=df['volume'].rolling(window=120).mean()
328 -
329 - # 이미 테이블이 존재한다면 저장된 가장 최신의 날짜 이후의 데이터만 저장
330 - if self.engine_bot.dialect.has_table(self.open_api.engine_stock,code_name):
331 - df=df[df.date>self.open_api.get_latest_date_from_stock_info(code_name)]
332 -
333 - df[['date', 'check_item', 'code', 'code_name', 'd1_diff_rate',
334 - 'close', 'open', 'high','low','volume',
335 - 'clo5', 'clo10', 'clo20', 'clo60','clo120',
336 - 'pre_clo5', 'pre_clo10', 'pre_clo20', 'pre_clo60','yes_clo120',
337 - 'vol5', 'vol10', 'vol20', 'vol60','vol120']]=\
338 - df[['date', 'check_item', 'code', 'code_name', 'd1_diff_rate',
339 - 'close', 'open', 'high','low','volume',
340 - 'clo5', 'clo10', 'clo20', 'clo60','clo120',
341 - 'pre_clo5', 'pre_clo10', 'pre_clo20', 'pre_clo60','yes_clo120',
342 - 'vol5', 'vol10', 'vol20', 'vol60','vol120']].fillna(0).astype(int)
343 -
344 - df.to_sql(name=code_name,con=self.open_api.engine_stock,if_exists='append')
345 -
346 - check_item_sort = 1
347 - return check_item_sort
348 -
349 - def check_daily_info(self):
350 - self.daily_info.create_daily_table()
351 - query="update setting_data set daily_info='%s'"
352 - self.engine_bot.execute(query%(self.open_api.today))
353 -
354 - def realtime_daily_info_check(self):
355 - if self.open_api.simul_api.is_date_exist(self.open_api.today):
356 - self.open_api.simul_api.get_date_for_simul()
357 - self.open_api.simul_api.choose_to_buy_list(self.open_api.today,self.open_api.today,len(self.open_api.simul_api.date_rows))
358 -
359 -
360 -
361 -
362 -
363 - if self.open_api.sf.is_date_exist(self.open_api.today):
364 - logger.debug("daily_buy_list DB에 {} 테이블이 있습니다. jackbot DB에 realtime_daily_buy_list 테이블을 생성합니다".format(self.open_api.today))
365 -
366 - self.open_api.sf.get_date_for_simul()
367 - # 첫 번째 파라미터는 여기서는 의미가 없다.
368 - # 두 번째 파라미터에 오늘 일자를 넣는 이유는 매수를 하는 시점인 내일 기준으로 date_rows_yesterday가 오늘 이기 때문
369 - 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))
370 -
371 -
372 - # all_item_db에서 open, clo5~120, volume 등을 오늘 일자 데이터로 업데이트 한다.
373 - self.open_api.sf.update_all_db_by_date(self.open_api.today)
374 - self.open_api.rate_check()
375 - # realtime_daily_buy_list(매수 리스트) 테이블 세팅을 완료 했으면 아래 쿼리를 통해 setting_data의 today_buy_list에 오늘 날짜를 찍는다.
376 - sql = "UPDATE setting_data SET today_buy_list='%s' limit 1"
377 - self.engine_JB.execute(sql % (self.open_api.today))
378 - else:
379 - logger.debug(
380 - """daily_buy_list DB에 {} 테이블이 없습니다. jackbot DB에 realtime_daily_buy_list 테이블을 생성 할 수 없습니다.
381 - realtime_daily_buy_list는 daily_buy_list DB 안에 오늘 날짜 테이블이 만들어져야 생성이 됩니다.
382 - realtime_daily_buy_list 테이블을 생성할 수 없는 이유는 아래와 같습니다.
383 - 1. 장이 열리지 않은 날 혹은 15시 30분 ~ 23시 59분 사이에 콜렉터를 돌리지 않은 경우
384 - 2. 콜렉터를 오늘 날짜 까지 돌리지 않아 daily_buy_list의 오늘 날짜 테이블이 없는 경우
385 - """.format(self.open_api.today))
386 -
387 -
388 -app=QApplication(sys.argv)
389 -c=Collector_Api()
390 -c.get_code_list()
...\ No newline at end of file ...\ No newline at end of file
1 -from sqlalchemy import *
2 -
3 -from open_api import *
4 -from daily_info import *
5 -from stock_info import *
6 -import config
7 -
8 -class CollectorApi():
9 - def __init__(self):
10 - self.open_api=OpenApi()
11 - self.engine_bot=self.open_api.engine_bot
12 -
13 - def set_variable(self):
14 - self.open_api.sort="collector"
15 - self.stock_info=StockInfo(config.real_bot,config.real_stockInfo,config.real_dailyInofo)
16 - self.daily_info=DailyInfo()
17 -
18 - def update_code(self):
19 - print("update code")
20 - query = "select code_update,jango_data_db_check, possessed_item, today_profit, final_chegyul_check, " \
21 - "db_to_buy_list,today_buy_list, daily_crawler , min_crawler, daily_buy_list " \
22 - "from setting_data limit 1"
23 - result=self.engine_bot.execute(query).fetchall()
24 -
25 - print(result)
26 -
27 - if result[0][0]!=self.open_api.today():
28 - self.open_api.check_balance()
29 - self.get_code_list()
30 -
31 -
32 - def set_db_minute_info(self):
33 - print("Make Minute Info Database")
34 - query="select code,code_name from stock_all"
35 - target=self.open_api.engine_dInfo.execute(query).fetchall()
36 - print(target)
37 -
38 -app = QApplication(sys.argv)
39 -c=CollectorApi()
40 -c.update_code()
...\ No newline at end of file ...\ No newline at end of file
...@@ -6,9 +6,10 @@ import datetime ...@@ -6,9 +6,10 @@ import datetime
6 from sqlalchemy import * 6 from sqlalchemy import *
7 from collections import defaultdict 7 from collections import defaultdict
8 from pandas import DataFrame 8 from pandas import DataFrame
9 +import re
9 10
10 from Logger import * 11 from Logger import *
11 -import config 12 +import cf
12 from Simulator_Api import * 13 from Simulator_Api import *
13 14
14 pymysql.install_as_MySQLdb() 15 pymysql.install_as_MySQLdb()
...@@ -21,7 +22,7 @@ class Open_Api(QAxWidget): ...@@ -21,7 +22,7 @@ class Open_Api(QAxWidget):
21 self.login_event_loop=QEventLoop() 22 self.login_event_loop=QEventLoop()
22 self.tr_event_loop=QEventLoop() 23 self.tr_event_loop=QEventLoop()
23 24
24 - # open_api 호출 횟수를 저장f 25 + # open_api 호출 횟수를 저장
25 self.rq_count=0 26 self.rq_count=0
26 self.set_date() 27 self.set_date()
27 self.tr_loop_count=0 28 self.tr_loop_count=0
...@@ -38,13 +39,14 @@ class Open_Api(QAxWidget): ...@@ -38,13 +39,14 @@ class Open_Api(QAxWidget):
38 # 변수 설정 39 # 변수 설정
39 self.set_variable() 40 self.set_variable()
40 41
41 - self.simul_api=Simulator_Api(self.simul_num,"real",self.db_name) 42 + self.sf=Simulator_Func(self.simul_num,"real",self.db_name)
42 logger.debug("알고리즘 번호 : %s",self.simul_api.simul_num) 43 logger.debug("알고리즘 번호 : %s",self.simul_api.simul_num)
43 logger.debug("매수 알고리즘 번호 : %s",self.simul_api.buy_algorithm) 44 logger.debug("매수 알고리즘 번호 : %s",self.simul_api.buy_algorithm)
44 logger.debug("매도 알고리즘 번호 : %s",self.simul_api.sell_algorithm) 45 logger.debug("매도 알고리즘 번호 : %s",self.simul_api.sell_algorithm)
45 46
47 + # 시뮬레이션 데이터베이스에 setting_data 테이블이 존재하지 않는다면 생성
46 if not self.simul_api.is_table_exist(self.db_name,"setting_data"): 48 if not self.simul_api.is_table_exist(self.db_name,"setting_data"):
47 - self.create_setting_data() 49 + self.init_setting_data()
48 50
49 self.set_simul_variable() 51 self.set_simul_variable()
50 self.ohlcv=defaultdict(list) 52 self.ohlcv=defaultdict(list)
...@@ -88,6 +90,28 @@ class Open_Api(QAxWidget): ...@@ -88,6 +90,28 @@ class Open_Api(QAxWidget):
88 except Exception as e: 90 except Exception as e:
89 logger.critical(e) 91 logger.critical(e)
90 92
93 + # 사용자의 계좌정보 저장 및 출력
94 + def get_account_info(self):
95 + account_no=self.get_login_info("ACCNO")
96 + self.account_no=account_no.split(";")[0]
97 + logger.debug(self.account_no)
98 +
99 + # 원하는 사용자 정보 반환
100 + # param : tag - ACCNO - 보유계좌리스트
101 + # ACCOUNT_CNT - 보유계좌 수
102 + # USER_ID - 사용자 ID
103 + # USER_NAME - 사용자 이름
104 + # KEY_BSECGB - 키보드 보안 해제 여부 (0 : 정상, 1: 해지)
105 + # FIREW_SECGB - 방화벽 설정여부 (0 : 미설정, 1: 설정, 2 : 해지)
106 + # GetServerGubun - 접속서버 구분 (1 : 모의투자, 나머지 : 실서버)
107 + # return : tag를 통해 요청한 정보(ret) 반환
108 + def get_login_info(self,tag):
109 + try:
110 + ret=self.dynamicCall("GetLoginInfo(QString)",tag)
111 + return ret
112 + except Exception as e:
113 + logger.critical(e)
114 +
91 # 수동 로그인설정인 경우 로그인창을 출력해서 로그인을 시도 115 # 수동 로그인설정인 경우 로그인창을 출력해서 로그인을 시도
92 # 자동로그인 설정인 경우 로그인창 출력없이 로그인을 시도 116 # 자동로그인 설정인 경우 로그인창 출력없이 로그인을 시도
93 def comm_connect(self): 117 def comm_connect(self):
...@@ -105,7 +129,7 @@ class Open_Api(QAxWidget): ...@@ -105,7 +129,7 @@ class Open_Api(QAxWidget):
105 # sPrevNext : 다음 페이지가 있는지 여부. "2" : 다음페이지 존재, "0" or "" : 다음페이지 없음 129 # sPrevNext : 다음 페이지가 있는지 여부. "2" : 다음페이지 존재, "0" or "" : 다음페이지 없음
106 def _receive_tr_data(self,sScrNo,sRQName,sTrCode,sRecordName,sPrevNext): 130 def _receive_tr_data(self,sScrNo,sRQName,sTrCode,sRecordName,sPrevNext):
107 if sPrevNext=='2': 131 if sPrevNext=='2':
108 - self.remained_data=True 132 + self.remained_data=True # 다음 페이지가 존재하는지 확인하는 변수
109 else: 133 else:
110 self.remained_data=False 134 self.remained_data=False
111 135
...@@ -161,14 +185,133 @@ class Open_Api(QAxWidget): ...@@ -161,14 +185,133 @@ class Open_Api(QAxWidget):
161 # GetChejanData()함수를 이용해서 상세한 정보를 얻을 수 있다 185 # GetChejanData()함수를 이용해서 상세한 정보를 얻을 수 있다
162 # param : sGubun - 체결구분. 접수와 체결시 '0'값, 국내주식 잔고전달은 '1'값, 파생잔고 전달은 '4' 186 # param : sGubun - 체결구분. 접수와 체결시 '0'값, 국내주식 잔고전달은 '1'값, 파생잔고 전달은 '4'
163 def _receive_chejan_data(self,sGubun,nItemCnt,sFIdList): 187 def _receive_chejan_data(self,sGubun,nItemCnt,sFIdList):
164 - # 현재 체결 진행 중인 코드 188 + # 체결구분. 접수와 체결
165 - print("주분번호 : ",self.get_chejan_data(9023)) 189 + if sGubun=="0":
166 - print("종목명 : ",self.get_chejan_data(302)) 190 + code=self.get_chejan_data(9001) # 현재 체결 진행 중인 코드
167 - print("주문수량 : ",self.get_chejan_data(900)) 191 + code=re.compile(r'\d{6}') # 종목코드는 연속된 숫자 6자리
168 - print("주문가격 : ",self.get_chejan_data(901)) 192 + order_num=self.get_chejan_data(9203) # 주문번호
193 +
194 + # 주문번호가 존재하지 않는다면 주문실패
195 + if not order_num:
196 + logger.debug(code,"주문 실패")
197 + return
198 +
199 + chegyul_fail_amount=self.get_chejan_data(902) # 미체결 수량
200 + order_gubun=self.get_chejan_data(905) # 주문구분
201 + purchase_price=self.get_chejan_data(10) # 체결가
202 +
203 + # 종목코드가 존재한다면
204 + if code:
205 + if chegyul_fail_amount!="":
206 + # 해당 종목을 보유하고 있지 않은 경우
207 + if not self.is_exist_possess_item_in_transaction(code):
208 + # 해당 종목의 체결 실패 내역이 없다면
209 + # transaction 테이블에 업데이트. 정상 체결 시 chegyul_check=0
210 + if chegyul_fail_amount=="0":
211 + logger.debug(code, "체결 완료")
212 + self.db_to_transaction(order_num,code,0,purchase_price,0)
213 + # 체결 실패 내역이 존재한다면
214 + # transaction 테이블에 업데이트. 미체결 시 chegyul_check=1
215 + else:
216 + logger.debug(code,"미체결")
217 + self.db_to_transaction(order_num,code,1,purchase_price,0)
218 +
219 + # 매수하는 경우
220 + elif order_gubun=="+매수":
221 + if chegyul_fail_amount!="0" and self.check_stock_chegyul(code):
222 + logger.debug("미체결. 매수 진행중!")
223 + pass
224 + elif chegyul_fail_amount=="0" and self.check_stock_chegyul(code):
225 + logger.debug("매수 완료")
226 + self.check_end_invest(code)
227 + else:
228 + pass
229 +
230 + # 매도하는 경우
231 + elif order_gubun=="-매도":
232 + if chegyul_fail_amount=="0":
233 + logger.debug("전량 매도")
234 + self.check_end_sell(code)
235 + else:
236 + logger.debug("부분 매도")
237 + self.check_sell_chegyul_fail(code)
238 +
239 + else:
240 + logger.debug("Invalid order_gubun")
241 + else:
242 + logger.debug("Invalid chegyul_fail_amount value")
243 + else:
244 + logger.debug("can't receive code value")
245 +
246 + # 국내주식 잔고전달
247 + elif sGubun=="1":
248 + chegyul_fail_amount=self.get_chejan_data(902)
249 + logger.debug("미체결 수량",chegyul_fail_amount)
250 +
251 + else:
252 + logger.debug("Invlid _receive_chejan_data")
253 +
254 + # 특정 종목을 보유하고 있는지 확인하는 함수
255 + def is_exist_possess_item_in_transaction(self,code):
256 + query = "select code from transaction " \
257 + "where code='%s' and (sell_date ='%s' or sell_date='%s') ORDER BY buy_date desc LIMIT 1"
258 + result = self.engine_bot.execute(query % (code, 0, "")).fetchall()
259 + if len(result) != 0:
260 + return True
261 + else:
262 + return False
263 +
264 + # 해당 종목이 체결되었는지 확인하는 함수
265 + def check_stock_chegyul(self,code):
266 + query = "SELECT chegyul_check FROM transaction " \
267 + "where code='%s' and sell_date = '%s' ORDER BY buy_date desc LIMIT 1"
268 + result = self.engine_bot.execute(query % (code, 0)).fetchall()
269 + if result[0][0] == 1:
270 + return True
271 + else:
272 + return False
273 +
274 + # 체결 완료 시 transaction 테이블의 chegyul_check항목을 업데이트
275 + def check_end_invest(self,code):
276 + query = "UPDATE transaction " \
277 + "SET " \
278 + "chegyul_check='%s' WHERE code='%s' and sell_date = '%s' ORDER BY buy_date desc LIMIT 1"
279 + self.engine_bot.execute(query % (0, code, 0))
280 +
281 + # 매도 완료 후 DB 업데이트트
282 + def check_sell_end(self,code):
283 + query="select valuation_profit,rate,item_total_urchase,present_price" \
284 + "from possessed_item" \
285 + "where code={} limit 1"
286 + get_list=self.engine_bot.execute(query.format(code)).fetchall()
287 +
288 + # 매도 완료 종목에 대해 DB 업데이트
289 + if get_list:
290 + item = get_list[0]
291 + query = f"""UPDATE transaction
292 + SET
293 + item_total_purchase = {item.item_total_purchase}, chegyul_check = 0,
294 + sell_date = '{self.today_detail}', valuation_profit = {item.valuation_profit},
295 + sell_rate = {item.rate}, sell_price = {item.present_price}
296 + WHERE code = '{code}' and sell_date = '0' ORDER BY buy_date desc LIMIT 1"""
297 + self.engine_bot.execute(query)
298 +
299 + # 매도 완료 후 possessd_item 테이블에서 해당 종목 삭제
300 + self.engine_bot.execute(f"DELETE FROM possessed_item WHERE code = '{code}'")
301 + else:
302 + logger.debug("보유 종목이 없습니다.")
303 +
304 + # 매도 체결 실패시 DB 업데이트
305 + def check_sell_chegyul_fail(self,code):
306 + query = "UPDATE transaction SET chegyul_check='%s' " \
307 + "WHERE code='%s' and sell_date = '%s' ORDER BY buy_date desc LIMIT 1"
308 + self.engine_bot.execute(query % (1, code, 0))
169 309
170 # OnReceiveChejan()이벤트가 호출될때 체결정보나 잔고정보를 얻어오는 함수 310 # OnReceiveChejan()이벤트가 호출될때 체결정보나 잔고정보를 얻어오는 함수
171 # param : nFid - 실시간 타입에 포함된 FID 311 # param : nFid - 실시간 타입에 포함된 FID
312 + # FID List
313 + # (FID, 설명) : (9023, 주문번호), (302, 종목명), (900, 주문수량), (901,주문가격), (902,미체결수량), (904,원주문번호),
314 + # (905, 주문구분), (908, 주문/체결시간), (909, 체결번호), (910, 체결가), (911, 체결량), (10, 현재가/체결가/실시간종가)
172 def get_chejan_data(self,nFid): 315 def get_chejan_data(self,nFid):
173 try: 316 try:
174 ret=self.dynamicCall("GetChejanData(int)",nFid) 317 ret=self.dynamicCall("GetChejanData(int)",nFid)
...@@ -176,27 +319,15 @@ class Open_Api(QAxWidget): ...@@ -176,27 +319,15 @@ class Open_Api(QAxWidget):
176 except Exception as e: 319 except Exception as e:
177 logger.critical(e) 320 logger.critical(e)
178 321
179 - # 사용자의 계좌정보 저장 및 출력 322 + # 거래이력(transaction)테이블에 현재 보유중인 종목이 있는지 확인하는 함수
180 - def get_account_info(self): 323 + def is_transaction_check(self,code):
181 - account_no=self.get_login_info("ACCNO") 324 + query = "select code from transaction " \
182 - self.account_no=account_no.split(";")[0] 325 + "where code='%s' and (sell_date ='%s' or sell_date='%s') ORDER BY buy_date desc LIMIT 1"
183 - logger.debug(self.account_no) 326 + rows = self.engine_bot.execute(query % (code, 0, "")).fetchall()
184 - 327 + if len(rows) != 0:
185 - # 원하는 사용자 정보 반환 328 + return True
186 - # param : tag - ACCNO - 보유계좌리스트 329 + else:
187 - # ACCOUNT_CNT - 보유계좌 수 330 + return False
188 - # USER_ID - 사용자 ID
189 - # USER_NAME - 사용자 이름
190 - # KEY_BSECGB - 키보드 보안 해제 여부 (0 : 정상, 1: 해지)
191 - # FIREW_SECGB - 방화벽 설정여부 (0 : 미설정, 1: 설정, 2 : 해지)
192 - # GetServerGubun - 접속서버 구분 (1 : 모의투자, 나머지 : 실서버)
193 - # return : tag를 통해 요청한 정보(ret) 반환
194 - def get_login_info(self,tag):
195 - try:
196 - ret=self.dynamicCall("GetLoginInfo(QString)",tag)
197 - return ret
198 - except Exception as e:
199 - logger.critical(e)
200 331
201 # 조회요청시 TR의 Input값을 지정하는 함수 332 # 조회요청시 TR의 Input값을 지정하는 함수
202 # param : sId - TR에 명시된 Input이름 333 # param : sId - TR에 명시된 Input이름
...@@ -240,55 +371,56 @@ class Open_Api(QAxWidget): ...@@ -240,55 +371,56 @@ class Open_Api(QAxWidget):
240 # 변수 설정 371 # 변수 설정
241 # 실전투자인지 모의투자인지 여부를 확인하고 그에 해당하는 데이터베이스를 생성하는 함수 372 # 실전투자인지 모의투자인지 여부를 확인하고 그에 해당하는 데이터베이스를 생성하는 함수
242 def set_variable(self): 373 def set_variable(self):
243 - self.config=config 374 + self.cf=cf
375 + self.get_today_buy_list_code=0
244 self.reset_opw00018_output() 376 self.reset_opw00018_output()
245 377
246 - if self.account_no==self.config.real_account_no: 378 + if self.account_no==self.cf.real_account_no:
247 logger.debug("실전투자") 379 logger.debug("실전투자")
248 - self.simul_num=self.config.real_num 380 + self.simul_num=self.cf.real_num
249 - self.set_database(self.config.real_bot_name) 381 + self.set_database(cf.real_bot_name)
250 - self.mod_classify=100 382 + self.mod_gubun=100 # 실전투자와 모의투자를 구분하는 변수
251 383
252 - elif self.account_no==self.config.test_account_no: 384 + elif self.account_no==self.cf.test_account_no:
253 logger.debug("모의투자") 385 logger.debug("모의투자")
254 - self.simul_num=self.config.test_num 386 + self.simul_num=self.cf.test_num
255 - self.set_database(self.config.test_bot_name) 387 + self.set_database(cf.test_bot_name)
256 - self.mod_classify=1 388 + self.mod_gubun=1
257 389
258 else: 390 else:
259 logger.debug("Invalid Account Number. Check the Config.py") 391 logger.debug("Invalid Account Number. Check the Config.py")
260 exit(1) 392 exit(1)
261 393
262 self.is_balance_null=True 394 self.is_balance_null=True
263 - self.use=False 395 + self.py_gubun=False
264 396
265 # 데이터베이스 생성 및 엔진 설정 397 # 데이터베이스 생성 및 엔진 설정
266 def set_database(self,db_name): 398 def set_database(self,db_name):
267 self.db_name=db_name 399 self.db_name=db_name
268 conn=pymysql.connect( 400 conn=pymysql.connect(
269 - host=config.db_ip, 401 + host=cf.db_ip,
270 - port=int(config.db_port), 402 + port=int(cf.db_port),
271 - user=config.db_id, 403 + user=cf.db_id,
272 - password=config.db_pw, 404 + password=cf.db_pw,
273 - charset='utf8' 405 + charset='utf8mb4'
274 ) 406 )
275 cursor=conn.cursor() 407 cursor=conn.cursor()
276 if not self.is_database_exist(cursor): 408 if not self.is_database_exist(cursor):
277 self.create_database(cursor) 409 self.create_database(cursor)
278 - self.engine_bot=create_engine("mysql+pymysql://"+self.config.db_id+":"+self.config.db_pw+"@"+ 410 + self.engine_bot=create_engine("mysql+pymysql://"+self.cf.db_id+":"+self.cf.db_pw+"@"+
279 - self.config.db_ip + ":" + self.config.db_port+"/"+db_name,encoding='utf-8') 411 + self.cf.db_ip + ":" + self.cf.db_port+"/"+db_name,encoding='utf-8')
280 - self.create_info_database(cursor) 412 + self.create_basic_database(cursor)
281 413
282 conn.commit() 414 conn.commit()
283 cursor.close() 415 cursor.close()
284 conn.close() 416 conn.close()
285 417
286 - self.engine_daily=create_engine("mysql+pymysql://"+self.config.db_id+":"+self.config.db_pw+"@"+ 418 + self.engine_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" +
287 - self.config.db_ip + ":" + self.config.db_port+"/daily_info",encoding='utf-8') 419 + cf.db_port + "/min_craw",encoding='utf-8')
288 - self.engine_stock=create_engine("mysql+pymysql://"+self.config.db_id+":"+self.config.db_pw+"@"+ 420 + self.engine_daily_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" +
289 - self.config.db_ip + ":" + self.config.db_port+"/stock_info",encoding='utf-8') 421 + cf.db_port + "/daily_craw",encoding='utf-8')
290 - self.engine_minute=create_engine("mysql+pymysql://"+self.config.db_id+":"+self.config.db_pw+"@"+ 422 + self.engine_daily_buy_list = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":"
291 - self.config.db_ip + ":" + self.config.db_port+"/minute_info",encoding='utf-8') 423 + + cf.db_port + "/daily_buy_list",encoding='utf-8')
292 424
293 # Bot Database가 존재하는지 확인하는 함수 425 # Bot Database가 존재하는지 확인하는 함수
294 def is_database_exist(self,cursor): 426 def is_database_exist(self,cursor):
...@@ -304,123 +436,183 @@ class Open_Api(QAxWidget): ...@@ -304,123 +436,183 @@ class Open_Api(QAxWidget):
304 query="create database {}" 436 query="create database {}"
305 cursor.execute(query.format(self.db_name)) 437 cursor.execute(query.format(self.db_name))
306 438
307 - # information 데이터베이스가 존재하는지 확인 439 + # daily_craw(종목의 날짜별 데이터), daily_buy_list(날짜별 종목 데이터), min_craw(종목의 분별 데이터) 가 존재하는지 확인하는 함수
308 # 존재하지 않는다면 새로 생성 440 # 존재하지 않는다면 새로 생성
309 - def create_info_database(self,cursor): 441 + def create_basic_database(self,cursor):
310 - info_list=['daily_info','stock_info','minute_info'] 442 + check_list = ['daily_craw', 'daily_buy_list', 'min_craw']
311 - query="select schema_name from information_schema.schemata" 443 + query = "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA"
312 cursor.execute(query) 444 cursor.execute(query)
313 - result=cursor.fetchall() 445 + result = cursor.fetchall()
314 - print(result) 446 + db_list = [n['SCHEMA_NAME'].lower() for n in result]
315 - exist_list=[item[0].lower() for item in result] 447 + create_db_query = "CREATE DATABASE {}"
316 - create_query="create database {}" 448 + has_created = False
317 - has_created=False 449 + for check_name in check_list:
318 - for db in info_list: 450 + if check_name not in db_list:
319 - if db not in exist_list: 451 + has_created = True
320 - has_created=True 452 + logger.debug(check_name,"데이터베이스 생성...")
321 - logger.debug(db,"Database not exist. Create the Database.") 453 + create_db_sql = create_db_query.format(check_name)
322 - cursor.execute(create_query.format(db)) 454 + cursor.execute(create_db_sql)
323 - logger.debug(db,"Creation Completed!")
324 455
325 if has_created and self.engine_bot.has_table('setting_data'): 456 if has_created and self.engine_bot.has_table('setting_data'):
326 - print("exist") 457 + self.engine_bot.execute("UPDATE setting_data SET code_update = '0';")
327 - self.engine_bot.execute("update setting_data set code_update='0") 458 +
328 - 459 + # setting_data 테이블 생성 및 초기화하는 함수
329 - def create_setting_data(self): 460 + def init_setting_data(self):
330 - df_data={"limit_money":[],"per_invest":[],"max_per_invest":[],"min_per_invest":[],"set_per_invest":[], 461 + df_setting_data_temp = {'limit_money': [], 'invest_unit': [], 'max_invest_unit': [],
331 - "code_update":[],"today_finish":[],"balance_to_db":[],"posses_stocks":[],"today_profit":[], 462 + 'min_invest_unit': [],'set_invest_unit': [], 'code_update': [],
332 - "contract_check":[],"final_contract_check":[],"db_to_daily_info":[],"today_buy_list":[], 463 + 'today_buy_stop': [],'account_balance_db_check': [], 'possessed_item': [],
333 - "stock_info":[],"min_info":[],"daily_info":[]} 464 + 'today_profit': [],'final_chegyul_check': [],'db_to_buy_list': [], 'today_buy_list': [],
334 - df_setting_data=DataFrame(df_data, 465 + 'daily_crawler': [],'daily_buy_list': []}
335 - columns=['limit_money','per_invest','max_per_invest','min_per_invest','set_per_invest', 466 +
336 - 'code_update','today_finish','balance_to_db','posses_stocks','today_profit', 467 + df_setting_data = DataFrame(df_setting_data_temp,
337 - 'contract_check','final_contract_check','db_to_daily_info','today_buy_list', 468 + columns=['limit_money', 'invest_unit', 'max_invest_unit','min_invest_unit',
338 - 'stock_info','min_info','daily_info']) 469 + 'set_invest_unit', 'code_update', 'today_buy_stop',
339 - 470 + 'account_balance_db_check', 'possessed_item', 'today_profit',
340 - df_setting_data.loc[0,'limit_money']=int(0) 471 + 'final_chegyul_check','db_to_buy_list', 'today_buy_list', 'daily_crawler',
341 - df_setting_data.loc[0,'per_invest']=int(0) 472 + 'daily_buy_list'])
342 - df_setting_data.loc[0,'max_per_invest']=int(0) 473 +
343 - df_setting_data.loc[0,'min_per_invest']=int(0) 474 + # 칼럼 자료형 설정
344 - df_setting_data.loc[0,'set_per_invest']=str(0) 475 + df_setting_data.loc[0, 'limit_money'] = int(0) # 잔고에 최소한으로 남겨놓을 금액
345 - 476 + df_setting_data.loc[0, 'invest_unit'] = int(0) # 기준 투자금액
346 - df_setting_data.loc[0,'code_update']=str(0) 477 + df_setting_data.loc[0, 'max_invest_unit'] = int(0) # 최대 투자금액
347 - df_setting_data.loc[0,'today_finish']=str(0) 478 + df_setting_data.loc[0, 'min_invest_unit'] = int(0) # 최소 투자금액
348 - df_setting_data.loc[0,'balance_to_db']=str(0) 479 + df_setting_data.loc[0, 'set_invest_unit'] = str(0) # 기준 투자금액 설정 날짜
349 - df_setting_data.loc[0,'posses_stocks']=str(0) 480 +
350 - df_setting_data.loc[0,'today_profit']=float(0) 481 + df_setting_data.loc[0, 'code_update'] = str(0) # setting_data의 데이터를 업데이트 한 날짜
351 - 482 + df_setting_data.loc[0, 'today_buy_stop'] = str(0) # 당일 구매 종료 설정 시간
352 - df_setting_data.loc[0,'contract_check']=str(0) 483 + df_setting_data.loc[0, 'account_balance_db_check'] = str(0) # 잔고데이터 DB 업데이트 날짜
353 - df_setting_data.loc[0,'final_contract_check']=str(0) 484 + df_setting_data.loc[0, 'possessed_item'] = str(0) # 보유종목 DB 업데이트 날짜
354 - df_setting_data.loc[0,'db_to_daily_info']=str(0) 485 + df_setting_data.loc[0, 'today_profit'] = str(0) # 당일 수익
355 - df_setting_data.loc[0,'today_buy_list']=str(0) 486 +
356 - df_setting_data.loc[0,'stock_info']=str(0) 487 + df_setting_data.loc[0, 'final_chegyul_check'] = str(0) # 마지막 체결 확인
357 - 488 + df_setting_data.loc[0, 'db_to_buy_list'] = str(0) # 구매 리스트 DB 업데이트 날짜
358 - df_setting_data.loc[0,'min_info']=str(0) 489 + df_setting_data.loc[0, 'today_buy_list'] = str(0) # 당일 구매 리스트 DB 업데이트 날짜
359 - df_setting_data.loc[0,'daily_info']=str(0) 490 + df_setting_data.loc[0, 'daily_crawler'] = str(0) # daily_crawler(종목의 일별 데이터) 업데이트 날짜
360 - 491 + df_setting_data.loc[0, 'min_crawler'] = str(0) # min_crawler(종목의 분별 데이터) 업데이트 날자
361 - df_setting_data.to_sql("setting_data",self.engine_bot,if_exists="replace") 492 + df_setting_data.loc[0, 'daily_buy_list'] = str(0) # daily_buy_list(일별 종목 데이터) 업데이트 날짜
362 - 493 +
363 - # 시뮬레이터에서 사용할 변수들을 설정 494 + df_setting_data.to_sql('setting_data', self.engine_JB, if_exists='replace')
495 +
496 + # simulator_fun 에서 설정한 변수를 가져오는 함수
364 def set_simul_variable(self): 497 def set_simul_variable(self):
365 - self.latest_date=self.simul_api.get_latest_date() 498 + # daily_buy_list에 저장된 가장 최신 날짜
366 - if not self.simul_api.is_table_exist(self.db_name,"transaction_history"): 499 + self.date_rows_yesterday=self.sf.get_recent_daily_buy_list_date()
367 - logger.debug("create transaction_history table") 500 +
368 - self.per_invest=0 501 + # AutoBot 데이터베이스에 transaction 테이블이 존재하지 않을 경우
369 - self.create_transaction_history(0,0,0,0,0) 502 + # 테이블 생성 및 초기화
370 - self.delete_item_by_code(0) 503 + if not self.sf.is_simul_table_exist(self.db_name,"transaction"):
371 - 504 + logger.debug("transaction 테이블을 생성합니다")
372 - if not self.check_per_invest(): 505 + self.invest_unit=0
373 - self.set_per_invest() 506 + self.db_to_transaction(0,0,0,0,0)
507 + # 테이블 생성 후 초기화
508 + self.delete_transaction_item("0")
509 +
510 + # setting_data에 invest_unit값이 없다면 설정
511 + if not self.check_set_invest_unit():
512 + self.set_invest_unit()
513 + # 존재한다면 해당 값을 simulator_func에 저장
374 else: 514 else:
375 - self.per_invest=self.get_per_invest() 515 + self.invest_unit=self.get_invest_unit()
376 - self.simul_api.per_invest=self.per_invest 516 + self.sf.invest_unit=self.invest_unit
377 - 517 +
378 - # transaction_history 테이블 생성 및 column 설정 518 + # transaction(거래 내역) 테이블 생성
379 - def create_transaction_history(self,order_num,code,contract_check,purchase_price,rate): 519 + def db_to_transaction(self,order_num,code,chegyul_check,purchase_price,rate):
380 - logger.debug("creating transaction_history table") 520 + self.date_setting()
381 - self.set_date() 521 + # 거래내역 DataFrame 생성
382 - self.simul_api.df_transaction_history() 522 + self.sf.init_df_transaction()
383 - self.simul_api.df_th.loc[0,'order_num']=order_num 523 +
384 - self.simul_api.df_th.loc[0,'code']=str(code) 524 + # dataframe에 값 할당
385 - self.simul_api.df_th.loc[0,'reate']=float(rate) 525 + self.sf.df_transaction.loc[0, 'order_num'] = order_num # 주문번호
386 - self.simul_api.df_th.loc[0,'buy_date']=self.today_time 526 + self.sf.df_transaction.loc[0, 'code'] = str(code) # 종목코드
387 - self.simul_api.df_th.loc[0,'contract_check']=contract_check 527 + self.sf.df_transaction.loc[0, 'rate'] = float(rate) # 수익률
388 - self.simul_api.df_th.loc[0,'per_invest']=self.per_invest 528 + self.sf.df_transaction.loc[0, 'buy_date'] = self.today_detail # 구매날짜
389 - self.simul_api.df_th.loc[0,'purchase_price']=purchase_price 529 + self.sf.df_all_item.loc[0, 'chegyul_check'] = chegyul_check # 체결확인
390 - 530 +
391 - self.simul_api.df_th=self.simul_api.df_th.fillna(0) 531 + self.sf.df_all_item.loc[0, 'invest_unit'] = self.invest_unit # 투자기준금액
392 - self.simul_api.df_th.to_sql('transaction_history',self.engine_bot,if_exists='append') 532 + self.sf.df_all_item.loc[0, 'purchase_price'] = purchase_price # 구매금액
393 - 533 +
394 - def delete_item_by_code(self,code): 534 + if order_num != 0:
395 - query="delete from transaction_history where code='%s'" 535 + recent_daily_buy_list_date=self.sf.get_recent_daily_buy_list_date()
396 - self.engine_bot.execute(query%code) 536 + if recent_daily_buy_list_date:
397 - 537 + # 특정 날짜, 특정 종목의 주가 데이터
398 - # setting_data에 per_invest항목이 설정되어 있는지 확인하는 함수 538 + df=self.sf.get_daily_buy_list_by_code(code,recent_daily_buy_list_date)
399 - def check_per_invest(self): 539 + if not df.empty:
400 - query="select per_invest, set_per_invest from setting_data" 540 + self.sf.df_transaction.loc[0, 'code_name'] = df.loc[0, 'code_name'] # 종목명
541 +
542 + self.sf.df_transaction.loc[0, 'close'] = df.loc[0, 'close'] # 종가
543 + self.sf.df_transaction.loc[0, 'open'] = df.loc[0, 'open'] # 시가
544 + self.sf.df_transaction.loc[0, 'high'] = df.loc[0, 'high'] # 고가
545 + self.sf.df_transaction.loc[0, 'low'] = df.loc[0, 'low'] # 저가
546 + self.sf.df_transaction.loc[0, 'volume'] = df.loc[0, 'volume'] # 거래량
547 +
548 + self.sf.df_transaction.loc[0,'d1_diff']=float(df.loc[0,'d1_diff']) # 전날대비 가격변동
549 + self.sf.df_transaction.loc[0, 'd1_diff_rate'] = float(df.loc[0, 'd1_diff_rate']) # 전날대비 가격변동률
550 +
551 + self.sf.df_transaction.loc[0, 'clo5'] = df.loc[0, 'clo5'] # 5일 이동평균선
552 + self.sf.df_transaction.loc[0, 'clo10'] = df.loc[0, 'clo10'] # 10일 이동평균선
553 + self.sf.df_transaction.loc[0, 'clo20'] = df.loc[0, 'clo20'] # 20일 이동평균선
554 + self.sf.df_transaction.loc[0, 'clo60'] = df.loc[0, 'clo60'] # 60일 이동평균선
555 + self.sf.df_transaction.loc[0, 'clo120'] = df.loc[0, 'clo120'] # 120일 이동평균선
556 +
557 + if df.loc[0, 'clo5_diff_rate'] is not None:
558 + self.sf.df_transaction.loc[0, 'clo5_diff_rate'] = float(df.loc[0, 'clo5_diff_rate']) # 5일 이동평균선 변동률
559 + if df.loc[0, 'clo10_diff_rate'] is not None:
560 + self.sf.df_transaction.loc[0, 'clo10_diff_rate'] = float(df.loc[0, 'clo10_diff_rate'])
561 + if df.loc[0, 'clo20_diff_rate'] is not None:
562 + self.sf.df_transaction.loc[0, 'clo20_diff_rate'] = float(df.loc[0, 'clo20_diff_rate'])
563 + if df.loc[0, 'clo60_diff_rate'] is not None:
564 + self.sf.df_transaction.loc[0, 'clo60_diff_rate'] = float(df.loc[0, 'clo60_diff_rate'])
565 + if df.loc[0, 'clo120_diff_rate'] is not None:
566 + self.sf.df_transaction.loc[0, 'clo120_diff_rate'] = float(df.loc[0, 'clo120_diff_rate'])
567 +
568 + # null값을 0으로 변환
569 + self.sf.df_all_item = self.sf.df_all_item.fillna(0)
570 + self.sf.df_all_item.to_sql('transaction', self.engine_bot, if_exists='append', dtype={
571 + 'code_name': Text,
572 + 'rate': Float,
573 + 'sell_rate': Float,
574 + 'purchase_rate': Float,
575 + 'sell_date': Text,
576 + 'd1_diff': Integer,
577 + 'd1_diff_rate': Float,
578 + 'clo5_diff_rate': Float,
579 + 'clo10_diff_rate': Float,
580 + 'clo20_diff_rate': Float,
581 + 'clo60_diff_rate': Float,
582 + 'clo120_diff_rate': Float,
583 + })
584 +
585 + # 거래내역(transaction) 테이블에서 특정 종목을 삭제하는 함수
586 + def delete_transaction_item(self,code):
587 + query=f"delete from transaction where code={code}"
588 + self.engine_bot.execute(query)
589 +
590 + # setting_data 테이블에 invest_unit이 오늘 업데이트 되었는지 확인
591 + def check_set_invest_unit(self):
592 + query="select invest_unit, set_invest_unit from setting_data"
401 result=self.engine_bot.execute(query).fetchall() 593 result=self.engine_bot.execute(query).fetchall()
402 if result[0][1]==self.today: 594 if result[0][1]==self.today:
403 - self.per_invest=result[0][0] 595 + self.invest_unit=result[0][0]
404 return True 596 return True
405 else: 597 else:
406 return False 598 return False
407 599
408 - # 데이터베이스에서 per_invest항목을 반환 600 + # 데이터베이스에서 invest_unit값을 가져오는 함수
409 - def get_per_invest(self): 601 + def get_invest_unit(self):
410 - query="select per_invest from setting_data" 602 + query="select invest_unit from setting_data"
411 result=self.engine_bot.execute(query).fetchall() 603 result=self.engine_bot.execute(query).fetchall()
412 return result[0][0] 604 return result[0][0]
413 605
414 - # per_invest 항목 설정 606 + # invest_unit 항목 업데이트
415 - # per_ invest : 한 종목 당 투자할 금액 607 + # 업데이트 완료 후 set_invest_unit에 업데이트 날짜 저장
416 - def set_per_invest(self): 608 + def set_invest_unit(self):
417 self.get_deposit() 609 self.get_deposit()
418 self.get_balance() 610 self.get_balance()
419 - self.total_invest=self.deposit+self.total_purchase 611 + self.total_invest=self.deposit+self.total_purchase_price
420 612
421 - self.per_invest=self.simul_api.per_invest 613 + self.invest_unit=self.sf.invest_unit
422 - query="update setting_data set per_invest='%s', set_per_invest='%s'" 614 + query=f"update setting_data set invest_unit='{self.invest_unit}', set_invest_unit='{self.today}'"
423 - self.engine_bot.execute(query%(self.per_invest,self.today)) 615 + self.engine_bot.execute(query)
424 616
425 # 예수금 조회 및 저장 617 # 예수금 조회 및 저장
426 def get_deposit(self): 618 def get_deposit(self):
...@@ -429,11 +621,6 @@ class Open_Api(QAxWidget): ...@@ -429,11 +621,6 @@ class Open_Api(QAxWidget):
429 self.set_input_value("조회구분",1) 621 self.set_input_value("조회구분",1)
430 self.comm_rq_data("opw00001_req","opw00001",0,"2000") 622 self.comm_rq_data("opw00001_req","opw00001",0,"2000")
431 623
432 - # 예수금 상세현황요청 함수
433 - def _opw00001(self,sRQName,sTrCode):
434 - self.deposit=self._get_comm_data(sTrCode,sRQName,0,"d+2출금가능금액")
435 - self.deposit=int(self.deposit)
436 -
437 # 잔고 조회 및 저장 624 # 잔고 조회 및 저장
438 def get_balance(self): 625 def get_balance(self):
439 self.reset_opw00018_output() 626 self.reset_opw00018_output()
...@@ -444,64 +631,6 @@ class Open_Api(QAxWidget): ...@@ -444,64 +631,6 @@ class Open_Api(QAxWidget):
444 self.set_input_value("계좌번호",self.account_no) 631 self.set_input_value("계좌번호",self.account_no)
445 self.comm_rq_data("opw00018_req","opw00018",2,"2000") 632 self.comm_rq_data("opw00018_req","opw00018",2,"2000")
446 633
447 - # 계좌평가 잔고내역을 저장하는 변수 초기화
448 - def reset_opw00018_output(self):
449 - self.opw00018_output={'single':[],'multi':[]}
450 -
451 -
452 - # 계좌평가 잔고내역 요청
453 - # 싱글데이터를 통해 계좌에 대한 평가 잔고 데이터를 제공
454 - # 멀티데이터를 통해 보유 종목별 평가 잔고 데이터를 제공
455 - def _opw00018(self,sRQName,sTrCode):
456 - # 계좌평가 잔고 데이터 - 싱글데이터 저장
457 - self.total_purchase=self._get_comm_data(sTrCode,sRQName,0,"총매입금액")
458 - self.total_evaluated_price=self._get_comm_data(sTrCode,sRQName,0,"총평가금액")
459 - self.total_valuation=self._get_comm_data(sTrCode,sRQName,0,"총평가손익금액")
460 - self.earning_rate=self._get_comm_data(sTrCode,sRQName,0,"총수익률(%)")
461 - self.estimated_deposit=self._get_comm_data(sTrCode,sRQName,0,"추정예탁자산")
462 -
463 - self.total_purchase=int(self.total_purchase)
464 - self.total_evaluated_price=int(self.total_evaluated_price)
465 - self.total_valuation=int(self.total_valuation)
466 - self.earning_rate=float(self.earning_rate)
467 - self.estimated_deposit=int(self.estimated_deposit)
468 -
469 - self.opw00018_output['single'].append(self.total_purchase)
470 - self.opw00018_output['single'].append(self.total_evaluated_price)
471 - self.opw00018_output['single'].append(self.total_valuation)
472 - self.opw00018_output['single'].append(self.earning_rate)
473 - self.opw00018_output['single'].append(self.estimated_deposit)
474 -
475 - # 종목별 평가 잔고 데이터 - 멀티데이터 저장
476 - rows=self._get_repeat_cnt(sTrCode,sRQName)
477 -
478 - for i in range(rows):
479 - code=self._get_comm_data(sTrCode,sRQName,i,"종목번호")
480 - name=self._get_comm_data(sTrCode,sRQName,i,"종목명")
481 - quantity=self._get_comm_data(sTrCode,sRQName,i,"보유수량")
482 - purchase_price=self._get_comm_data(sTrCode,sRQName,i,"매입가")
483 - current_price=self._get_comm_data(sTrCode,sRQName,i,"현재가")
484 - total_valuation=self._get_comm_data(sTrCode,sRQName,i,"평가손익")
485 - earning_rate=self._get_comm_data(sTrCode,sRQName,i,"수익률(%)")
486 - total_purchase=self._get_comm_data(sTrCode,sRQName,i,"매입금액")
487 -
488 - code=code[1:]
489 - quantity=int(quantity)
490 - purchase_price=int(purchase_price)
491 - current_price=int(current_price)
492 - total_valuation=int(total_valuation)
493 - earning_rate=float(earning_rate)
494 - total_purchase=int(total_purchase)
495 -
496 - self.opw00018_output['multi'].append(
497 - [name,quantity,purchase_price,current_price,total_valuation,earning_rate,total_purchase,code]
498 - )
499 -
500 - # 일자별 실현 손익 요청
501 - def _opt10074(self,sRQName,sTrCode):
502 - self.total_profit=self._get_comm_data(sTrCode,sRQName,0,"실현손익")
503 - self.today_profit=self._get_comm_data(sTrCode,sRQName,0,"당일매도손익")
504 -
505 # open_api를 통해 보유한 종목을 가져오는 함수 634 # open_api를 통해 보유한 종목을 가져오는 함수
506 # 가져온 정보를 posses_item이라는 테이블에 저장 635 # 가져온 정보를 posses_item이라는 테이블에 저장
507 def get_posses_item(self): 636 def get_posses_item(self):
...@@ -556,39 +685,11 @@ class Open_Api(QAxWidget): ...@@ -556,39 +685,11 @@ class Open_Api(QAxWidget):
556 685
557 self.create_transaction_history(self.not_contract['주문번호'],item.code,contract_check,self.not_contract['체결가'],item.rate) 686 self.create_transaction_history(self.not_contract['주문번호'],item.code,contract_check,self.not_contract['체결가'],item.rate)
558 687
559 - def _opt10076(self,sRQName,sTrCode):
560 - outputs=['주문번호','종목명','주문구분','주문가격','주문수량','체결가','체결량','미체결수량',
561 - '당일매매수수료','당일매매세금','주문상태','매매구분','원주문번호','주문시간','종목코드']
562 - self.not_contract={}
563 -
564 - for key in outputs:
565 - if key not in ['주문번호','원주문번호','주문시간','종목코드']:
566 - self.not_contract[key]=int(self._get_comm_data(sTrCode,sRQName,0,key))
567 - self.not_contract[key]=self._get_comm_data(sTrCode,sRQName,0,key)
568 -
569 # posses_item 테이블을 업데이트 했을 경우 setting data 테이블에 업데이트 한 날짜를 표시 688 # posses_item 테이블을 업데이트 했을 경우 setting data 테이블에 업데이트 한 날짜를 표시
570 def setting_data_posses_stock(self): 689 def setting_data_posses_stock(self):
571 query="update setting_data set posses_stocks='%s'" 690 query="update setting_data set posses_stocks='%s'"
572 self.engine_bot.execute(query%self.today) 691 self.engine_bot.execute(query%self.today)
573 692
574 - def reset_opt10073_output(self):
575 - self.opt10073_output={'single':[],'multi':[]}
576 -
577 - def _opt10073(self,sRQName,sTrCode):
578 - rows=self._get_repeat_cnt(sTrCode,sRQName)
579 -
580 - for i in range(rows):
581 - date=self._get_comm_data(sTrCode,sRQName,i,"일자")
582 - code=self._get_comm_data(sTrCode,sRQName,i,"종목코드")
583 - code_name=self._get_comm_data(sTrCode,sRQName,i,"종목명")
584 - amount=self._get_comm_data(sTrCode,sRQName,i,"체결량")
585 - today_profit=self._get_comm_data(sTrCode,sRQName,i,"당일매도손익")
586 - earning_rate=self._get_comm_data(sTrCode,sRQName,i,"손익율")
587 -
588 - code=code.lstrip('A')
589 -
590 - self.opt10073_output['multi'].append([date,code,code_name,amount,today_profit,earning_rate])
591 -
592 # 특정 종목의 일자별 거래 데이터 조회 함수 693 # 특정 종목의 일자별 거래 데이터 조회 함수
593 def get_date_data(self,code,code_name,date): 694 def get_date_data(self,code,code_name,date):
594 self.ohlcv=defaultdict(list) 695 self.ohlcv=defaultdict(list)
...@@ -625,26 +726,6 @@ class Open_Api(QAxWidget): ...@@ -625,26 +726,6 @@ class Open_Api(QAxWidget):
625 else: 726 else:
626 return False 727 return False
627 728
628 - # 주식 일봉차트 조회 요청
629 - # 주식의 날짜별 데이터를 저장하는 함수
630 - def collector_opt10081(self,sRQName,sTrCode):
631 - ohlcv_cnt=self._get_repeat_cnt(sTrCode,sRQName)
632 -
633 - for i in range(ohlcv_cnt):
634 - date=self._get_comm_data(sTrCode,sRQName,i,"일자")
635 - open=self._get_comm_data(sTrCode,sRQName,i,"시가")
636 - high=self._get_comm_data(sTrCode,sRQName,i,"고가")
637 - low=self._get_comm_data(sTrCode,sRQName,i,"저가")
638 - close=self._get_comm_data(sTrCode,sRQName,i,"현재가")
639 - volume=self._get_comm_data(sTrCode,sRQName,i,"거래량")
640 -
641 - self.ohlcv['date'].append(date)
642 - self.ohlcv['open'].append(int(open))
643 - self.ohlcv['high'].append(int(high))
644 - self.ohlcv['low'].append(int(low))
645 - self.ohlcv['close'].append(int(close))
646 - self.ohlcv['volume'].append(int(volume))
647 -
648 # stock_info의 특정 종목 테이블에서 마지막으로 저장된 날짜를 가져오는 함수 729 # stock_info의 특정 종목 테이블에서 마지막으로 저장된 날짜를 가져오는 함수
649 # 저장된 데이터가 없다면 '0'문자를 반환 730 # 저장된 데이터가 없다면 '0'문자를 반환
650 def get_latest_date_from_stock_info(self,code_name): 731 def get_latest_date_from_stock_info(self,code_name):
...@@ -697,6 +778,167 @@ class Open_Api(QAxWidget): ...@@ -697,6 +778,167 @@ class Open_Api(QAxWidget):
697 "where code='%s' and sell_date='%s'" 778 "where code='%s' and sell_date='%s'"
698 self.engine_bot.execute(query%(0,self.today_time,code,0)) 779 self.engine_bot.execute(query%(0,self.today_time,code,0))
699 780
781 + # 주식일봉차트조회 요청 함수 - 하나의 데이터만 저장
782 + def _opt10081(self, sRQName, sTrCode):
783 + code = self._get_comm_data(sTrCode, sRQName, 0, "종목코드")
784 + # 조회하는 종목이 매수하려는 종목이 아니라면 에러메세지 출력
785 + if code != self.get_today_buy_list_code:
786 + logger.critical(f"_opt10081:({code},{self.get_today_buy_list_code})")
787 +
788 + date = self._get_comm_data(sTrCode, sRQName, 0, "일자")
789 + open = self._get_comm_data(sTrCode, sRQName, 0, "시가")
790 + high = self._get_comm_data(sTrCode, sRQName, 0, "고가")
791 + low = self._get_comm_data(sTrCode, sRQName, 0, "저가")
792 + close = self._get_comm_data(sTrCode, sRQName, 0, "현재가")
793 + volume = self._get_comm_data(sTrCode, sRQName, 0, "거래량")
794 +
795 + self.ohlcv['date'].append(date)
796 + self.ohlcv['open'].append(int(open))
797 + self.ohlcv['high'].append(int(high))
798 + self.ohlcv['low'].append(int(low))
799 + self.ohlcv['close'].append(int(close))
800 + self.ohlcv['volume'].append(int(volume))
801 +
802 + # 주식일봉차트조회 요청 함수 - 모든 행의 데이터를 저장
803 + def collector_opt10081(self, sRQName, sTrCode):
804 + # 몇개의 행을 읽어야 하는지 담는 변수
805 + ohlcv_cnt = self._get_repeat_cnt(sTrCode, sRQName)
806 +
807 + for i in range(ohlcv_cnt):
808 + date = self._get_comm_data(sTrCode, sRQName, i, "일자")
809 + open = self._get_comm_data(sTrCode, sRQName, i, "시가")
810 + high = self._get_comm_data(sTrCode, sRQName, i, "고가")
811 + low = self._get_comm_data(sTrCode, sRQName, i, "저가")
812 + close = self._get_comm_data(sTrCode, sRQName, i, "현재가")
813 + volume = self._get_comm_data(sTrCode, sRQName, i, "거래량")
814 +
815 + self.ohlcv['date'].append(date)
816 + self.ohlcv['open'].append(int(open))
817 + self.ohlcv['high'].append(int(high))
818 + self.ohlcv['low'].append(int(low))
819 + self.ohlcv['close'].append(int(close))
820 + self.ohlcv['volume'].append(int(volume))
821 +
822 + # 예수금 상세현황요청 함수
823 + def _opw00001(self,sRQName,sTrCode):
824 + self.deposit=self._get_comm_data(sTrCode,sRQName,0,"d+2출금가능금액")
825 + self.deposit=int(self.deposit)
826 +
827 + # 계좌평가 잔고내역을 저장하는 변수 초기화
828 + def reset_opw00018_output(self):
829 + # single data : 계좌에 대한 평가 잔고 데이터 제공
830 + # multi data : 보유 종목별 평가 잔고 데이터 제공
831 + self.opw00018_output={'single':[],'multi':[]}
832 +
833 + # 계좌평가 잔고내역 요청 함수
834 + def _opw00018(self,sRQName,sTrCode):
835 + # 계좌평가 잔고 데이터 - 싱글데이터 저장
836 + self.total_purchase_price=self._get_comm_data(sTrCode,sRQName,0,"총매입금액")
837 + self.total_eval_price=self._get_comm_data(sTrCode,sRQName,0,"총평가금액")
838 + self.total_eval_profit_loss_price=self._get_comm_data(sTrCode,sRQName,0,"총평가손익금액")
839 + self.total_earning_rate=self._get_comm_data(sTrCode,sRQName,0,"총수익률(%)")
840 + self.estimated_deposit=self._get_comm_data(sTrCode,sRQName,0,"추정예탁자산")
841 +
842 + self.total_purchase_price=int(self.total_purchase_price)
843 + self.total_eval_price=int(self.total_eval_price)
844 + self.total_eval_profit_loss_price=int(self.total_eval_profit_loss_price)
845 + self.total_earning_rate=float(self.total_earning_rate)
846 + self.estimated_deposit=int(self.estimated_deposit)
847 +
848 + self.opw00018_output['single'].append(self.total_purchase_price)
849 + self.opw00018_output['single'].append(self.total_eval_price)
850 + self.opw00018_output['single'].append(self.total_eval_profit_loss_price)
851 + self.opw00018_output['single'].append(self.total_earning_rate)
852 + self.opw00018_output['single'].append(self.estimated_deposit)
853 +
854 + # 종목별 평가 잔고 데이터 - 멀티데이터 저장
855 + rows=self._get_repeat_cnt(sTrCode,sRQName)
856 +
857 + for i in range(rows):
858 + code=self._get_comm_data(sTrCode,sRQName,i,"종목번호")
859 + name=self._get_comm_data(sTrCode,sRQName,i,"종목명")
860 + quantity=self._get_comm_data(sTrCode,sRQName,i,"보유수량")
861 + purchase_price=self._get_comm_data(sTrCode,sRQName,i,"매입가")
862 + current_price=self._get_comm_data(sTrCode,sRQName,i,"현재가")
863 + eval_profit_loss_price=self._get_comm_data(sTrCode,sRQName,i,"평가손익")
864 + earning_rate=self._get_comm_data(sTrCode,sRQName,i,"수익률(%)")
865 + item_total_purchase=self._get_comm_data(sTrCode,sRQName,i,"매입금액")
866 +
867 + code=code[1:]
868 + quantity=int(quantity)
869 + purchase_price=int(purchase_price)
870 + current_price=int(current_price)
871 + eval_profit_loss_price=int(eval_profit_loss_price)
872 + earning_rate=float(earning_rate)
873 + item_total_purchase=int(item_total_purchase)
874 +
875 + self.opw00018_output['multi'].append(
876 + [name,quantity,purchase_price,current_price,eval_profit_loss_price,earning_rate,item_total_purchase,code]
877 + )
878 +
879 + # 일자별 실현 손익 요청
880 + def _opt10074(self,sRQName,sTrCode):
881 + self.total_profit=self._get_comm_data(sTrCode,sRQName,0,"실현손익")
882 + self.today_profit=self._get_comm_data(sTrCode,sRQName,0,"당일매도손익")
883 +
884 + # 위탁종합거래내역 요청 함수
885 + def _opw00015(self,sRQName,sTrCode):
886 + rows = self._get_repeat_cnt(sTrCode, sRQName)
887 + acc_no = self._get_comm_data(sTrCode, sRQName, 1, "계좌번호")
888 + for i in range(rows):
889 + date = self._get_comm_data(sTrCode, sRQName, i, "거래일자")
890 +
891 + # 실시간체결요청 함수
892 + def _opt10076(self,sRQName,sTrCode):
893 + outputs=['주문번호','종목명','주문구분','주문가격','주문수량','체결가','체결량','미체결수량',
894 + '당일매매수수료','당일매매세금','주문상태','매매구분','원주문번호','주문시간','종목코드']
895 + self._data={}
896 +
897 + for key in outputs:
898 + if key not in ['주문번호','원주문번호','주문시간','종목코드']:
899 + self._data[key]=int(self._get_comm_data(sTrCode,sRQName,0,key))
900 + continue
901 + self._data[key]=self._get_comm_data(sTrCode,sRQName,0,key)
902 +
903 + # _opt10073 결과를 담는 변수를 초기화하는 함수
904 + def reset_opt10073_output(self):
905 + self.opt10073_output={'single':[],'multi':[]}
906 +
907 + # 일자별종목별실현손익요청 함수
908 + def _opt10073(self,sRQName,sTrCode):
909 + rows=self._get_repeat_cnt(sTrCode,sRQName)
910 +
911 + for i in range(rows):
912 + date=self._get_comm_data(sTrCode,sRQName,i,"일자")
913 + code=self._get_comm_data(sTrCode,sRQName,i,"종목코드")
914 + code_name=self._get_comm_data(sTrCode,sRQName,i,"종목명")
915 + amount=self._get_comm_data(sTrCode,sRQName,i,"체결량")
916 + today_profit=self._get_comm_data(sTrCode,sRQName,i,"당일매도손익")
917 + earning_rate=self._get_comm_data(sTrCode,sRQName,i,"손익율")
918 +
919 + code=code.lstrip('A')
920 +
921 + self.opt10073_output['multi'].append([date,code,code_name,amount,today_profit,earning_rate])
922 +
923 + # 주식분봉차트조회요청 함수
924 + def _opt10080(self,sRQName,sTrCode):
925 + data_cnt = self._get_repeat_cnt(sTrCode, sRQName)
926 + for i in range(data_cnt):
927 + date = self._get_comm_data(sTrCode, sRQName, i, "체결시간")
928 + open = self._get_comm_data(sTrCode, sRQName, i, "시가")
929 + high = self._get_comm_data(sTrCode, sRQName, i, "고가")
930 + low = self._get_comm_data(sTrCode, sRQName, i, "저가")
931 + close = self._get_comm_data(sTrCode, sRQName, i, "현재가")
932 + volume = self._get_comm_data(sTrCode, sRQName, i, "거래량")
933 +
934 + self.ohlcv['date'].append(date[:-2])
935 + self.ohlcv['open'].append(abs(int(open)))
936 + self.ohlcv['high'].append(abs(int(high)))
937 + self.ohlcv['low'].append(abs(int(low)))
938 + self.ohlcv['close'].append(abs(int(close)))
939 + self.ohlcv['volume'].append(int(volume))
940 + self.ohlcv['sum_volume'].append(int(0))
941 +
700 942
701 if __name__=="__main__": 943 if __name__=="__main__":
702 app=QApplication(sys.argv) 944 app=QApplication(sys.argv)
......