이하영

collector 추가

1 +import pymysql
2 +pymysql.install_as_MySQLdb()
3 +import sys
4 +
5 +from library.collector_api import *
6 +
7 +class Collector:
8 + def __init__(self):
9 + self.collector_api=collector_api()
10 +
11 + def collecting(self):
12 + self.collector_api.code_update_check()
13 +
14 +if __name__=="__main__":
15 + app=QApplication(sys.argv)
16 + c=Collector()
17 + c.collecting()
...\ No newline at end of file ...\ No newline at end of file
1 -import pymysql
2 -
3 -pymysql.install_as_MySQLdb()
4 -
5 -class Collector:
6 - def __init__(self):
...\ No newline at end of file ...\ No newline at end of file
1 -def errors(err_code):
2 - err_dict={0:('OP_ERR_NONE','정상처리'),
3 - -10:('OP_ERR_FAIL','실패'),
4 - -100:('OP_ERR_LOGIN','사용자정보교환실패'),
5 - -101:('OP_ERR_CONNECT','서버접속실패'),
6 - -102:('OP_ERR_VERSION','버전처리실패'),
7 - -103:('OP_ERR_FAIRWALL','개인방화벽실패'),
8 - -104:('OP_ERR_MEMORY','메모리보호실패'),
9 - -105:('OP_ERR_INPUT','함수입력값오류'),
10 - -106:('OP_ERR_SOCKET_CLOSED','통신연결종료'),
11 - -200:('OP_ERR_SISE_OVERFLOW','시세조회과부화'),
12 - -201:('OP_ERR_RQ_STRUCT_FAIL','전문작성초기화실패'),
13 - -202:('OP_ERR_RQ_STRING_FAIL','전문작성입력값오류'),
14 - -203:('OP_ERR_NO_DATA','데이터없음'),
15 - -204:('OP_ERR_OVER_MAX_DATA','조회가능한종목수초과'),
16 - -205:('OP_ERR_DATA_RCV_FAIL','데이터수신실패'),
17 - -206:('OP_ERR_OVER_MAX_FID','조회가능한FID수초과'),
18 - -207:('OP_ERR_REAL_CANCEL','실시간해제오류'),
19 - -300:('OP_ERR_ORD_WRONG_INPUT','입력값오류'),
20 - -301:('OP_ERR_ORD_WRONG_ACCNO','계좌비밀번호없음'),
21 - -302:('OP_ERR_OTHER_ACC_USE','타인계좌사용오류'),
22 - -303:('OP_ERR_MIS_2BILL_EXC','주문가격이20억원을초과'),
23 - -304:('OP_ERR_MIS_5BILL_EXC','주문가격이50억원을초과'),
24 - -305:('OP_ERR_MIS_1PER_EXC','주문수량이총발행주수의1 % 초과오류'),
25 - -306:('OP_ERR_MIS_3PER_EXC','주문수량이총발행주수의3 % 초과오류'),
26 - -307:('OP_ERR_SEND_FAIL','주문전송실패'),
27 - -308:('OP_ERR_ORD_OVERFLOW','주문전송과부화'),
28 - -309:('OP_ERR_MIS_300CNT_EXC','주문수량300계약초과'),
29 - -310:('OP_ERR_MIS_500CNT_EXC','주문수량500계약초과'),
30 - -340:('OP_ERR_ORD_WRONG_ACCINFO','계좌정보없음'),
31 - -500:('OP_ERR_ORD_SYMCODE_EMPTY','종목코드없음')
32 - }
33 -
34 - result=err_dict[err_code]
35 - return result
...\ No newline at end of file ...\ No newline at end of file
1 import datetime 1 import datetime
2 from sqlalchemy import * 2 from sqlalchemy import *
3 +from sqlalchemy import event
3 import pymysql 4 import pymysql
4 from pandas import * 5 from pandas import *
5 6
6 -from Logger import * 7 +from library.Logger import *
7 -import cf 8 +import library.cf
9 +from library.open_api import *
8 10
9 -class Simulator_Api: 11 +class simulator_api:
10 def __init__(self,simul_num,op,db_name): 12 def __init__(self,simul_num,op,db_name):
13 + self.cf=library.cf
11 self.simul_num=int(simul_num) 14 self.simul_num=int(simul_num)
12 15
13 if self.simul_num==-1: 16 if self.simul_num==-1:
14 - self.set_date() 17 + self.date_setting()
15 18
16 elif op=='reset': 19 elif op=='reset':
17 self.op='reset' 20 self.op='reset'
18 self.simul_reset=True 21 self.simul_reset=True
19 - self.set_variable() 22 + self.variable_setting()
20 self.rotate_date() 23 self.rotate_date()
21 24
22 elif op=='real': 25 elif op=='real':
23 self.op='real' 26 self.op='real'
24 self.simul_reset=False 27 self.simul_reset=False
25 self.db_name=db_name 28 self.db_name=db_name
26 - self.set_variable() 29 + self.variable_setting()
27 30
28 elif op=='continue': 31 elif op=='continue':
29 self.op='continue' 32 self.op='continue'
30 self.simul_reset=False 33 self.simul_reset=False
31 - self.set_variable() 34 + self.variable_setting()
32 self.rotate_date() 35 self.rotate_date()
33 36
34 else: 37 else:
35 logger.error("Invalid option") 38 logger.error("Invalid option")
36 39
37 # 오늘 날짜를 설정하는 함수 40 # 오늘 날짜를 설정하는 함수
38 - def set_date(self): 41 + def date_setting(self):
39 self.today=datetime.datetime.today().strftime("%Y%m%d") 42 self.today=datetime.datetime.today().strftime("%Y%m%d")
40 - self.today_with_time=datetime.datetime.today().strftime("%Y%m%d%H%M") 43 + self.today_detail=datetime.datetime.today().strftime("%Y%m%d%H%M")
41 - self.today_form=datetime.datetime.strptime(self.today,"%Y%m%d").date() 44 + self.today_date_form=datetime.datetime.strptime(self.today,"%Y%m%d").date()
42 45
43 # 사용되는 변수를 설정하는 함수 46 # 사용되는 변수를 설정하는 함수
44 - def set_variable(self): 47 + def variable_setting(self):
45 - self.set_date() 48 + self.date_setting()
46 self.simul_end_date=self.today # 시뮬레이션이 끝나는 날짜 49 self.simul_end_date=self.today # 시뮬레이션이 끝나는 날짜
47 self.start_min="0900" # 장 시작 시간 : 9시 50 self.start_min="0900" # 장 시작 시간 : 9시
48 51
49 self.use_min=False # 분별 시뮬레이션을 사용하는 변수 52 self.use_min=False # 분별 시뮬레이션을 사용하는 변수
50 - self.use_nine=True # 9시에만 거래를 수행하는 변수 53 + self.only_nine_buy=True # 9시에만 거래를 수행하는 변수
51 self.buy_stop=False # 거래를 중지하는 변수 54 self.buy_stop=False # 거래를 중지하는 변수
52 self.trade_check_num=False # 실시간 조건 매수 옵션. 분별 시뮬레이팅의 경우 True, 일별 시뮬레이팅의 경우 False 55 self.trade_check_num=False # 실시간 조건 매수 옵션. 분별 시뮬레이팅의 경우 True, 일별 시뮬레이팅의 경우 False
53 56
54 print("simul_num : ",self.simul_num) 57 print("simul_num : ",self.simul_num)
55 58
59 + self.volume_limit=1000
60 +
56 if self.simul_num==1: 61 if self.simul_num==1:
57 self.simul_start_date="20190101" 62 self.simul_start_date="20190101"
58 63
59 - # 매수/매도 알고리즘 설정 64 + self.db_to_realtime_daily_buy_list_num=1 # 매수리스트 설정 알고리즘
60 - self.buy_algorithm=1 65 + self.sell_list_num=1 # 매도리스트 설정 알고리즘
61 - self.sell_algorithm=1
62 66
63 # 시뮬레이션 변수 설정 67 # 시뮬레이션 변수 설정
64 self.start_invest_price=1000000 # 초기 투자자금 68 self.start_invest_price=1000000 # 초기 투자자금
...@@ -73,8 +77,8 @@ class Simulator_Api: ...@@ -73,8 +77,8 @@ class Simulator_Api:
73 elif self.simul_num==2: 77 elif self.simul_num==2:
74 self.simul_start_date="20190101" 78 self.simul_start_date="20190101"
75 79
76 - self.buy_algorithm=2 80 + self.db_to_realtime_daily_buy_list_num=2
77 - self.sell_algorithm=2 81 + self.sell_list_num=2
78 82
79 self.start_invest_price=1000000 83 self.start_invest_price=1000000
80 self.invest_unit=100000 84 self.invest_unit=100000
...@@ -82,14 +86,14 @@ class Simulator_Api: ...@@ -82,14 +86,14 @@ class Simulator_Api:
82 self.sell_point=10 86 self.sell_point=10
83 self.losscut_point=-2 87 self.losscut_point=-2
84 88
85 - self.invest_buy_limit_rate=1.01 89 + self.invest_limit_rate=1.01
86 - self.invest_sell_limit_rate=0.98 90 + self.invest_min_limit_rate=0.98
87 91
88 elif self.simul_num==3: 92 elif self.simul_num==3:
89 self.simul_start_date = "20190101" 93 self.simul_start_date = "20190101"
90 94
91 - self.buy_algorithm = 3 95 + self.db_to_realtime_daily_buy_list_num = 3
92 - self.sell_algorithm = 3 96 + self.sell_list_num = 3
93 97
94 self.start_invest_price = 1000000 98 self.start_invest_price = 1000000
95 self.invest_unit = 100000 99 self.invest_unit = 100000
...@@ -97,16 +101,18 @@ class Simulator_Api: ...@@ -97,16 +101,18 @@ class Simulator_Api:
97 self.sell_point = 10 101 self.sell_point = 10
98 self.losscut_point = -2 102 self.losscut_point = -2
99 103
100 - self.invest_buy_limit_rate = 1.01 104 + self.invest_limit_rate = 1.01
101 - self.invest_sell_limit_rate = 0.98 105 + self.invest_min_limit_rate = 0.98
102 106
103 else: 107 else:
104 logger.error("Invalid simul_num") 108 logger.error("Invalid simul_num")
105 109
106 - self.set_db_control() 110 + self.db_name_setting()
107 111
108 if self.op!='real': 112 if self.op!='real':
109 - self.set_table() 113 + # database, table 초기화
114 + self.table_setting()
115 + # 시뮬레이팅 할 날짜 저장
110 self.get_date_for_simul() 116 self.get_date_for_simul()
111 117
112 self.total_valuation_profit=0 # 매도 종목들에 대한 총 수익 118 self.total_valuation_profit=0 # 매도 종목들에 대한 총 수익
...@@ -115,47 +121,54 @@ class Simulator_Api: ...@@ -115,47 +121,54 @@ class Simulator_Api:
115 self.total_purchase_price=0 # 투자금 121 self.total_purchase_price=0 # 투자금
116 self.d2_deposit=self.start_invest_price # 예수금 = 초기자본 + 매도수익 - 투자금 122 self.d2_deposit=self.start_invest_price # 예수금 = 초기자본 + 매도수익 - 투자금
117 123
118 - self.update_balance() # 일별 정산 124 + # 일별 정산
125 + self.check_balance()
119 126
120 self.tax_rate=0.0025 # 거래 세금 127 self.tax_rate=0.0025 # 거래 세금
121 self.fees_rate=0.00015 # 거래 수수료 128 self.fees_rate=0.00015 # 거래 수수료
122 129
123 self.simul_reset_lock=False # 시뮬레이터를 멈춘 지점부터 다시 돌릴 것인지를 선택하는 변수 130 self.simul_reset_lock=False # 시뮬레이터를 멈춘 지점부터 다시 돌릴 것인지를 선택하는 변수
124 131
125 - # database를 control하기 위한 eninge 및 connection을 저장하는 함수 132 + # database를 control하기 위한 engine 및 connection을 저장하는 함수
126 - def set_db_control(self): 133 + def db_name_setting(self):
127 # simul database에 접속하는 engine 134 # simul database에 접속하는 engine
128 if self.op=='real': 135 if self.op=='real':
129 - self.engine_simul=create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 136 + self.engine_simul=create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
130 - cf.db_port + "/" + str(self.db_name), encoding='utf-8') 137 + self.cf.db_port + "/" + str(self.db_name), encoding='utf-8')
131 else: 138 else:
132 self.db_name="simul"+str(self.simul_num) 139 self.db_name="simul"+str(self.simul_num)
133 - self.engine_simul=create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 140 + self.engine_simul=create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
134 - cf.db_port + "/" + str(self.db_name), encoding='utf-8') 141 + self.cf.db_port + "/" + str(self.db_name), encoding='utf-8')
135 # daily_craw database에 접속하는 engine 142 # daily_craw database에 접속하는 engine
136 # daily_craw : 각 종목에 대해 날짜별 데이터를 저장하는 데이터베이스 143 # daily_craw : 각 종목에 대해 날짜별 데이터를 저장하는 데이터베이스
137 - self.engine_daily_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 144 + self.engine_daily_craw = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
138 - cf.db_port + "/daily_craw" , encoding='utf-8') 145 + self.cf.db_port + "/daily_craw" , encoding='utf-8')
139 # min_craw database에 접속하는 engine 146 # min_craw database에 접속하는 engine
140 # min_craw : 각 종목에 대해 분별 데이터를 저장하는 데디터베이스 147 # min_craw : 각 종목에 대해 분별 데이터를 저장하는 데디터베이스
141 - self.engine_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 148 + self.engine_craw = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
142 - cf.db_port + "/min_craw", encoding='utf-8') 149 + self.cf.db_port + "/min_craw", encoding='utf-8')
143 # daily_buy_list database에 접속하는 engine 150 # daily_buy_list database에 접속하는 engine
144 # daily_buy_list : 날짜별로 종목에 대한 데이터를 저장하는 데이터베이스 151 # daily_buy_list : 날짜별로 종목에 대한 데이터를 저장하는 데이터베이스
145 - self.engine_daily_buy_list = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 152 + self.engine_daily_buy_list = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
146 - cf.db_port + "/daily_buy_list", encoding='utf-8') 153 + self.cf.db_port + "/daily_buy_list", encoding='utf-8')
154 +
155 + from library.open_api import escape_percentage
156 + event.listen(self.engine_simul, 'before_execute', escape_percentage, retval=True)
157 + event.listen(self.engine_daily_craw, 'before_execute', escape_percentage, retval=True)
158 + event.listen(self.engine_craw, 'before_execute', escape_percentage, retval=True)
159 + event.listen(self.engine_daily_buy_list, 'before_execute', escape_percentage, retval=True)
147 160
148 # mysql에 접속하는 객체 생성 161 # mysql에 접속하는 객체 생성
149 self.db_conn = pymysql.connect( 162 self.db_conn = pymysql.connect(
150 - host=cf.db_ip, 163 + host=self.cf.db_ip,
151 - port=int(cf.db_port), 164 + port=int(self.cf.db_port),
152 - user=cf.db_id, 165 + user=self.cf.db_id,
153 - password=cf.db_pw, 166 + password=self.cf.db_pw,
154 charset='utf8' 167 charset='utf8'
155 ) 168 )
156 169
157 # 데이터베이스와 테이블을 설정 170 # 데이터베이스와 테이블을 설정
158 - def set_table(self): 171 + def table_setting(self):
159 # simul_reset==True인 경우, 시뮬레이터를 초기화하고 다시 구축 172 # simul_reset==True인 경우, 시뮬레이터를 초기화하고 다시 구축
160 if self.simul_reset: 173 if self.simul_reset:
161 self.init_database() 174 self.init_database()
...@@ -164,11 +177,11 @@ class Simulator_Api: ...@@ -164,11 +177,11 @@ class Simulator_Api:
164 else: 177 else:
165 # 시뮬레이터 데이터베이스, transaction 테이블, account_balance 테이블이 모두 존재하는 경우 이어서 시뮬레이션 178 # 시뮬레이터 데이터베이스, transaction 테이블, account_balance 테이블이 모두 존재하는 경우 이어서 시뮬레이션
166 if (self.is_simul_database_exist() and 179 if (self.is_simul_database_exist() and
167 - self.is_simul_table_exist(self.db_name,"transaction") and 180 + self.is_simul_table_exist(self.db_name,"all_stocks") and
168 - self.is_simul_table_exist(self.db_name,"account_balance")): 181 + self.is_simul_table_exist(self.db_name,"jango_data")):
169 - self.init_df_transaction() 182 + self.init_df_jango()
170 - self.init_df_account_balance() 183 + self.init_df_all_stocks()
171 - self.last_simul_date=self.get_last_date_account_balance() 184 + self.last_simul_date=self.get_jango_data_last_date()
172 # 필요한 데이터베이스와 테이블이 모두 존재하지 않는 경우, 다시 생성 185 # 필요한 데이터베이스와 테이블이 모두 존재하지 않는 경우, 다시 생성
173 else: 186 else:
174 self.init_database() 187 self.init_database()
...@@ -178,8 +191,8 @@ class Simulator_Api: ...@@ -178,8 +191,8 @@ class Simulator_Api:
178 def init_database(self): 191 def init_database(self):
179 self.drop_database() 192 self.drop_database()
180 self.create_database() 193 self.create_database()
181 - self.init_df_account_balance() 194 + self.init_df_jango() # 잔고 내역 테이블
182 - self.init_df_transaction() 195 + self.init_df_all_stocks() # 모든 거래 내역을 저장하는 테이블
183 196
184 # 시뮬레이터 데이터베이스 삭제 197 # 시뮬레이터 데이터베이스 삭제
185 def drop_database(self): 198 def drop_database(self):
...@@ -213,27 +226,27 @@ class Simulator_Api: ...@@ -213,27 +226,27 @@ class Simulator_Api:
213 else: 226 else:
214 return False 227 return False
215 228
216 - # account_balance table 생성 229 + # jango table 생성 : 잔고 내역을 저장하는 테이블
217 - def init_df_account_balance(self): 230 + def init_df_jango(self):
218 - a_balance={'id':[]} 231 + jango_temp={'id':[]}
219 - self.account_balance=DataFrame(a_balance, 232 + self.jango=DataFrame(jango_temp,
220 - columns=['date', 'today_earning_rate', 'sum_valuation_profit', 'total_profit', 233 + columns=['date', 'today_earning_rate', 'sum_valuation_profit', 'total_profit',
221 - 'today_profit','today_profitcut_count', 'today_losscut_count', 234 + 'today_profit','today_profitcut_count', 'today_losscut_count',
222 - 'today_profitcut','today_losscut','d2_deposit', 'total_possess_count', 235 + 'today_profitcut','today_losscut','d2_deposit', 'total_possess_count',
223 - 'today_buy_count', 'total_invest', 236 + 'today_buy_count', 'today_buy_list_count', 'total_invest',
224 - 'sum_item_total_purchase', 'total_evaluation', 'today_rate', 237 + 'sum_item_total_purchase', 'total_evaluation', 'today_rate',
225 - 'today_invest_price','today_sell_price', 'volume_limit', 'sell_point', 238 + 'today_invest_price','today_sell_price', 'volume_limit', 'sell_point',
226 - 'invest_unit','limit_money', 'total_profitcut', 239 + 'invest_limit_rate','invest_unit','limit_money', 'total_profitcut',
227 - 'total_losscut','total_profitcut_count','total_losscut_count', 240 + 'total_losscut','total_profitcut_count','total_losscut_count',
228 - 'today_buy_today_sell_count','today_buy_today_possess_count', 241 + 'today_buy_today_sell_count','today_buy_today_possess_count',
229 - 'today_buy_today_profitcut_count','today_buy_today_losscut_count', 242 + 'today_buy_today_profitcut_count','today_buy_today_losscut_count',
230 - 'today_buy_today_profitcut_rate','today_buy_today_losscut_rate'], 243 + 'today_buy_today_profitcut_rate','today_buy_today_losscut_rate'],
231 - index=a_balance['id']) 244 + index=jango_temp['id'])
232 - 245 +
233 - # transaction table 생성 246 + # all_stocks table 생성 : 모든 거래내역을 저장하는 테이블
234 def init_df_all_stocks(self): 247 def init_df_all_stocks(self):
235 - all_stocks={'id':[]} 248 + all_stocks_temp={'id':[]}
236 - self.df_all_stocks=DataFrame(all_stocks, 249 + self.df_all_stocks=DataFrame(all_stocks_temp,
237 columns=['id', 'order_num', 'code', 'code_name', 'rate', 'purchase_rate', 250 columns=['id', 'order_num', 'code', 'code_name', 'rate', 'purchase_rate',
238 'purchase_price','present_price', 'valuation_price','valuation_profit', 251 'purchase_price','present_price', 'valuation_price','valuation_profit',
239 'holding_amount', 'buy_date', 'item_total_purchase','chegyul_check', 252 'holding_amount', 'buy_date', 'item_total_purchase','chegyul_check',
...@@ -244,9 +257,9 @@ class Simulator_Api: ...@@ -244,9 +257,9 @@ class Simulator_Api:
244 "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate", 257 "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate",
245 "clo60_diff_rate", "clo120_diff_rate"]) 258 "clo60_diff_rate", "clo120_diff_rate"])
246 259
247 - # account_balance(잔고 데이터)에 저장된 가장 최근의 날짜를 가져오는 함수 260 + #jango(잔고 테이블)에 저장된 가장 최근의 날짜를 가져오는 함수
248 - def get_last_date_account_balance(self): 261 + def get_jango_data_last_date(self):
249 - query = "SELECT date from account_balance order by date desc limit 1" 262 + query = "SELECT date from jango_data order by date desc limit 1"
250 result=self.engine_simul.execute(query).fechall() 263 result=self.engine_simul.execute(query).fechall()
251 return result[0][0] 264 return result[0][0]
252 265
...@@ -257,32 +270,32 @@ class Simulator_Api: ...@@ -257,32 +270,32 @@ class Simulator_Api:
257 f"where date >= '{self.simul_start_date}' and date <= '{self.simul_end_date}' group by date" 270 f"where date >= '{self.simul_start_date}' and date <= '{self.simul_end_date}' group by date"
258 self.date_rows = self.engine_daily_craw.execute(query).fetchall() 271 self.date_rows = self.engine_daily_craw.execute(query).fetchall()
259 272
260 - # 거래한 데이터를 바탕으로 거래이력(transaction) 테이블을 정산하는 함수 273 + # 거래한 데이터를 바탕으로 거래이력(all_stocks) 테이블을 정산하는 함수
261 - def update_balance(self): 274 + def check_balance(self):
262 - # transaction table이 존재하지 않을 경우 return 275 + # all_stocks table이 존재하지 않을 경우 return
263 - if not self.is_simul_table_exist(self.db_name,"transaction"): 276 + if not self.is_simul_table_exist(self.db_name,"all_stocks"):
264 return 277 return
265 278
266 - query="select sum(valuation_profit) from transaction" 279 + query="select sum(valuation_profit) from all_stocks"
267 self.sum_valuation_profit=self.engine_simul.execute(query).fethcall()[0][0] # 총수익금 (종목별 평가 금액의 합) 280 self.sum_valuation_profit=self.engine_simul.execute(query).fethcall()[0][0] # 총수익금 (종목별 평가 금액의 합)
268 281
269 self.total_invest_price=self.start_invest_price+self.sum_valuation_profit # 총자산 282 self.total_invest_price=self.start_invest_price+self.sum_valuation_profit # 총자산
270 283
271 - query="select sum(item_total_purchase) from transaction where sell_date='%s'" 284 + query="select sum(item_total_purchase) from all_stocks where sell_date='%s'"
272 self.total_purchase_price=self.engine_simul.execute(query%(0)).fethcall()[0][0] # 총투자금액 285 self.total_purchase_price=self.engine_simul.execute(query%(0)).fethcall()[0][0] # 총투자금액
273 if self.total_purchase_price is None: 286 if self.total_purchase_price is None:
274 self.total_purchase_price=0 287 self.total_purchase_price=0
275 288
276 - query="select sum(valuation_profit) from transaction where sell_date!='%s'" 289 + query="select sum(valuation_profit) from all_stocks where sell_date!='%s'"
277 self.total_valuation_profit=self.engine_simul.execute(query%(0)).fetchall()[0][0] # 매도 종목들에 대한 수익 290 self.total_valuation_profit=self.engine_simul.execute(query%(0)).fetchall()[0][0] # 매도 종목들에 대한 수익
278 if self.total_valuation_profit is None: 291 if self.total_valuation_profit is None:
279 self.total_valuation_profit=0 292 self.total_valuation_profit=0
280 293
281 - self.d2_deposit=self.start_invest_price+self.total_valuation_profit-self.total_purchase_price # 예수금 294 + self.d2_deposit=self.start_invest_price+self.total_valuation_profit-self.total_purchase_price # 투자가능 예수금
282 295
283 # 날짜별로 돌아가면서 시뮬레이션을 실행하는 함수 296 # 날짜별로 돌아가면서 시뮬레이션을 실행하는 함수
284 def rotate_date(self): 297 def rotate_date(self):
285 - for i in range(self.date_rows): 298 + for i in range(1,len(self.date_rows)):
286 date_rows_today=self.date_rows[i][0] # 시뮬레이팅 할 날짜 299 date_rows_today=self.date_rows[i][0] # 시뮬레이팅 할 날짜
287 date_rows_yesterday=self.date_rows[i-1][0] # 시뮬레이팅 하루 전 날짜 300 date_rows_yesterday=self.date_rows[i-1][0] # 시뮬레이팅 하루 전 날짜
288 301
...@@ -299,118 +312,118 @@ class Simulator_Api: ...@@ -299,118 +312,118 @@ class Simulator_Api:
299 # 일별 시뮬레이션 312 # 일별 시뮬레이션
300 else: 313 else:
301 self.simul_by_date(date_rows_today,date_rows_yesterday,i) 314 self.simul_by_date(date_rows_today,date_rows_yesterday,i)
302 - # 시뮬레이션을 완료한 후 account_balance 테이블 업데이트 315 + # 시뮬레이션을 완료한 후 jango_data 테이블 업데이트
303 - self.arrange_account_balance() 316 + self.arrange_jango_data()
304 - 317 +
305 - # 하루에 대한 시뮬레이션이 끝난 뒤 해당 날짜의 잔고(account_balance)정보를 업데이트하는 함수 318 + # 하루에 대한 시뮬레이션이 끝난 뒤 해당 날짜의 잔고(jango_data)정보를 업데이트하는 함수
306 - def arrange_account_balance(self): 319 + def arrange_jango_data(self):
307 - if self.engine_simul.dialect.has_table(self.engine_simul,"account_balance"): 320 + if self.engine_simul.dialect.has_table(self.engine_simul,"jango_data"):
308 - len_date=self.get_len_account_balance_data() 321 + len_date=self.get_len_jango_data_date()
309 - query="select date from account_balance" 322 + query="select date from jango_data"
310 rows=self.engine_simul.execute(query).fetchall() 323 rows=self.engine_simul.execute(query).fetchall()
311 324
312 logger.debug("account balance 최종 정산") 325 logger.debug("account balance 최종 정산")
313 326
314 for i in range(len_date): 327 for i in range(len_date):
315 # today_buy_count : 오늘 매수한 종목의 수 328 # today_buy_count : 오늘 매수한 종목의 수
316 - query="update account_balance " \ 329 + query="update jango_data " \
317 "set " \ 330 "set " \
318 - "today_buy_count=(select count(*) from (select code from transaction where buy_date like '%s')) "\ 331 + "today_buy_count=(select count(*) from (select code from all_stocks where buy_date like '%s')) "\
319 "where date='%s'" 332 "where date='%s'"
320 self.engine_simul.execute(query%("%%"+str(rows[i][0])+"%%",rows[i][0])) 333 self.engine_simul.execute(query%("%%"+str(rows[i][0])+"%%",rows[i][0]))
321 334
322 # today_buy_today_sell_count : 오늘 매수하고 오늘 매도한 종목의 수 335 # today_buy_today_sell_count : 오늘 매수하고 오늘 매도한 종목의 수
323 - query="update account_balance " \ 336 + query="update jango_data " \
324 "set " \ 337 "set " \
325 "today_buy_today_sell_count=" \ 338 "today_buy_today_sell_count=" \
326 "(select count(*) from " \ 339 "(select count(*) from " \
327 - "(select code from transaction where buy_date like '%s' and sell_date!=0 group by code)) " \ 340 + "(select code from all_stocks where buy_date like '%s' and sell_date!=0 group by code)) " \
328 "where date='%s'" 341 "where date='%s'"
329 self.engine_simul.execute(query%("%%"+str(rows[i][0])+"%%",rows[i][0])) 342 self.engine_simul.execute(query%("%%"+str(rows[i][0])+"%%",rows[i][0]))
330 343
331 # today_buy_today_possess_count : 오늘 매수하였으나 매도하지 않은 종목의 수 344 # today_buy_today_possess_count : 오늘 매수하였으나 매도하지 않은 종목의 수
332 - query="update account_balance " \ 345 + query="update jango_data " \
333 "set" \ 346 "set" \
334 "today_buy_today_possess_count=" \ 347 "today_buy_today_possess_count=" \
335 "(select count(*) from " \ 348 "(select count(*) from " \
336 - "(select code from transaction where buy_date like '%s' and sell_date='%s' group by code)) " \ 349 + "(select code from all_stocks where buy_date like '%s' and sell_date='%s' group by code)) " \
337 "where date='%s'" 350 "where date='%s'"
338 self.engine_simul.execute(query%("%%"+rows[i][0]+"%%",0,rows[i][0])) 351 self.engine_simul.execute(query%("%%"+rows[i][0]+"%%",0,rows[i][0]))
339 352
340 # today_buy_today_profitcut_count : 오늘 매수하고 익절한 종목의 수 353 # today_buy_today_profitcut_count : 오늘 매수하고 익절한 종목의 수
341 - query="update account_balance " \ 354 + query="update jango_data " \
342 "set " \ 355 "set " \
343 "today_buy_today_profitcut_count=" \ 356 "today_buy_today_profitcut_count=" \
344 "(select count(*) from " \ 357 "(select count(*) from " \
345 - "(select code from transaction " \ 358 + "(select code from all_stocks " \
346 "where buy_date like '%s' and sell_date like '%s' and sell_rate>'%s' group by code)) " \ 359 "where buy_date like '%s' and sell_date like '%s' and sell_rate>'%s' group by code)) " \
347 "where date='%s'" 360 "where date='%s'"
348 self.engine_simul.execute(query%("%%" + rows[i][0] + "%%", "%%" + rows[i][0] + "%%", 0, rows[i][0])) 361 self.engine_simul.execute(query%("%%" + rows[i][0] + "%%", "%%" + rows[i][0] + "%%", 0, rows[i][0]))
349 362
350 # today_buy_today_profitcut_rate : 오늘 매수하고 익절한 종목의 수익률 363 # today_buy_today_profitcut_rate : 오늘 매수하고 익절한 종목의 수익률
351 - query = "update account_balance " \ 364 + query = "update jango_data " \
352 "set " \ 365 "set " \
353 "today_buy_today_profitcut_rate=round(today_buy_today_profitcut_count /today_buy_count *100,2) "\ 366 "today_buy_today_profitcut_rate=round(today_buy_today_profitcut_count /today_buy_count *100,2) "\
354 "where date = '%s'" 367 "where date = '%s'"
355 self.engine_simul.execute(query%(rows[i][0])) 368 self.engine_simul.execute(query%(rows[i][0]))
356 369
357 # today_buy_today_losscut_count : 오늘 매수하고 손절한 종목의 수 370 # today_buy_today_losscut_count : 오늘 매수하고 손절한 종목의 수
358 - query = "update account_balance " \ 371 + query = "update jango_data " \
359 "set " \ 372 "set " \
360 "today_buy_today_losscut_count=" \ 373 "today_buy_today_losscut_count=" \
361 "(select count(*) from " \ 374 "(select count(*) from " \
362 - "(select code from transaction " \ 375 + "(select code from all_stocks " \
363 - "where buy_date like '%s' and sell_date like '%s' and sell_rate < '%s' group by code)) " \ 376 + "where buy_date like '%s' and sell_date like '%s' and sell_rate < '%s' group by code)) " \
364 "WHERE date='%s'" 377 "WHERE date='%s'"
365 self.engine_simul.execute(query%("%%" + rows[i][0] + "%%", "%%" + rows[i][0] + "%%", 0, rows[i][0])) 378 self.engine_simul.execute(query%("%%" + rows[i][0] + "%%", "%%" + rows[i][0] + "%%", 0, rows[i][0]))
366 379
367 # today_buy_today_losscut_rate : 오늘 매수하고 손절한 종목의 수익률 380 # today_buy_today_losscut_rate : 오늘 매수하고 손절한 종목의 수익률
368 - query = "update account_balance " \ 381 + query = "update jango_data " \
369 "set " \ 382 "set " \
370 "today_buy_today_losscut_rate=round(today_buy_today_losscut_count /today_buy_count *100,2) " \ 383 "today_buy_today_losscut_rate=round(today_buy_today_losscut_count /today_buy_count *100,2) " \
371 "WHERE date = '%s'" 384 "WHERE date = '%s'"
372 self.engine_simul.execute(query%(rows[i][0])) 385 self.engine_simul.execute(query%(rows[i][0]))
373 386
374 # total_profitcut_count : 총 익절한 종목의 수 387 # total_profitcut_count : 총 익절한 종목의 수
375 - query = "update account_balance " \ 388 + query = "update jango_data " \
376 "set " \ 389 "set " \
377 "total_profitcut_count=" \ 390 "total_profitcut_count=" \
378 "(select count(*) from " \ 391 "(select count(*) from " \
379 - "(select code from transaction where sell_rate >= '%s' group by code)) "\ 392 + "(select code from all_stocks where sell_rate >= '%s' group by code)) "\
380 "WHERE date='%s'" 393 "WHERE date='%s'"
381 self.engine_simul.execute(query%(0, rows[i][0])) 394 self.engine_simul.execute(query%(0, rows[i][0]))
382 395
383 # total_profitcut : 총 익절한 금액 (매도가 - 매수가) 396 # total_profitcut : 총 익절한 금액 (매도가 - 매수가)
384 - query = "update account_balance " \ 397 + query = "update jango " \
385 "set " \ 398 "set " \
386 "total_profitcut=sum" \ 399 "total_profitcut=sum" \
387 - "(select sell_price-purchase_price from transaction " \ 400 + "(select sell_price-purchase_price from all_stocks " \
388 "where sell_price>=purchase_price group by code))" \ 401 "where sell_price>=purchase_price group by code))" \
389 "WHERE date = '%s'" 402 "WHERE date = '%s'"
390 self.engine_simul.execute(query%(rows[i][0])) 403 self.engine_simul.execute(query%(rows[i][0]))
391 404
392 # total_losscut_count : 총 손절한 종목의 수 405 # total_losscut_count : 총 손절한 종목의 수
393 - query = "update account_balance " \ 406 + query = "update jango_data " \
394 "set " \ 407 "set " \
395 "total_losscut_count=" \ 408 "total_losscut_count=" \
396 "(select count(*) from " \ 409 "(select count(*) from " \
397 - "(select code from transaction where sell_rate < '%s' group by code )) " \ 410 + "(select code from all_stocks where sell_rate < '%s' group by code )) " \
398 "WHERE date='%s'" 411 "WHERE date='%s'"
399 self.engine_simul.execute(query%(0,rows[i][0])) 412 self.engine_simul.execute(query%(0,rows[i][0]))
400 413
401 # total_losscut : 총 손절한 금액 (매수가 - 매도가) 414 # total_losscut : 총 손절한 금액 (매수가 - 매도가)
402 - query = "update account_balance " \ 415 + query = "update jango_data " \
403 "set " \ 416 "set " \
404 "total_losscut=sum" \ 417 "total_losscut=sum" \
405 - "(select purchase_price-sell_price from transaction " \ 418 + "(select purchase_price-sell_price from all_stocks " \
406 "where purchase_price>=sell_price)) " \ 419 "where purchase_price>=sell_price)) " \
407 "where date='%s'" 420 "where date='%s'"
408 self.engine_simul.execute(query%(rows[i][0])) 421 self.engine_simul.execute(query%(rows[i][0]))
409 print("account balance 정산 완료") 422 print("account balance 정산 완료")
410 423
411 - # account_balance에 저장된 일자를 반환하는 함수 424 + # jango_data에 저장된 일자를 반환하는 함수
412 - def get_len_account_balance_data(self): 425 + def get_len_jango_data_date(self):
413 - query="select date from account_balance" 426 + query="select date from jango_data"
414 rows=self.engine_simul.execute(query).fetchall() 427 rows=self.engine_simul.execute(query).fetchall()
415 return len(rows) 428 return len(rows)
416 429
...@@ -418,22 +431,22 @@ class Simulator_Api: ...@@ -418,22 +431,22 @@ class Simulator_Api:
418 def simul_by_min(self, date_rows_today, date_rows_yesterday, i): 431 def simul_by_min(self, date_rows_today, date_rows_yesterday, i):
419 print("************************** date: " + date_rows_today) 432 print("************************** date: " + date_rows_today)
420 # 시뮬레이팅 전에 변수 초기화 433 # 시뮬레이팅 전에 변수 초기화
421 - self.set_daily_variable() 434 + self.daily_variable_setting()
422 # daily_buy_list에 시뮬레이팅 할 날짜에 해당하는 테이블과 전 날 테이블이 존재하는지 확인 435 # daily_buy_list에 시뮬레이팅 할 날짜에 해당하는 테이블과 전 날 테이블이 존재하는지 확인
423 if self.is_date_exist(date_rows_today) and self.is_date_exist(date_rows_yesterday): 436 if self.is_date_exist(date_rows_today) and self.is_date_exist(date_rows_yesterday):
424 self.db_to_realtime_daily_buy_list(date_rows_today, date_rows_yesterday, i) # 매수리스트 확인 437 self.db_to_realtime_daily_buy_list(date_rows_today, date_rows_yesterday, i) # 매수리스트 확인
425 self.trading_by_min(date_rows_today, date_rows_yesterday, i) # 시뮬레이팅 시작 438 self.trading_by_min(date_rows_today, date_rows_yesterday, i) # 시뮬레이팅 시작
426 - self.db_to_account_balance(date_rows_today) # 잔고 테이블 업데이트 439 + self.db_to_jango(date_rows_today) # 잔고 테이블 업데이트
427 440
428 - # transaction 테이블이 존재하고, 현재 보유 중인 종목이 있는 경우, 해당 종목에 대해 데이터베이스 업데이트 441 + # all_stocks 테이블이 존재하고, 현재 보유 중인 종목이 있는 경우, 해당 종목에 대해 데이터베이스 업데이트
429 - if self.is_simul_table_exist(self.db_name, "transaction") and len(self.get_data_from_possessed_item()) != 0: 442 + if self.is_simul_table_exist(self.db_name, "all_stocks") and len(self.get_data_from_possessed_item()) != 0:
430 - self.update_transaction_by_date(date_rows_today, option='ALL') 443 + self.update_all_db_by_date(date_rows_today, option='ALL')
431 444
432 else: 445 else:
433 print("테이블이 존재하지 않습니다") 446 print("테이블이 존재하지 않습니다")
434 447
435 # 매일 시뮬레이션이 돌기 전에 변수를 초기화하는 함수 448 # 매일 시뮬레이션이 돌기 전에 변수를 초기화하는 함수
436 - def set_daily_variable(self): 449 + def daily_variable_setting(self):
437 self.buy_stop=False 450 self.buy_stop=False
438 self.today_invest_price=0 451 self.today_invest_price=0
439 452
...@@ -446,50 +459,50 @@ class Simulator_Api: ...@@ -446,50 +459,50 @@ class Simulator_Api:
446 else: 459 else:
447 return False 460 return False
448 461
449 - # 매수 할 종목의 리스트를 선정하는 함수 462 + # 다음날 매수 할 종목의 리스트를 선정하는 함수
450 def db_to_realtime_daily_buy_list(self,date_rows_today,date_rows_yesterday,i): 463 def db_to_realtime_daily_buy_list(self,date_rows_today,date_rows_yesterday,i):
451 - to_buy_list=None 464 + realtime_daily_buy_list=None # 다음날 매수할 종목 리스트를 저장하는 변수
452 -
453 # (5,20) 골든크로스 465 # (5,20) 골든크로스
454 - if self.buy_algorithm == 1: 466 + if self.db_to_realtime_daily_buy_list_num == 1:
455 query=f"select * from '{date_rows_yesterday}' " \ 467 query=f"select * from '{date_rows_yesterday}' " \
456 f"where yes_clo20>yes_clo5 and clo5>clo20 and close<'{self.invest_unit}' group by code" 468 f"where yes_clo20>yes_clo5 and clo5>clo20 and close<'{self.invest_unit}' group by code"
457 - to_buy_list=self.engine_daily_buy_list.execute(query).fetchall() 469 + realtime_daily_buy_list=self.engine_daily_buy_list.execute(query).fetchall()
458 470
459 # (20,60) 골든크로스 471 # (20,60) 골든크로스
460 - elif self.buy_algorithm == 2: 472 + elif self.db_to_realtime_daily_buy_list_num == 2:
461 query = f"select * from '{date_rows_yesterday}' " \ 473 query = f"select * from '{date_rows_yesterday}' " \
462 f"where yes_clo40 > yes_clo5 and clo5 > clo40 and close < '{self.invest_unit}' group by code" 474 f"where yes_clo40 > yes_clo5 and clo5 > clo40 and close < '{self.invest_unit}' group by code"
463 - to_buy_list = self.engine_daily_buy_list.execute(query).fetchall() 475 + realtime_daily_buy_list = self.engine_daily_buy_list.execute(query).fetchall()
464 476
465 else: 477 else:
466 logger.error("Invalid Algorithm Setting...") 478 logger.error("Invalid Algorithm Setting...")
467 479
468 # 알고리즘에 의해 선택된 항목이 존재한다면 데이터베이스에 해당 항목 업데이트 480 # 알고리즘에 의해 선택된 항목이 존재한다면 데이터베이스에 해당 항목 업데이트
469 - if len(to_buy_list) > 0: 481 + if len(realtime_daily_buy_list) > 0:
470 - df_to_buy_list = DataFrame(to_buy_list, 482 + df_realtime_daily_buy_list = DataFrame(realtime_daily_buy_list,
471 - columns=['index', 'index2', 'date', 'check_item', 'code', 483 + columns=['index', 'index2', 'date', 'check_item', 'code',
472 - 'code_name', 'd1_diff','d1_diff_rate', 484 + 'code_name', 'd1_diff','d1_diff_rate',
473 - 'close', 'open', 'high','low', 'volume', 485 + 'close', 'open', 'high','low', 'volume',
474 - 'clo5', 'clo10', 'clo20', 'clo60', 'clo120', 486 + 'clo5', 'clo10', 'clo20', 'clo60', 'clo120',
475 - "clo5_diff_rate", "clo10_diff_rate", "clo20_diff_rate", 487 + "clo5_diff_rate", "clo10_diff_rate", "clo20_diff_rate",
476 - "clo60_diff_rate", "clo120_diff_rate", 488 + "clo60_diff_rate", "clo120_diff_rate",
477 - 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120', 489 + 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
478 - 'vol5', 'vol10', 'vol20', 'vol60', 'vol120']) 490 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120'])
479 - 491 +
480 - # to_buy_list 중 종목 code가 6자리의 정수로 된 항목만 선택 492 + # 다음날 매수할 종목 중 code가 6자리의 정수로 된 항목만 선택
481 - to_buy_list['code'] = to_buy_list['code'].apply(lambda x: "{:0>6d}".format(int(x))) 493 + df_realtime_daily_buy_list['code'] = df_realtime_daily_buy_list['code'].apply(
494 + lambda x: "{:0>6d}".format(int(x)))
482 495
483 # 시뮬레이터 496 # 시뮬레이터
484 if self.op != 'real': 497 if self.op != 'real':
485 - to_buy_list['check_item'] = int(0) 498 + df_realtime_daily_buy_list['check_item'] = int(0)
486 - to_buy_list.to_sql('realtime_daily_buy_list', self.engine_simul, if_exists='replace') 499 + df_realtime_daily_buy_list.to_sql('realtime_daily_buy_list', self.engine_simul, if_exists='replace')
487 500
488 # 현재 보유 중인 종목은 매수 리스트(realtime_daily_buy_list) 에서 제거 501 # 현재 보유 중인 종목은 매수 리스트(realtime_daily_buy_list) 에서 제거
489 - if self.is_simul_table_exist(self.db_name, "transaction"): 502 + if self.is_simul_table_exist(self.db_name, "all_stocks"):
490 query = "delete from realtime_daily_buy_list " \ 503 query = "delete from realtime_daily_buy_list " \
491 "where code in " \ 504 "where code in " \
492 - "(select code from transaction where sell_date = '0')" 505 + "(select code from all_stocks where sell_date = '0')"
493 self.engine_simul.execute(query) 506 self.engine_simul.execute(query)
494 507
495 # realtime_daily_buy_list 테이블에 저장 된 종목들을 저장 508 # realtime_daily_buy_list 테이블에 저장 된 종목들을 저장
...@@ -497,12 +510,12 @@ class Simulator_Api: ...@@ -497,12 +510,12 @@ class Simulator_Api:
497 510
498 # 모의투자 / 실전투자 511 # 모의투자 / 실전투자
499 else: 512 else:
500 - to_buy_list['check_item'] = int(0) 513 + df_realtime_daily_buy_list['check_item'] = int(0)
501 - to_buy_list.to_sql('realtime_daily_buy_list', self.engine_simul, if_exists='replace') 514 + df_realtime_daily_buy_list.to_sql('realtime_daily_buy_list', self.engine_simul, if_exists='replace')
502 515
503 # 현재 보유 중인 종목들은 삭제 516 # 현재 보유 중인 종목들은 삭제
504 query = "delete from realtime_daily_buy_list where code in (select code from possessed_item)" 517 query = "delete from realtime_daily_buy_list where code in (select code from possessed_item)"
505 - self.engine_simul.execute(sql) 518 + self.engine_simul.execute(query)
506 else: 519 else:
507 self.len_df_realtime_daily_buy_list = 0 520 self.len_df_realtime_daily_buy_list = 0
508 521
...@@ -530,8 +543,8 @@ class Simulator_Api: ...@@ -530,8 +543,8 @@ class Simulator_Api:
530 self.show_info(date_rows_today) 543 self.show_info(date_rows_today)
531 544
532 # 현재 보유중인 종목이 존재한다면, 보유 종목의 주가를 업데이트 545 # 현재 보유중인 종목이 존재한다면, 보유 종목의 주가를 업데이트
533 - if self.is_simul_table_exist(self.db_name,"transaction"): 546 + if self.is_simul_table_exist(self.db_name,"all_stocks"):
534 - self.update_transaction_by_date(date_rows_today,option='OPEN') 547 + self.update_all_db_by_date(date_rows_today,option='OPEN')
535 548
536 # 분별 시간 데이터를 가져오기 549 # 분별 시간 데이터를 가져오기
537 self.get_min_data_for_simul(date_rows_today) 550 self.get_min_data_for_simul(date_rows_today)
...@@ -540,84 +553,87 @@ class Simulator_Api: ...@@ -540,84 +553,87 @@ class Simulator_Api:
540 for t in range(len(self.min_data_rows)): 553 for t in range(len(self.min_data_rows)):
541 min=self.min_data_rows[t][0] 554 min=self.min_data_rows[t][0]
542 # 현재 보유 종목이 있는 경우 555 # 현재 보유 종목이 있는 경우
543 - if self.is_simul_table_exist(self.db_name,"account_balance"): 556 + if self.is_simul_table_exist(self.db_name,"all_stocks") and len(self.get_data_from_possessed_item())!=0:
544 self.show_info(min) 557 self.show_info(min)
545 # 종목 데이터 업데이트 558 # 종목 데이터 업데이트
546 - self.update_transaction_by_min(min) 559 + self.update_all_db_by_min(min)
547 - self.update_transaction_etc() 560 + self.update_all_db_etc()
548 # 매도 561 # 매도
549 self.auto_trade_sell_stock(min,i) 562 self.auto_trade_sell_stock(min,i)
550 563
551 # 매수를 진행할 금액이 남아있는 경우 564 # 매수를 진행할 금액이 남아있는 경우
552 - if not self.buy_stop and self.check_balance(): 565 + if not self.buy_stop and self.jango_check():
553 # 매수할 종목리스트 저장 566 # 매수할 종목리스트 저장
554 self.get_realtime_daily_buy_list() 567 self.get_realtime_daily_buy_list()
555 # 매수할 종목이 존재한다면 매수 568 # 매수할 종목이 존재한다면 매수
556 if self.len_df_realtime_daily_buy_list>0: 569 if self.len_df_realtime_daily_buy_list>0:
557 - self.auto_trade_buy_stock(min,date_rows_today,date_rows_yesterday) 570 + self.auto_trade_stock_realtime(min,date_rows_today,date_rows_yesterday)
558 else: 571 else:
559 print("금일 매수할 종목이 없습니다") 572 print("금일 매수할 종목이 없습니다")
560 # 보유 종목이 없는 경우 573 # 보유 종목이 없는 경우
561 else: 574 else:
562 - if not self.buy_stop and self.check_balance(): 575 + if not self.buy_stop and self.jango_check():
563 - self.auto_trade_buy_stock(min,date_rows_today,date_rows_yesterday) 576 + self.auto_trade_stock_realtime(min,date_rows_today,date_rows_yesterday)
564 577
565 - if not self.buy_stop and self.use_nine: 578 + if not self.buy_stop and self.only_nine_buy:
566 print("9시 매수를 종료합니다") 579 print("9시 매수를 종료합니다")
567 self.buy_stop=True 580 self.buy_stop=True
568 581
569 # 시뮬레이팅 정보를 출력하는 함수 582 # 시뮬레이팅 정보를 출력하는 함수
570 def show_info(self,date): 583 def show_info(self,date):
571 print("simulator num : ",self.simul_num) 584 print("simulator num : ",self.simul_num)
572 - if self.is_simul_table_exist(self.db_name,"transaction"): 585 + if self.is_simul_table_exist(self.db_name,"all_stocks"):
573 print("simulating 시간 : ",date) 586 print("simulating 시간 : ",date)
574 print("보유종목 수 : ",self.get_count_possess_item()) 587 print("보유종목 수 : ",self.get_count_possess_item())
575 588
576 # 현재 보유하고 있는 종목수를 반환하는 함수 589 # 현재 보유하고 있는 종목수를 반환하는 함수
577 def get_count_possess_item(self): 590 def get_count_possess_item(self):
578 - query="select count(*) from transaction where sell_date='0'" 591 + query="select count(*) from all_stocks where sell_date='0'"
579 result=self.engine_simul.execute(query).fetchall() 592 result=self.engine_simul.execute(query).fetchall()
580 return result[0][0] 593 return result[0][0]
581 594
582 # 보유 종목의 주가를 일별로 업데이트하는 함수 595 # 보유 종목의 주가를 일별로 업데이트하는 함수
583 - def update_transaction_by_date(self,date,option='ALL'): 596 + def update_all_db_by_date(self,date,option='ALL'):
584 - possess_item_list=self.get_data_from_possess_item() 597 + possessed_item_list=self.get_data_from_possessed_item()
585 598
586 - if len(possess_item_list)==0: 599 + if len(possessed_item_list)==0:
587 print("보유 종목이 없습니다") 600 print("보유 종목이 없습니다")
588 601
589 - for i in range(len(possess_item_list)): 602 + for i in range(len(possessed_item_list)):
590 - code_name=possess_item_list[i][0] 603 + code_name=possessed_item_list[i][0]
591 - result=self.get_current_price_by_date(code_name,date) 604 + result=self.get_now_price_by_date(code_name,date)
592 if result==False: 605 if result==False:
593 continue 606 continue
594 - d1_diff_rate = result[0][0] 607 +
595 - close = result[0][1] 608 + d1_diff=result[0][0]
596 - open = result[0][2] 609 + d1_diff_rate = result[0][1]
597 - high = result[0][3] 610 + close = result[0][2]
598 - low = result[0][4] 611 + open = result[0][3]
599 - volume = result[0][5] 612 + high = result[0][4]
600 - clo5 = result[0][6] 613 + low = result[0][5]
601 - clo10 = result[0][7] 614 + volume = result[0][6]
602 - clo20 = result[0][8] 615 + clo5 = result[0][7]
603 - clo60 = result[0][9] 616 + clo10 = result[0][8]
604 - clo120 = result[0][10] 617 + clo20 = result[0][9]
618 + clo60 = result[0][10]
619 + clo120 = result[0][11]
605 620
606 if open: 621 if open:
607 - self.db_to_transaction_update(code_name,d1_diff_rate,close,open,high,low,volume, 622 + self.db_to_all_stocks_present_price_update(code_name,d1_diff,d1_diff_rate,close,open,high,low,volume,
608 - clo5,clo10,clo20,clo60,clo120,option) 623 + clo5,clo10,clo20,clo60,clo120,option)
609 else: 624 else:
610 continue 625 continue
611 626
612 # 보유한 종목의 이름을 반환하는 함수 627 # 보유한 종목의 이름을 반환하는 함수
613 - def get_data_from_possess_item(self): 628 + def get_data_from_possessed_item(self):
614 - query="select code_name from transaction where sell_date='0'" 629 + query="select code_name from all_stocks where sell_date='0'"
615 result=self.engine_simul.execute(query).fetchall() 630 result=self.engine_simul.execute(query).fetchall()
616 return result[0][0] 631 return result[0][0]
617 632
618 # daily_buy_list를 통해 특정 날짜에 해당하는 주가정보를 가져오는 함수 633 # daily_buy_list를 통해 특정 날짜에 해당하는 주가정보를 가져오는 함수
619 - def get_current_price_by_date(self,code_name,date): 634 + def get_now_price_by_date(self,code_name,date):
620 - query = f"select d1_diff_rate, close, open, high, low, volume, clo5, clo10, clo20, clo60, clo120 from `{date}` " \ 635 + query = f"select d1_diff,d1_diff_rate, close, open, high, low, volume, clo5, clo10, clo20, clo60, clo120 " \
636 + f"from '{date}' " \
621 f"where code_name = '{code_name}' group by code" 637 f"where code_name = '{code_name}' group by code"
622 result=self.engine_daily_buy_list.execute(query).fetchall() 638 result=self.engine_daily_buy_list.execute(query).fetchall()
623 639
...@@ -626,9 +642,9 @@ class Simulator_Api: ...@@ -626,9 +642,9 @@ class Simulator_Api:
626 else: 642 else:
627 return False 643 return False
628 644
629 - # 현재의 주가를 거래이력(transaction)에 있는 보유 종목에 반영 645 + # 현재의 주가를 거래이력(all_stocks)에 있는 보유 종목에 반영
630 - def db_to_transaction_update(self,code_name,d1_diff_rate,close,open,high,low,volume, 646 + def db_to_all_stocks_present_price_update(self,code_name,d1_diff,d1_diff_rate,close,open,high,low,volume,
631 - clo5,clo10,clo20,clo60,clo120,option='ALL'): 647 + clo5,clo10,clo20,clo60,clo120,option='ALL'):
632 # 모의투자 / 실전투자의 경우 현재가를 종가로 업데이트 648 # 모의투자 / 실전투자의 경우 현재가를 종가로 업데이트
633 if self.op=='real': 649 if self.op=='real':
634 present_price=close 650 present_price=close
...@@ -638,36 +654,36 @@ class Simulator_Api: ...@@ -638,36 +654,36 @@ class Simulator_Api:
638 654
639 # option==ALL이면 모든 데이터를 업데이트 655 # option==ALL이면 모든 데이터를 업데이트
640 if option=="ALL": 656 if option=="ALL":
641 - query = f"update transaction " \ 657 + query = f"update all_stocks " \
642 f"set " \ 658 f"set " \
643 - f"d1_diff_rate = {d1_diff_rate}, " \ 659 + f"d1_diff={d1_diff}, d1_diff_rate = {d1_diff_rate}, " \
644 f"close = {close}, open = {open}, high = {high}, low = {low}, volume = {volume}, " \ 660 f"close = {close}, open = {open}, high = {high}, low = {low}, volume = {volume}, " \
645 f"present_price = {present_price}, " \ 661 f"present_price = {present_price}, " \
646 f"clo5 = {clo5}, clo10 = {clo10}, clo20 = {clo20}, clo60 = {clo60}, clo120 = {clo120} " \ 662 f"clo5 = {clo5}, clo10 = {clo10}, clo20 = {clo20}, clo60 = {clo60}, clo120 = {clo120} " \
647 - f"where code_name = '{code_name}' and sell_date = {0}" 663 + f"where code_name = '{code_name}' and sell_date = '{0}'"
648 # option==open이면 open,present_price값만 업데이트 664 # option==open이면 open,present_price값만 업데이트
649 else: 665 else:
650 - query = f"update transaction " \ 666 + query = f"update all_stocks " \
651 f"set " \ 667 f"set " \
652 f"open = {open}, present_price = {present_price} " \ 668 f"open = {open}, present_price = {present_price} " \
653 - f"where code_name = '{code_name}' and sell_date = {0}" 669 + f"where code_name = '{code_name}' and sell_date = '{0}'"
654 670
655 self.engine_simul.execute(query) 671 self.engine_simul.execute(query)
656 672
657 - # 분 데이터를 가져오는 함수 673 + # 분 데이터를 가져오는 함수
658 - def get_min_data_for_simul(self,simul_start_date): 674 + def get_date_min_for_simul(self,simul_start_date):
659 simul_start_date_min=simul_start_date+self.start_min # 장 시작시간 = 9시 675 simul_start_date_min=simul_start_date+self.start_min # 장 시작시간 = 9시
660 simul_end_date_min=simul_start_date+"1530" # 장 마감시간 = 3시 30분 676 simul_end_date_min=simul_start_date+"1530" # 장 마감시간 = 3시 30분
661 677
662 query = f"select date from `gs글로벌` " \ 678 query = f"select date from `gs글로벌` " \
663 f"where date >= '{simul_start_date_min}' and date <='{simul_end_date_min}' and open != 0 group by date" 679 f"where date >= '{simul_start_date_min}' and date <='{simul_end_date_min}' and open != 0 group by date"
664 - self.min_data_rows = self.engine_craw.execute(query).fetchall() 680 + self.min_date_rows = self.engine_craw.execute(query).fetchall()
665 681
666 - # 거래이력(transaction)의 시세(close) 데이터를 분 별로 업데이트 682 + # 거래이력(all_stocks)의 시세(close) 데이터를 분 별로 업데이트
667 - def update_transaction_by_min(self,min): 683 + def update_all_db_by_min(self,min):
668 - possess_item=self.get_data_from_possess_item() 684 + possessed_code_name=self.get_data_from_possessed_item()
669 - for i in range(len(possess_item)): 685 + for i in range(len(possessed_code_name)):
670 - code_name=possess_item[i][0] 686 + code_name=possessed_code_name[i][0]
671 current_close_price=self.get_current_close_price_by_min(code_name,min) 687 current_close_price=self.get_current_close_price_by_min(code_name,min)
672 if current_close_price: 688 if current_close_price:
673 self.db_to_transaction_update_present_price_by_min(code_name,current_close_price) 689 self.db_to_transaction_update_present_price_by_min(code_name,current_close_price)
...@@ -686,16 +702,16 @@ class Simulator_Api: ...@@ -686,16 +702,16 @@ class Simulator_Api:
686 return False 702 return False
687 703
688 # 보유한 종목에 현재가를 실시간으로 업데이트하는 함수 704 # 보유한 종목에 현재가를 실시간으로 업데이트하는 함수
689 - def db_to_transaction_update_present_price_by_min(self,code_name,current_close_price): 705 + def db_to_all_stocks_present_price_update_by_min(self,code_name,current_close_price):
690 - query=f"update transaction set present_price={current_close_price} " \ 706 + query=f"update all_stocks set present_price={current_close_price} " \
691 f"where code_name={code_name} and sell_date='{0}'" 707 f"where code_name={code_name} and sell_date='{0}'"
692 self.engine_simul.execute(query) 708 self.engine_simul.execute(query)
693 709
694 - # 잔고 테이블의 주가 이외의 기타 정보를 업데이트 710 + # 보유중인 종목들의 주가 이외의 기타 정보를 업데이트
695 - def update_transaction_etc(self): 711 + def update_all_db_etc(self):
696 # valuation_price : 평가금액 712 # valuation_price : 평가금액
697 # 평가금액 = (보유주 현재가 * 보유주 수량) - (총 구매금액 * 수수료) - (보유주 현재가 * 보유주 수량 * (수수료 + 세금)) 713 # 평가금액 = (보유주 현재가 * 보유주 수량) - (총 구매금액 * 수수료) - (보유주 현재가 * 보유주 수량 * (수수료 + 세금))
698 - query = f"update transaction " \ 714 + query = f"update all_stocks " \
699 f"set " \ 715 f"set " \
700 f"valuation_price = " \ 716 f"valuation_price = " \
701 f"round((present_price * holding_amount) - item_total_purchase * {self.fees_rate} - " \ 717 f"round((present_price * holding_amount) - item_total_purchase * {self.fees_rate} - " \
...@@ -707,11 +723,11 @@ class Simulator_Api: ...@@ -707,11 +723,11 @@ class Simulator_Api:
707 # valuation_profit : 수익 금액 723 # valuation_profit : 수익 금액
708 # 수익 금액 = 평가금액 - 총 구매금액 724 # 수익 금액 = 평가금액 - 총 구매금액
709 # 수익률 = 수익금액 / 구매금액 * 100 725 # 수익률 = 수익금액 / 구매금액 * 100
710 - query = "update account_balance " \ 726 + query = "update all_stocks " \
711 "set " \ 727 "set " \
712 "rate= round((valuation_price - item_total_purchase)/item_total_purchase*100,2), " \ 728 "rate= round((valuation_price - item_total_purchase)/item_total_purchase*100,2), " \
713 "valuation_profit = valuation_price - item_total_purchase " \ 729 "valuation_profit = valuation_price - item_total_purchase " \
714 - "where sell_date = '0';" 730 + "where sell_date = '0'"
715 self.engine_simul.execute(query) 731 self.engine_simul.execute(query)
716 732
717 # 매도 함수 733 # 매도 함수
...@@ -742,17 +758,17 @@ class Simulator_Api: ...@@ -742,17 +758,17 @@ class Simulator_Api:
742 print("=========================================") 758 print("=========================================")
743 759
744 # 매도 결과를 데이터베이스에 반영 760 # 매도 결과를 데이터베이스에 반영
745 - self.send_sell_order(date,present_price,sell_rate,sell_code) 761 + self.sell_send_order(date,present_price,sell_rate,sell_code)
746 762
747 - # 매도한 결과를 transaction에 반영하는 함수 763 + # 매도한 결과를 all_stocks에 반영하는 함수
748 - def send_sell_order(self,min,sell_price,sell_rate,code): 764 + def sell_send_order(self,min,sell_price,sell_rate,code):
749 - query=f"update transaction " \ 765 + query=f"update all_stocks " \
750 f"set " \ 766 f"set " \
751 f"sell_date='{min}', sell_price='{sell_price}', sell_rate='{sell_rate}' " \ 767 f"sell_date='{min}', sell_price='{sell_price}', sell_rate='{sell_rate}' " \
752 f"where code='{code}' and sell_date='{0}' order by buy_date desc limit 1" 768 f"where code='{code}' and sell_date='{0}' order by buy_date desc limit 1"
753 self.engine_simul.execute(query) 769 self.engine_simul.execute(query)
754 # 매도 후 정산 770 # 매도 후 정산
755 - self.update_balance() 771 + self.check_balance()
756 772
757 # 매도함수를 이용하여 매도할 종목을 가져오는 함수 773 # 매도함수를 이용하여 매도할 종목을 가져오는 함수
758 def get_sell_list(self,i): 774 def get_sell_list(self,i):
...@@ -760,14 +776,14 @@ class Simulator_Api: ...@@ -760,14 +776,14 @@ class Simulator_Api:
760 776
761 # (5,20) 데드크로스 777 # (5,20) 데드크로스
762 # 또는 손절 기준 수익률 이하로 떨어졌을 경우 매도 778 # 또는 손절 기준 수익률 이하로 떨어졌을 경우 매도
763 - if self.sell_algorithm==1: 779 + if self.sell_list_num==1:
764 - query=f"select code,rate, present_price,valuation_price from transaction " \ 780 + query=f"select code,rate, present_price,valuation_price from all_stocks " \
765 f"where sell_date='0' and (clo5<clo20 or rate<='{self.losscut_point}') group by code" 781 f"where sell_date='0' and (clo5<clo20 or rate<='{self.losscut_point}') group by code"
766 sell_list=self.engine_simul.execute(query).fetchall() 782 sell_list=self.engine_simul.execute(query).fetchall()
767 783
768 # (20,60) 데드크로스 784 # (20,60) 데드크로스
769 - elif self.sell_algorithm==2: 785 + elif self.sell_list_num==2:
770 - query=f"select code,rate, present_price,valuation_price from transaction " \ 786 + query=f"select code,rate, present_price,valuation_price from all_stocks " \
771 f"where sell_date='0' and (clo20<clo60 or rate<='{self.losscut_point}') group by code" 787 f"where sell_date='0' and (clo20<clo60 or rate<='{self.losscut_point}') group by code"
772 sell_list=self.engine_simul.execute(query).fetchall() 788 sell_list=self.engine_simul.execute(query).fetchall()
773 789
...@@ -783,17 +799,18 @@ class Simulator_Api: ...@@ -783,17 +799,18 @@ class Simulator_Api:
783 799
784 # 남은 금액을 확인하는 함수 800 # 남은 금액을 확인하는 함수
785 # 남은 금액이 최소 보유금 + 투자단위금액 이상이면 True, 아니면 False 반환 801 # 남은 금액이 최소 보유금 + 투자단위금액 이상이면 True, 아니면 False 반환
786 - def check_balance(self): 802 + def jango_check(self):
787 if int(self.d2_deposit)>=int(self.limit_money)+int(self.invest_unit): 803 if int(self.d2_deposit)>=int(self.limit_money)+int(self.invest_unit):
788 return True 804 return True
789 else: 805 else:
790 return False 806 return False
791 807
792 # 매수 함수 808 # 매수 함수
793 - def auto_trade_buy_stock(self,min,date_rows_today,date_rows_yesterday): 809 + def auto_trade_stock_realtime(self,min,date_rows_today,date_rows_yesterday):
794 # self.df_realtime_daily_buy_list에 있는 모든 종목을 매수 810 # self.df_realtime_daily_buy_list에 있는 모든 종목을 매수
795 for i in range(self.len_df_realtime_daily_buy_list): 811 for i in range(self.len_df_realtime_daily_buy_list):
796 - if self.check_balance(): 812 + # 매수할 잔액이 남아있다면
813 + if self.jango_check():
797 code=self.df_realtime_daily_buy_list.loc[i,'code'].rjust(6,"0") 814 code=self.df_realtime_daily_buy_list.loc[i,'code'].rjust(6,"0")
798 code_name=self.df_realtime_daily_buy_list.loc[i,'code_name'] 815 code_name=self.df_realtime_daily_buy_list.loc[i,'code_name']
799 816
...@@ -810,9 +827,10 @@ class Simulator_Api: ...@@ -810,9 +827,10 @@ class Simulator_Api:
810 827
811 # 일별 시뮬레이팅인 경우 828 # 일별 시뮬레이팅인 경우
812 if not self.use_min: 829 if not self.use_min:
813 - price=self.get_current_open_price_by_date(code,date_rows_today) 830 + price=self.get_now_open_price_by_date(code,date_rows_today)
831 + # 분별 시뮬레이팅인 경우
814 else: 832 else:
815 - price=self.get_current_close_price_by_min(code_name,min) 833 + price=self.get_now_close_price_by_min(code_name,min)
816 834
817 # 전날 종가를 저장 835 # 전날 종가를 저장
818 yes_close=self.get_yes_close_price_by_date(code,date_rows_yesterday) 836 yes_close=self.get_yes_close_price_by_date(code,date_rows_yesterday)
...@@ -822,16 +840,17 @@ class Simulator_Api: ...@@ -822,16 +840,17 @@ class Simulator_Api:
822 continue 840 continue
823 841
824 # 분별 시뮬레이팅인 경우 842 # 분별 시뮬레이팅인 경우
825 - if self.use_min and not self.use_nine and self.trade_check_num: 843 + if self.use_min and not self.only_nine_buy and self.trade_check_num:
826 - open=self.get_current_open_price_by_date(code,date_rows_today) # 시가 844 + open=self.get_now_open_price_by_date(code,date_rows_today) # 시가
827 - sum_volume=self.get_current_volume_by_min(code_name,min) # 당일 누적 거래량 845 + sum_volume=self.get_now_volume_by_min(code_name,min) # 당일 누적 거래량
828 846
829 if open and sum_volume: 847 if open and sum_volume:
830 # 실시간 매수조건에 부합하지 않는 경우 매수하지 않음 848 # 실시간 매수조건에 부합하지 않는 경우 매수하지 않음
831 - if not self.check_trade(self.df_realtime_daily_buy_list.loc[i],open,price,sum_volume): 849 + if not self.trade_check(self.df_realtime_daily_buy_list.loc[i],open,price,sum_volume):
832 continue 850 continue
833 851
834 - self.send_buy_order(min,code,code_name,price,yes_close,i) 852 + # 매수주문
853 + self.invest_send_order(min,code,code_name,price,yes_close,i)
835 else: 854 else:
836 break 855 break
837 856
...@@ -854,8 +873,8 @@ class Simulator_Api: ...@@ -854,8 +873,8 @@ class Simulator_Api:
854 return False 873 return False
855 874
856 # 특정 날짜의 테이블에서 특정 종목의 시가를 가져오는 함수 875 # 특정 날짜의 테이블에서 특정 종목의 시가를 가져오는 함수
857 - def get_current_open_price_by_date(self,code,date): 876 + def get_now_open_price_by_date(self,code,date):
858 - query=f"select open from `{date}` where code = '{code}' group by code" 877 + query=f"select open from '{date}' where code = '{code}' group by code"
859 open=self.engine_daily_buy_list.execute(query).fetchall() 878 open=self.engine_daily_buy_list.execute(query).fetchall()
860 if len(open)==1: 879 if len(open)==1:
861 return open[0][0] 880 return open[0][0]
...@@ -864,7 +883,7 @@ class Simulator_Api: ...@@ -864,7 +883,7 @@ class Simulator_Api:
864 883
865 # 전날 종가(close)를 가져오는 함수 884 # 전날 종가(close)를 가져오는 함수
866 def get_yes_close_price_by_date(self,code,date): 885 def get_yes_close_price_by_date(self,code,date):
867 - query = f"select close from `{date}` where code = '{code}' group by code" 886 + query = f"select close from '{date}' where code = '{code}' group by code"
868 result = self.engine_daily_buy_list.execute(query).fetchall() 887 result = self.engine_daily_buy_list.execute(query).fetchall()
869 if len(result) == 1: 888 if len(result) == 1:
870 return result[0][0] 889 return result[0][0]
...@@ -872,8 +891,8 @@ class Simulator_Api: ...@@ -872,8 +891,8 @@ class Simulator_Api:
872 return False 891 return False
873 892
874 # 분별 현재 누적 거래량을 가져오는 함수 893 # 분별 현재 누적 거래량을 가져오는 함수
875 - def get_current_volume_by_min(self,code_name,min): 894 + def get_now_volume_by_min(self,code_name,min):
876 - query= f"select sum_volume from `{code_name}` " \ 895 + query= f"select sum_volume from '{code_name}' " \
877 f"where date = '{min}' and open != 0 and volume !=0 order by sum_volume desc limit 1" 896 f"where date = '{min}' and open != 0 and volume !=0 order by sum_volume desc limit 1"
878 result = self.engine_craw.execute(query).fetchall() 897 result = self.engine_craw.execute(query).fetchall()
879 if len(result) == 1: 898 if len(result) == 1:
...@@ -887,7 +906,7 @@ class Simulator_Api: ...@@ -887,7 +906,7 @@ class Simulator_Api:
887 # current_price - 현재가 906 # current_price - 현재가
888 # current_sum_volume - 현재 누적 거래량 907 # current_sum_volume - 현재 누적 거래량
889 # return : True인 경우 매수, False인 경우 매수하지 않음 908 # return : True인 경우 매수, False인 경우 매수하지 않음
890 - def check_trade(self,df_row,open_price,current_price,current_sum_volume): 909 + def trade_check(self,df_row,open_price,current_price,current_sum_volume):
891 code_name = df_row['code_name'] 910 code_name = df_row['code_name']
892 yes_vol20 = df_row['vol20'] 911 yes_vol20 = df_row['vol20']
893 yes_close = df_row['close'] 912 yes_close = df_row['close']
...@@ -896,6 +915,7 @@ class Simulator_Api: ...@@ -896,6 +915,7 @@ class Simulator_Api:
896 yes_volume = df_row['volume'] 915 yes_volume = df_row['volume']
897 916
898 # 실시간 거래 대금 체크 알고리즘 917 # 실시간 거래 대금 체크 알고리즘
918 +
899 # 어제 종가 보다 현재가가 증가했고, 거래 대금이 어제 거래대금에 비해서 x배 올라갔을 때 매수 919 # 어제 종가 보다 현재가가 증가했고, 거래 대금이 어제 거래대금에 비해서 x배 올라갔을 때 매수
900 if self.trade_check_num == 1: 920 if self.trade_check_num == 1:
901 yes_total_tr_price = yes_close * yes_volume # 전날 거래 대금 921 yes_total_tr_price = yes_close * yes_volume # 전날 거래 대금
...@@ -930,180 +950,173 @@ class Simulator_Api: ...@@ -930,180 +950,173 @@ class Simulator_Api:
930 logger.error("Invalid trade_check_num") 950 logger.error("Invalid trade_check_num")
931 951
932 # 데이터베이스에 매수 내역 업데이트 952 # 데이터베이스에 매수 내역 업데이트
933 - def send_buy_order(self,date,code,code_name,price,yes_close,j): 953 + def invest_send_order(self,date,code,code_name,price,yes_close,j):
934 # 가격이 invest_unit보다 작은 경우 매수 954 # 가격이 invest_unit보다 작은 경우 매수
935 if price < self.invest_unit: 955 if price < self.invest_unit:
936 - # 매수하는 경우 account_balance에 해당 내역을 추가 956 + # 매수하는 경우 all_stocks에 해당 내역을 추가
937 - self.db_to_transaction(date,self.df_realtime_daily_buy_list,j,code,code_name,price,yes_close) 957 + self.db_to_all_stocks(date,self.df_realtime_daily_buy_list,j,code,code_name,price,yes_close)
938 958
939 # 매수를 성공적으로 했으면 realtime_daily_buy_list 테이블의 check_item 에 매수 시간을 설정 959 # 매수를 성공적으로 했으면 realtime_daily_buy_list 테이블의 check_item 에 매수 시간을 설정
940 self.update_realtime_daily_buy_list(code, date) 960 self.update_realtime_daily_buy_list(code, date)
941 961
942 # 정산 962 # 정산
943 - self.update_balance() 963 + self.check_balance()
944 964
945 - # transaction 테이블에 추가하는 함수 965 + # all_stocks 테이블에 추가하는 함수
946 - def db_to_transaction(self,min,df,index,code,code_name,purchase_price,yesterday_close): 966 + def db_to_all_stocks(self,min,df,index,code,code_name,purchase_price,yesterday_close):
947 - self.df_transaction.loc[0,'code']=code 967 + self.df_all_stocks.loc[0,'code']=code
948 - self.df_transaction.loc[0,'code_name']=code_name 968 + self.df_all_stocks.loc[0,'code_name']=code_name
949 - self.df_transaction.loc[0,'rate']=float(-0.33) 969 + self.df_all_stocks.loc[0,'rate']=float(-0.33)
950 970
951 if yesterday_close: 971 if yesterday_close:
952 - self.df_transaction.loc[0, 'purchase_rate'] = round( 972 + self.df_all_stocks.loc[0, 'purchase_rate'] = round(
953 (float(purchase_price) - float(yesterday_close)) / float(yesterday_close) * 100, 2) 973 (float(purchase_price) - float(yesterday_close)) / float(yesterday_close) * 100, 2)
954 974
955 - self.df_transaction.loc[0, 'purchase_price'] = purchase_price 975 + self.df_all_stocks.loc[0, 'purchase_price'] = purchase_price
956 - self.df_transaction.loc[0, 'present_price'] = purchase_price 976 + self.df_all_stocks.loc[0, 'present_price'] = purchase_price
977 +
978 + self.df_all_stocks.loc[0, 'holding_amount'] = int(self.invest_unit / purchase_price)
979 + self.df_all_stocks.loc[0, 'buy_date'] = min
980 + self.df_all_stocks.loc[0, 'item_total_purchase'] = self.df_all_stocks.loc[0, 'purchase_price'] * \
981 + self.df_all_stocks.loc[0, 'holding_amount']
957 982
958 - self.df_transaction.loc[0, 'holding_amount'] = int(self.invest_unit / purchase_price) 983 + self.today_invest_price = self.today_invest_price + self.df_all_stocks.loc[0, 'item_total_purchase']
959 - self.df_transaction.loc[0, 'buy_date'] = min
960 - self.df_transaction.loc[0, 'item_total_purchase'] = self.df_transaction.loc[0, 'purchase_price'] * \
961 - self.df_transaction.loc[0, 'holding_amount']
962 984
963 - self.today_invest_price = self.today_invest_price + self.df_transaction.loc[0, 'item_total_purchase'] 985 + self.df_all_stocks.loc[0, 'chegyul_check'] = 0
986 + self.df_all_stocks.loc[0, 'id'] = 0
987 + self.df_all_stocks.loc[0, 'invest_unit'] = self.invest_unit
964 988
965 - self.df_transaction.loc[0, 'chegyul_check'] = 0 989 + self.df_all_stocks.loc[0, 'yes_close'] = yesterday_close
966 - self.df_transaction.loc[0, 'id'] = 0 990 + self.df_all_stocks.loc[0, 'close'] = df.loc[index, 'close']
967 - self.df_transaction.loc[0, 'invest_unit'] = self.invest_unit
968 991
969 - self.df_transaction.loc[0, 'yes_close'] = yesterday_close 992 + self.df_all_stocks.loc[0, 'open'] = df.loc[index, 'open']
970 - self.df_transaction.loc[0, 'close'] = df.loc[index, 'close'] 993 + self.df_all_stocks.loc[0, 'high'] = df.loc[index, 'high']
994 + self.df_all_stocks.loc[0, 'low'] = df.loc[index, 'low']
995 + self.df_all_stocks.loc[0, 'volume'] = df.loc[index, 'volume']
971 996
972 - self.df_transaction.loc[0, 'open'] = df.loc[index, 'open'] 997 + self.df_all_stocks.loc[0,'d1_diff']=int(df.loc[index,'d1_diff'])
973 - self.df_transaction.loc[0, 'high'] = df.loc[index, 'high'] 998 + self.df_all_stocks.loc[0, 'd1_diff_rate'] = float(df.loc[index, 'd1_diff_rate'])
974 - self.df_transaction.loc[0, 'low'] = df.loc[index, 'low']
975 - self.df_transaction.loc[0, 'volume'] = df.loc[index, 'volume']
976 999
977 - self.df_transaction.loc[0, 'd1_diff_rate'] = float(df.loc[index, 'd1_diff_rate']) 1000 + self.df_all_stocks.loc[0, 'clo5'] = df.loc[index, 'clo5']
978 - self.df_transaction.loc[0, 'clo5'] = df.loc[index, 'clo5'] 1001 + self.df_all_stocks.loc[0, 'clo10'] = df.loc[index, 'clo10']
979 - self.df_transaction.loc[0, 'clo10'] = df.loc[index, 'clo10'] 1002 + self.df_all_stocks.loc[0, 'clo20'] = df.loc[index, 'clo20']
980 - self.df_transaction.loc[0, 'clo20'] = df.loc[index, 'clo20'] 1003 + self.df_all_stocks.loc[0, 'clo60'] = df.loc[index, 'clo40']
981 - self.df_transaction.loc[0, 'clo60'] = df.loc[index, 'clo40'] 1004 + self.df_all_stocks.loc[0, 'clo120'] = df.loc[index, 'clo60']
982 - self.df_transaction.loc[0, 'clo120'] = df.loc[index, 'clo60']
983 1005
984 if df.loc[index, 'clo5_diff_rate'] is not None: 1006 if df.loc[index, 'clo5_diff_rate'] is not None:
985 - self.df_transaction.loc[0, 'clo5_diff_rate'] = float(df.loc[index, 'clo5_diff_rate']) 1007 + self.df_all_stocks.loc[0, 'clo5_diff_rate'] = float(df.loc[index, 'clo5_diff_rate'])
986 if df.loc[index, 'clo10_diff_rate'] is not None: 1008 if df.loc[index, 'clo10_diff_rate'] is not None:
987 - self.df_transaction.loc[0, 'clo10_diff_rate'] = float(df.loc[index, 'clo10_diff_rate']) 1009 + self.df_all_stocks.loc[0, 'clo10_diff_rate'] = float(df.loc[index, 'clo10_diff_rate'])
988 if df.loc[index, 'clo20_diff_rate'] is not None: 1010 if df.loc[index, 'clo20_diff_rate'] is not None:
989 - self.df_transaction.loc[0, 'clo20_diff_rate'] = float(df.loc[index, 'clo20_diff_rate']) 1011 + self.df_all_stocks.loc[0, 'clo20_diff_rate'] = float(df.loc[index, 'clo20_diff_rate'])
990 if df.loc[index, 'clo60_diff_rate'] is not None: 1012 if df.loc[index, 'clo60_diff_rate'] is not None:
991 - self.df_transaction.loc[0, 'clo40_diff_rate'] = float(df.loc[index, 'clo40_diff_rate']) 1013 + self.df_all_stocks.loc[0, 'clo40_diff_rate'] = float(df.loc[index, 'clo60_diff_rate'])
992 if df.loc[index, 'clo120_diff_rate'] is not None: 1014 if df.loc[index, 'clo120_diff_rate'] is not None:
993 - self.df_transaction.loc[0, 'clo60_diff_rate'] = float(df.loc[index, 'clo60_diff_rate']) 1015 + self.df_all_stocks.loc[0, 'clo60_diff_rate'] = float(df.loc[index, 'clo120_diff_rate'])
994 1016
995 - self.df_transaction.loc[0, 'valuation_profit'] = int(0) 1017 + self.df_all_stocks.loc[0, 'valuation_profit'] = int(0)
996 1018
997 - self.df_transaction=self.df_transaction.fillna(0) 1019 + self.df_all_stocks=self.df_all_stocks.fillna(0)
998 1020
999 # 거래이력 테이블이 이미 존재한다면 데이터 추가 1021 # 거래이력 테이블이 이미 존재한다면 데이터 추가
1000 - if self.is_simul_table_exist(self.db_name, "transaction"): 1022 + if self.is_simul_table_exist(self.db_name, "all_stocks"):
1001 - self.df_transaction.to_sql('transaction', self.engine_simul, if_exists='append') 1023 + self.df_all_stocks.to_sql('all_stocks', self.engine_simul, if_exists='append')
1002 # 테이블이 존재하지 않는다면 생성 1024 # 테이블이 존재하지 않는다면 생성
1003 else: 1025 else:
1004 - self.df_transaction.to_sql('transaction', self.engine_simul, if_exists='replace') 1026 + self.df_all_stocks.to_sql('all_stocks', self.engine_simul, if_exists='replace')
1005 1027
1006 # 매수할 리스트(realtime_daily_buy_list)에서 특정 종목을 매수한 경우 check_item칼럼에 매수한 날짜를 저장하는 함수 1028 # 매수할 리스트(realtime_daily_buy_list)에서 특정 종목을 매수한 경우 check_item칼럼에 매수한 날짜를 저장하는 함수
1007 def update_realtime_daily_buy_list(self,code,min): 1029 def update_realtime_daily_buy_list(self,code,min):
1008 query = f"update realtime_daily_buy_list set check_item = '{min}' where code = '{code}'" 1030 query = f"update realtime_daily_buy_list set check_item = '{min}' where code = '{code}'"
1009 self.engine_simul.execute(query) 1031 self.engine_simul.execute(query)
1010 1032
1011 - # account_balance(잔고) 테이블을 생성 및 데이터를 추가하는 함수 1033 + # jango 테이블을 생성 및 데이터를 추가하는 함수
1012 - def db_to_account_balance(self,date_rows_today): 1034 + def db_to_jango(self,date_rows_today):
1013 - self.update_balance() 1035 + self.check_balance()
1014 # 거래이력(transaction)테이블이 존재하지 않는다면 return 1036 # 거래이력(transaction)테이블이 존재하지 않는다면 return
1015 - if not self.is_simul_table_exist(self.db_name,"transaction"): 1037 + if not self.is_simul_table_exist(self.db_name,"all_stocks"):
1016 return 1038 return
1017 1039
1018 - columns = ['date', 'today_earning_rate', 'sum_valuation_profit', 'total_profit', 1040 + self.jango.loc[0,'date']=date_rows_today # 구매일
1019 - 'today_profit', 'today_profitcut_count', 'today_losscut_count', 1041 + self.jango.loc[0, 'sum_valuation_profit'] = self.sum_valuation_profit # 총평가금액
1020 - 'today_profitcut', 'today_losscut', 'd2_deposit', 'total_possess_count', 1042 + self.jango.loc[0, 'total_profit'] = self.total_valuation_profit # 총수익
1021 - 'today_buy_count','total_invest', 1043 + self.jango.loc[0, 'today_profit'] = self.get_today_profit(date_rows_today) # 당일수익
1022 - 'sum_item_total_purchase', 'total_evaluation', 'today_rate', 1044 +
1023 - 'today_invest_price', 'today_sell_price', 'volume_limit', 'sell_point', 1045 + self.jango.loc[0, 'today_profitcut_count'] = self.get_today_profitcut_count(date_rows_today) # 당일 익절종목 수
1024 - 'invest_unit', 'limit_money', 'total_profitcut', 1046 + self.jango.loc[0, 'today_losscut_count'] = self.get_today_losscut_count(date_rows_today) # 당일 손절종목 수
1025 - 'total_losscut', 'total_profitcut_count', 'total_losscut_count'] 1047 + self.jango.loc[0, 'today_profitcut'] = self.get_sum_today_profitcut(date_rows_today) # 당일 익절금액
1026 - 1048 + self.jango.loc[0, 'today_losscut'] = self.get_sum_today_losscut(date_rows_today) # 당일 손절금액
1027 - self.account_balance.loc[0,'date']=date_rows_today # 구매일 1049 +
1028 - self.account_balance.loc[0, 'sum_valuation_profit'] = self.sum_valuation_profit # 총평가금액 1050 + self.jango.loc[0, 'd2_deposit'] = self.d2_deposit # 예수금
1029 - self.account_balance.loc[0, 'total_profit'] = self.total_valuation_profit # 총수익 1051 + self.jango.loc[0, 'total_possess_count'] = self.get_total_possess_count() # 보유종목 수
1030 - self.account_balance.loc[0, 'today_profit'] = self.get_today_profit(date_rows_today) # 당일수익 1052 + self.jango.loc[0, 'today_buy_count'] = 0 # 오늘 구매한 종목수
1031 - 1053 + self.jango.loc[0, 'total_invest'] = self.total_invest_price # 총 투자금액
1032 - self.account_balance.loc[0, 'today_profitcut_count'] = self.get_today_profitcut_count(date_rows_today) # 당일 익절종목 수 1054 +
1033 - self.account_balance.loc[0, 'today_losscut_count'] = self.get_today_losscut_count(date_rows_today) # 당일 손절종목 수 1055 + self.jango.loc[0, 'sum_item_total_purchase'] = self.get_sum_item_total_purchase() # 총매입금액
1034 - self.account_balance.loc[0, 'today_profitcut'] = self.get_sum_today_profitcut(date_rows_today) # 당일 익절금액 1056 + self.jango.loc[0, 'total_evaluation'] = self.get_sum_valuation_price() # 총평가금액
1035 - self.account_balance.loc[0, 'today_losscut'] = self.get_sum_today_losscut(date_rows_today) # 당일 손절금액
1036 -
1037 - self.account_balance.loc[0, 'd2_deposit'] = self.d2_deposit # 예수금
1038 - self.account_balance.loc[0, 'total_possess_count'] = self.get_total_possess_count() # 보유종목 수
1039 - self.account_balance.loc[0, 'today_buy_count'] = 0 # 오늘 구매한 종목수
1040 - self.account_balance.loc[0, 'total_invest'] = self.total_invest_price # 총 투자금액
1041 -
1042 - self.account_balance.loc[0, 'sum_item_total_purchase'] = self.get_sum_item_total_purchase() # 총매입금액
1043 - self.account_balance.loc[0, 'total_evaluation'] = self.get_sum_valuation_price() # 총평가금액
1044 try: 1057 try:
1045 - self.account_balance.loc[0, 'today_rate'] = round( 1058 + self.jango.loc[0, 'today_rate'] = round(
1046 - (float(self.account_balance.loc[0, 'total_evaluation']) - 1059 + (float(self.jango.loc[0, 'total_evaluation']) -
1047 - float(self.account_balance.loc[0, 'sum_item_total_purchase'])) / 1060 + float(self.jango.loc[0, 'sum_item_total_purchase'])) /
1048 - float(self.account_balance.loc[0, 'sum_item_total_purchase']) * (100 - 0.33), 2) # 당일 기준 수익률 1061 + float(self.jango.loc[0, 'sum_item_total_purchase']) * (100 - 0.33), 2) # 당일 기준 수익률
1049 except ZeroDivisionError: 1062 except ZeroDivisionError:
1050 pass 1063 pass
1051 1064
1052 - self.account_balance.loc[0, 'today_invest_price'] = float(self.today_invest_price) # 당일 투자금액 1065 + self.jango.loc[0, 'today_invest_price'] = float(self.today_invest_price) # 당일 투자금액
1053 - self.account_balance.loc[0, 'today_sell_price'] = self.get_sum_today_sell_price(date_rows_today) 1066 + self.jango.loc[0, 'today_sell_price'] = self.get_sum_today_sell_price(date_rows_today)
1054 - self.account_balance.loc[0, 'volume_limit'] = self.volume_limit 1067 + self.jango.loc[0, 'volume_limit'] = self.volume_limit
1055 - self.account_balance.loc[0, 'sell_point'] = self.sell_point 1068 + self.jango.loc[0, 'sell_point'] = self.sell_point
1056 - self.account_balance.loc[0, 'invest_unit'] = self.invest_unit 1069 + self.jango.loc[0, 'invest_unit'] = self.invest_unit
1057 1070
1058 - self.account_balance.loc[0, 'limit_money'] = self.limit_money 1071 + self.jango.loc[0, 'limit_money'] = self.limit_money
1059 - self.account_balance.loc[0, 'total_profitcut'] = self.get_sum_total_profitcut() 1072 + self.jango.loc[0, 'total_profitcut'] = self.get_sum_total_profitcut()
1060 - self.account_balance.loc[0, 'total_losscut'] = self.get_sum_total_losscut() 1073 + self.jango.loc[0, 'total_losscut'] = self.get_sum_total_losscut()
1061 - self.account_balance.loc[0, 'total_profitcut_count'] = self.get_sum_total_profitcut_count() 1074 + self.jango.loc[0, 'total_profitcut_count'] = self.get_sum_total_profitcut_count()
1062 - self.account_balance.loc[0, 'total_losscut_count'] = self.get_sum_total_losscut_count() 1075 + self.jango.loc[0, 'total_losscut_count'] = self.get_sum_total_losscut_count()
1063 1076
1064 # 데이터베이스에 테이블 추가 1077 # 데이터베이스에 테이블 추가
1065 - self.account_balance.to_sql('account_balance', self.engine_simul, if_exists='append') 1078 + self.jango.to_sql('jango_data', self.engine_simul, if_exists='append')
1066 1079
1067 # 매도종목에 대한 당일 수익 1080 # 매도종목에 대한 당일 수익
1068 - query = f"update account_balance " \ 1081 + query = f"update jango_data " \
1069 f"set " \ 1082 f"set " \
1070 f"today_earning_rate =round(today_profit / total_invest * 100, 2) WHERE date='{date_rows_today}'" 1083 f"today_earning_rate =round(today_profit / total_invest * 100, 2) WHERE date='{date_rows_today}'"
1071 self.engine_simul.execute(query) 1084 self.engine_simul.execute(query)
1072 1085
1073 # 당일 수익을 계산하는 함수 1086 # 당일 수익을 계산하는 함수
1074 def get_today_profit(self,date): 1087 def get_today_profit(self,date):
1075 - query="SELECT sum(valuation_profit) from transaction where sell_date like '%s'" 1088 + query="SELECT sum(valuation_profit) from all_stocks where sell_date like '%s'"
1076 result=self.engine_simul.execute(query%("%%"+date+"%%")).fetchall() 1089 result=self.engine_simul.execute(query%("%%"+date+"%%")).fetchall()
1077 return result[0][0] 1090 return result[0][0]
1078 1091
1079 # 당일 익절 종목 수를 반환하는 함수 1092 # 당일 익절 종목 수를 반환하는 함수
1080 def get_today_profitcut_count(self,date): 1093 def get_today_profitcut_count(self,date):
1081 - query = "SELECT count(code) from transaction where sell_date like '%s' and sell_rate>='%s'" 1094 + query = "SELECT count(code) from all_stocks where sell_date like '%s' and sell_rate>='%s'"
1082 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0] 1095 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0]
1083 1096
1084 # 당일 손절 종목 수를 반환하는 함수 1097 # 당일 손절 종목 수를 반환하는 함수
1085 def get_today_losscut_count(self, date): 1098 def get_today_losscut_count(self, date):
1086 - query = "SELECT count(code) from transaction where sell_date like '%s' and sell_rate<'%s'" 1099 + query = "SELECT count(code) from all_stocks where sell_date like '%s' and sell_rate<'%s'"
1087 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0] 1100 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0]
1088 1101
1089 # 당일 익절 금액을 반환하는 함수 1102 # 당일 익절 금액을 반환하는 함수
1090 def get_sum_today_profitcut(self, date): 1103 def get_sum_today_profitcut(self, date):
1091 - query = "SELECT sum(valuation_profit) from transaction where sell_date like '%s' and valuation_profit >= '%s' " 1104 + query = "SELECT sum(valuation_profit) from all_stocks where sell_date like '%s' and valuation_profit >= '%s' "
1092 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0] 1105 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0]
1093 1106
1094 # 당일 손절 금액을 반환하는 함수 1107 # 당일 손절 금액을 반환하는 함수
1095 def get_sum_today_losscut(self, date): 1108 def get_sum_today_losscut(self, date):
1096 - query = "SELECT sum(valuation_profit) from transaction where sell_date like '%s' and valuation_profit < '%s' " 1109 + query = "SELECT sum(valuation_profit) from all_stocks where sell_date like '%s' and valuation_profit < '%s' "
1097 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0] 1110 return self.engine_simul.execute(query % ("%%" + date + "%%", 0)).fetchall()[0][0]
1098 1111
1099 # 총 보유한 종목 수를 반환하는 함수 1112 # 총 보유한 종목 수를 반환하는 함수
1100 def get_total_possess_count(self): 1113 def get_total_possess_count(self):
1101 - query = "select count(code) from transaction where sell_date = '%s'" 1114 + query = "select count(code) from all_stocks where sell_date = '%s'"
1102 return self.engine_simul.execute(query % (0)).fetchall()[0][0] 1115 return self.engine_simul.execute(query % (0)).fetchall()[0][0]
1103 1116
1104 # 총 매입금액을 계산하는 함수 1117 # 총 매입금액을 계산하는 함수
1105 def get_sum_item_total_purchase(self): 1118 def get_sum_item_total_purchase(self):
1106 - query = "SELECT sum(item_total_purchase) from transaction where sell_date = '%s'" 1119 + query = "SELECT sum(item_total_purchase) from all_stocks where sell_date = '%s'"
1107 result = self.engine_simul.execute(query % (0)).fetchall()[0][0] 1120 result = self.engine_simul.execute(query % (0)).fetchall()[0][0]
1108 if result is not None: 1121 if result is not None:
1109 return result 1122 return result
...@@ -1112,7 +1125,7 @@ class Simulator_Api: ...@@ -1112,7 +1125,7 @@ class Simulator_Api:
1112 1125
1113 # 총평가금액을 계산하는 함수 1126 # 총평가금액을 계산하는 함수
1114 def get_sum_valuation_price(self): 1127 def get_sum_valuation_price(self):
1115 - query = "SELECT sum(valuation_price) from transaction where sell_date = '%s'" 1128 + query = "SELECT sum(valuation_price) from all_stocks where sell_date = '%s'"
1116 result = self.engine_simul.execute(query % (0)).fetchall()[0][0] 1129 result = self.engine_simul.execute(query % (0)).fetchall()[0][0]
1117 if result is not None: 1130 if result is not None:
1118 return result 1131 return result
...@@ -1121,38 +1134,33 @@ class Simulator_Api: ...@@ -1121,38 +1134,33 @@ class Simulator_Api:
1121 1134
1122 # 당일 매도금액을 계산하는 함수 1135 # 당일 매도금액을 계산하는 함수
1123 def get_sum_today_sell_price(self, date): 1136 def get_sum_today_sell_price(self, date):
1124 - query = "SELECT sum(valuation_price) from transaction where sell_date like '%s'" 1137 + query = "SELECT sum(valuation_price) from all_stocks where sell_date like '%s'"
1125 return self.engine_simul.execute(query % ("%%" + date + "%%")).fetchall()[0][0] 1138 return self.engine_simul.execute(query % ("%%" + date + "%%")).fetchall()[0][0]
1126 1139
1127 # 총 익절금액을 계산하는 함수 1140 # 총 익절금액을 계산하는 함수
1128 def get_sum_total_profitcut(self): 1141 def get_sum_total_profitcut(self):
1129 - query = "SELECT sum(valuation_profit) from transaction where sell_date != 0 and valuation_profit >= '%s' " 1142 + query = "SELECT sum(valuation_profit) from all_stocks where sell_date != 0 and valuation_profit >= '%s' "
1130 return self.engine_simul.execute(query % (0)).fetchall()[0][0] 1143 return self.engine_simul.execute(query % (0)).fetchall()[0][0]
1131 1144
1132 # 총 손절금액을 계산하는 함수 1145 # 총 손절금액을 계산하는 함수
1133 def get_sum_total_losscut(self): 1146 def get_sum_total_losscut(self):
1134 - query = "SELECT sum(valuation_profit) from transaction where sell_date != 0 and valuation_profit < '%s' " 1147 + query = "SELECT sum(valuation_profit) from all_stocks where sell_date != 0 and valuation_profit < '%s' "
1135 return self.engine_simul.execute(query % (0)).fetchall()[0][0] 1148 return self.engine_simul.execute(query % (0)).fetchall()[0][0]
1136 1149
1137 # 총 익절종목수를 반환하는 함수 1150 # 총 익절종목수를 반환하는 함수
1138 def get_sum_total_profitcut_count(self): 1151 def get_sum_total_profitcut_count(self):
1139 - query = "select count(code) from transaction where sell_date != 0 and valuation_profit >= '%s'" 1152 + query = "select count(code) from all_stocks where sell_date != 0 and valuation_profit >= '%s'"
1140 return self.engine_simul.execute(query % (0)).fetchall()[0][0] 1153 return self.engine_simul.execute(query % (0)).fetchall()[0][0]
1141 1154
1142 # 총 손절종목수를 반환하는 함수 1155 # 총 손절종목수를 반환하는 함수
1143 def get_sum_total_losscut_count(self): 1156 def get_sum_total_losscut_count(self):
1144 - query = "select count(code) from transaction where sell_date != 0 and valuation_profit < '%s' " 1157 + query = "select count(code) from all_stocks where sell_date != 0 and valuation_profit < '%s' "
1145 return self.engine_simul.execute(query % (0)).fetchall()[0][0] 1158 return self.engine_simul.execute(query % (0)).fetchall()[0][0]
1146 1159
1147 - # 보유종목의 종목명을 반환하는 함수
1148 - def get_data_from_possessed_item(self):
1149 - query="SELECT code_name from transaction where sell_date = '%s'"
1150 - return self.engine_simul.execute(query % (0)).fetchall()
1151 -
1152 # 날짜별 시뮬레이팅 함수 1160 # 날짜별 시뮬레이팅 함수
1153 def simul_by_date(self,date_rows_today,date_rows_yesterday,i): 1161 def simul_by_date(self,date_rows_today,date_rows_yesterday,i):
1154 # 시뮬레이팅 전 변수 초기화 1162 # 시뮬레이팅 전 변수 초기화
1155 - self.set_daily_variable() 1163 + self.daily_variable_setting()
1156 1164
1157 # daily_buy_list에 시뮬레이팅 할 날짜에 해당하는 테이블과 전 날 테이블이 존재하는지 확인 1165 # daily_buy_list에 시뮬레이팅 할 날짜에 해당하는 테이블과 전 날 테이블이 존재하는지 확인
1158 if self.is_date_exist(date_rows_today) and self.is_date_exist(date_rows_yesterday): 1166 if self.is_date_exist(date_rows_today) and self.is_date_exist(date_rows_yesterday):
...@@ -1161,12 +1169,12 @@ class Simulator_Api: ...@@ -1161,12 +1169,12 @@ class Simulator_Api:
1161 # 매수/매도 1169 # 매수/매도
1162 self.trading_by_date(date_rows_today, date_rows_yesterday, i) 1170 self.trading_by_date(date_rows_today, date_rows_yesterday, i)
1163 1171
1164 - if self.is_simul_table_exist(self.db_name, "transaction") and len(self.get_data_from_possessed_item()) != 0: 1172 + if self.is_simul_table_exist(self.db_name, "all_stocks") and len(self.get_data_from_possessed_item()) != 0:
1165 # 보유 중인 종목들의 주가를 일별로 업데이트 1173 # 보유 중인 종목들의 주가를 일별로 업데이트
1166 - self.update_transaction_by_date(date_rows_today,option="ALL") 1174 + self.update_all_db_by_date(date_rows_today,option="ALL")
1167 1175
1168 # 정산 1176 # 정산
1169 - self.db_to_account_balance(date_rows_today) 1177 + self.db_to_jango(date_rows_today)
1170 1178
1171 else: 1179 else:
1172 print("날짜 테이블이 존재하지 않습니다.") 1180 print("날짜 테이블이 존재하지 않습니다.")
...@@ -1176,21 +1184,21 @@ class Simulator_Api: ...@@ -1176,21 +1184,21 @@ class Simulator_Api:
1176 self.show_info(date_rows_today) 1184 self.show_info(date_rows_today)
1177 1185
1178 # 보유주 정보 업데이트 1186 # 보유주 정보 업데이트
1179 - if self.is_simul_table_exist(self.db_name, "transaction") and len(self.get_data_from_possessed_item()) != 0: 1187 + if self.is_simul_table_exist(self.db_name, "all_stocks") and len(self.get_data_from_possessed_item()) != 0:
1180 - self.update_transaction_by_date(date_rows_today,option="OPEN") 1188 + self.update_all_db_by_date(date_rows_today,option="OPEN")
1181 - self.update_transaction_etc() 1189 + self.update_all_db_etc()
1182 1190
1183 # 매도 1191 # 매도
1184 self.auto_trade_sell_stock(date_rows_today,i) 1192 self.auto_trade_sell_stock(date_rows_today,i)
1185 1193
1186 # 매수할 잔액이 존재한다면 매수 1194 # 매수할 잔액이 존재한다면 매수
1187 - if self.check_balance(): 1195 + if self.jango_check():
1188 - self.auto_trade_buy_stock(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday) 1196 + self.auto_trade_stock_realtime(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday)
1189 1197
1190 # 매도 리스트가 존재하지 않는다면 매수만 진행 1198 # 매도 리스트가 존재하지 않는다면 매수만 진행
1191 else: 1199 else:
1192 - if self.check_balance(): 1200 + if self.jango_check():
1193 - self.auto_trade_buy_stock(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday) 1201 + self.auto_trade_stock_realtime(str(date_rows_today) + "0900", date_rows_today, date_rows_yesterday)
1194 1202
1195 # daily_buy_list 데이터베이스에서 가장 최근의 날짜 테이블을 가져오는 함수 1203 # daily_buy_list 데이터베이스에서 가장 최근의 날짜 테이블을 가져오는 함수
1196 def get_recent_daily_buy_list_date(self): 1204 def get_recent_daily_buy_list_date(self):
...@@ -1204,7 +1212,7 @@ class Simulator_Api: ...@@ -1204,7 +1212,7 @@ class Simulator_Api:
1204 1212
1205 # 최근 daily_buy_list의 날짜 테이블에서 code에 해당하는 데이터만 가져오는 함수 1213 # 최근 daily_buy_list의 날짜 테이블에서 code에 해당하는 데이터만 가져오는 함수
1206 def get_daily_buy_list_by_code(self,code,date): 1214 def get_daily_buy_list_by_code(self,code,date):
1207 - query = f"select * from `{date}` where code = '{code}' group by code" 1215 + query = f"select * from '{date}' where code = '{code}' group by code"
1208 1216
1209 daily_buy_list = self.engine_daily_buy_list.execute(query).fetchall() 1217 daily_buy_list = self.engine_daily_buy_list.execute(query).fetchall()
1210 1218
...@@ -1217,4 +1225,41 @@ class Simulator_Api: ...@@ -1217,4 +1225,41 @@ class Simulator_Api:
1217 "clo60_diff_rate", "clo120_diff_rate", 1225 "clo60_diff_rate", "clo120_diff_rate",
1218 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120', 1226 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
1219 'vol5', 'vol10', 'vol20', 'vol60', 'vol120']) 1227 'vol5', 'vol10', 'vol20', 'vol60', 'vol120'])
1220 - return df_daily_buy_list
...\ No newline at end of file ...\ No newline at end of file
1228 + return df_daily_buy_list
1229 +
1230 + # 현재 특정 종목의 종가를 가져오는 함수
1231 + def get_now_close_price_by_date(self,code,date):
1232 + query=f"select close from '{date}' where code='{code}' group by code"
1233 + result=self.engine_daily_buy_list.execute(query).fetchall()
1234 +
1235 + if len(result)==1:
1236 + return result[0][0]
1237 + else:
1238 + return False
1239 +
1240 + # 모든 테이블을 삭제하는 함수
1241 + def delete_table_data(self):
1242 + if self.is_simul_table_exist(self.db_name,"all_stocks"):
1243 + query="drop table all_stocks"
1244 + self.engine_simul.execute(query)
1245 +
1246 + if self.is_simul_table_exist(self.db_name,"jango_data"):
1247 + query="drop table jango_data"
1248 + self.engine_simul.execute(query)
1249 +
1250 + if self.is_simul_table_exist(self.db_name,"realtime_daily_buy_list"):
1251 + query="drop table realtime_daily_buy_list"
1252 + self.engine_simul.execute(query)
1253 +
1254 + # 코드값으로 해당하는 종목명을 가져오는 함수
1255 + def get_name_by_code(self,code):
1256 + query=f"select code_name from stock_item_all where code='{code}'"
1257 + code_name=self.engine_daily_buy_list.execute(query)
1258 + if code_name:
1259 + return code_name[0][0]
1260 + else:
1261 + return False
1262 +
1263 + # 몇개의 주를 살지 계산하는 함수
1264 + def buy_num_count(self,invest_unit,present_price):
1265 + return int(int(invest_unit)/int(present_price))
...\ No newline at end of file ...\ No newline at end of file
......
No preview for this file type
...@@ -8,7 +8,7 @@ db_ip="localhost" ...@@ -8,7 +8,7 @@ db_ip="localhost"
8 test_account_no="8147766711" 8 test_account_no="8147766711"
9 9
10 test_num=1 10 test_num=1
11 -test_bot_name="AutoBot"+str(test_num)+"_Test" 11 +test_bot_name="autobot"+str(test_num)+"_Test"
12 12
13 # 실전투자 정보 13 # 실전투자 정보
14 real_account_no="" 14 real_account_no=""
......
...@@ -7,8 +7,8 @@ import time ...@@ -7,8 +7,8 @@ import time
7 from PyQt5.QtWidgets import * 7 from PyQt5.QtWidgets import *
8 from pandas import DataFrame 8 from pandas import DataFrame
9 9
10 -from open_api import * 10 +from library.open_api import *
11 -from daily_buy_list import * 11 +from library.daily_buy_list import *
12 12
13 # open_api를 이용하여 데이터베이스에 정보를 저장하는 클래스 13 # open_api를 이용하여 데이터베이스에 정보를 저장하는 클래스
14 class collector_api(): 14 class collector_api():
...@@ -20,51 +20,55 @@ class collector_api(): ...@@ -20,51 +20,55 @@ class collector_api():
20 # 변수설정 20 # 변수설정
21 def variable_setting(self): 21 def variable_setting(self):
22 self.open_api.py_gubun = "collector" # 용도를 저장하는 변수. collector : 데이터 저장 / trader : 종목 거래 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, 23 + self.dc = daily_crawler(self.open_api.cf.real_bot_name, self.open_api.cf.real_daily_craw_db_name,
24 self.open_api.cf.real_daily_buy_list_db_name) 24 self.open_api.cf.real_daily_buy_list_db_name)
25 self.dbl = daily_buy_list() 25 self.dbl = daily_buy_list()
26 26
27 # 콜렉팅을 실행하는 함수 27 # 콜렉팅을 실행하는 함수
28 def code_update_check(self): 28 def code_update_check(self):
29 - logger.debug("code_update_check function") 29 + logger.debug("code_update_check 함수에 들어왔습니다.")
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 30
33 - rows = self.engine_bot.execute(query).fetchall() 31 + sql = "select code_update,jango_data_db_check, possessed_item, today_profit, final_chegyul_check, " \
32 + "db_to_buy_list,today_buy_list, daily_crawler , min_crawler, daily_buy_list from setting_data limit 1"
33 + rows = self.engine_bot.execute(sql).fetchall()
34 +
35 + # 종목 업데이트
36 + if rows[0][0] != self.open_api.today:
37 + self.open_api.check_balance()
34 38
35 # 잔고/보유종목 업데이트 확인 39 # 잔고/보유종목 업데이트 확인
36 - if rows[0][0] != self.open_api.today or rows[0][1] != self.open_api.today: 40 + if rows[0][1] != self.open_api.today or rows[0][2] != self.open_api.today:
37 self.py_check_balance() 41 self.py_check_balance()
38 self.open_api.set_invest_unit() 42 self.open_api.set_invest_unit()
39 43
40 # possessed_item(현재 보유종목) 테이블 업데이트 44 # possessed_item(현재 보유종목) 테이블 업데이트
41 - if rows[0][1] != self.open_api.today: 45 + if rows[0][2] != self.open_api.today:
42 - self.open_api.db_to_possesed_item() 46 + self.open_api.db_to_possessed_item()
43 - self.open_api.setting_data_possesed_item() 47 + self.open_api.setting_data_possessed_item()
44 48
45 # 당일 종목별 실현 손익 내역 테이블 업데이트 49 # 당일 종목별 실현 손익 내역 테이블 업데이트
46 - if rows[0][2] != self.open_api.today: 50 + if rows[0][3] != self.open_api.today:
47 self.db_to_today_profit_list() 51 self.db_to_today_profit_list()
48 52
49 # daily_craw 데이터베이스 업데이트 53 # daily_craw 데이터베이스 업데이트
50 - if rows[0][6] != self.open_api.today: 54 + if rows[0][7] != self.open_api.today:
51 self.daily_crawler_check() 55 self.daily_crawler_check()
52 56
53 # daily_buy_list 데이터베이스 업데이트 57 # daily_buy_list 데이터베이스 업데이트
54 - if rows[0][8] != self.open_api.today: 58 + if rows[0][9] != self.open_api.today:
55 self.daily_buy_list_check() 59 self.daily_buy_list_check()
56 60
57 # 매수/매도 후 daily_buy_list 데이터베이스 업데이트 61 # 매수/매도 후 daily_buy_list 데이터베이스 업데이트
58 - if rows[0][3] != self.open_api.today: 62 + if rows[0][4] != self.open_api.today:
59 - self.open_api.chegyul_check() # 매수 후 all_stocks에 저장되지 않은 종목 처리 63 + self.open_api.check_chegyul() # 매수 후 all_item_db에 저장되지 않은 종목 처리
60 - self.open_api.final_chegyul_check() # # 매도 후 all_stocks에 sell_date가 업데이트 되지 않은 항목 처리 64 + self.open_api.final_chegyul_check() # 매도 후 all_item_db에 sell_date가 업데이트 되지 않은 항목 처리
61 65
62 # 다음날 매수 종목 테이블(realtime_daily_buy_list) 업데이트 66 # 다음날 매수 종목 테이블(realtime_daily_buy_list) 업데이트
63 - if rows[0][5] != self.open_api.today: 67 + if rows[0][6] != self.open_api.today:
64 self.realtime_daily_buy_list_check() 68 self.realtime_daily_buy_list_check()
65 69
66 # min_craw db (분별 데이터) 업데이트 70 # min_craw db (분별 데이터) 업데이트
67 - if rows[0][7] != self.open_api.today: 71 + if rows[0][8] != self.open_api.today:
68 self.min_crawler_check() 72 self.min_crawler_check()
69 73
70 logger.debug("collecting 작업을 모두 정상적으로 마쳤습니다.") 74 logger.debug("collecting 작업을 모두 정상적으로 마쳤습니다.")
...@@ -179,7 +183,7 @@ class collector_api(): ...@@ -179,7 +183,7 @@ class collector_api():
179 logger.debug("daily_crawler success !!!") 183 logger.debug("daily_crawler success !!!")
180 184
181 sql = "UPDATE setting_data SET daily_crawler='%s' limit 1" 185 sql = "UPDATE setting_data SET daily_crawler='%s' limit 1"
182 - self.engine_JB.execute(sql % (self.open_api.today)) 186 + self.engine_bot.execute(sql % (self.open_api.today))
183 187
184 # 틱(1분 별) 데이터를 가져오는 함수 188 # 틱(1분 별) 데이터를 가져오는 함수
185 def set_min_crawler_table(self, code, code_name): 189 def set_min_crawler_table(self, code, code_name):
...@@ -271,7 +275,7 @@ class collector_api(): ...@@ -271,7 +275,7 @@ class collector_api():
271 df_temp.to_sql(name=code_name, con=self.open_api.engine_craw, if_exists='append') 275 df_temp.to_sql(name=code_name, con=self.open_api.engine_craw, if_exists='append')
272 # 콜렉팅하다가 max_api_call 횟수까지 가게 된 경우 276 # 콜렉팅하다가 max_api_call 횟수까지 가게 된 경우
273 # 이후 콜렉팅 하지 못한 정보를 가져오기 위해 check_item_gubun=0 277 # 이후 콜렉팅 하지 못한 정보를 가져오기 위해 check_item_gubun=0
274 - if self.open_api.rq_count == cf.max_api_call - 1: 278 + if self.open_api.rq_count == self.open_api.cf.max_api_call - 1:
275 check_item_gubun = 0 279 check_item_gubun = 0
276 # 정상완료한 경우 check_item_gubun=1 280 # 정상완료한 경우 check_item_gubun=1
277 else: 281 else:
...@@ -289,7 +293,7 @@ class collector_api(): ...@@ -289,7 +293,7 @@ class collector_api():
289 293
290 # 특정 종목명(code_name)의 테이블이 존재하는 경우 294 # 특정 종목명(code_name)의 테이블이 존재하는 경우
291 if self.engine_bot.dialect.has_table(self.open_api.engine_daily_craw, code_name): 295 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" 296 + 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() 297 check_row = self.open_api.engine_daily_craw.execute(query).fetchall()
294 # 종목명 테이블이 존재하지 않는 경우, 종목 리스트(stock_item_all) 테이블에 check_daily_crawler=4 업데이트 298 # 종목명 테이블이 존재하지 않는 경우, 종목 리스트(stock_item_all) 테이블에 check_daily_crawler=4 업데이트
295 else: 299 else:
...@@ -372,12 +376,12 @@ class collector_api(): ...@@ -372,12 +376,12 @@ class collector_api():
372 return check_item_gubun 376 return check_item_gubun
373 377
374 df_temp[['close', 'open', 'high', 'low', 'volume', 'clo5', 'clo10', 'clo20', 'clo60','clo120', 378 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', 379 + 'yes_clo5', 'yes_clo10', 'yes_clo20','yes_clo60', 'yes_clo120',
376 - 'vol5', 'vol10', 'vol20', 'vol40', 'vol60', 'vol80', 'vol100', 'vol120']] = \ 380 + 'vol5', 'vol10', 'vol20','vol60','vol120']] = \
377 df_temp[ 381 df_temp[
378 ['close', 'open', 'high', 'low', 'volume', 'clo5', 'clo10', 'clo20','clo60','clo120', 382 ['close', 'open', 'high', 'low', 'volume', 'clo5', 'clo10', 'clo20','clo60','clo120',
379 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120', 383 'yes_clo5', 'yes_clo10', 'yes_clo20', 'yes_clo60','yes_clo120',
380 - 'vol5', 'vol10', 'vol20', 'vol40', 'vol60', 'vol80', 'vol100', 'vol120']].fillna(0).astype(int) 384 + 'vol5', 'vol10', 'vol20', 'vol60', 'vol120']].fillna(0).astype(int)
381 385
382 df_temp.to_sql(name=code_name, con=self.open_api.engine_daily_craw, if_exists='append') 386 df_temp.to_sql(name=code_name, con=self.open_api.engine_daily_craw, if_exists='append')
383 387
...@@ -388,7 +392,7 @@ class collector_api(): ...@@ -388,7 +392,7 @@ class collector_api():
388 logger.info('daily_buy_list 업데이트 중..') 392 logger.info('daily_buy_list 업데이트 중..')
389 393
390 query="SELECT table_name as tname FROM information_schema.tables " \ 394 query="SELECT table_name as tname FROM information_schema.tables " \
391 - "WHERE table_schema ='daily_buy_list' AND table_name REGEXP '[0-9]{8}" 395 + "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() 396 dbl_dates = self.open_api.engine_daily_buy_list.execute(query).fetchall()
393 397
394 for row in dbl_dates: 398 for row in dbl_dates:
...@@ -410,14 +414,14 @@ class collector_api(): ...@@ -410,14 +414,14 @@ class collector_api():
410 def db_to_today_profit_list(self): 414 def db_to_today_profit_list(self):
411 self.open_api.reset_opt10073_output() 415 self.open_api.reset_opt10073_output()
412 416
413 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 417 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
414 self.open_api.set_input_value("시작일자", self.open_api.today) 418 self.open_api.set_input_value("시작일자", self.open_api.today)
415 self.open_api.set_input_value("종료일자", self.open_api.today) 419 self.open_api.set_input_value("종료일자", self.open_api.today)
416 420
417 self.open_api.comm_rq_data("opt10073_req", "opt10073", 0, "0328") 421 self.open_api.comm_rq_data("opt10073_req", "opt10073", 0, "0328")
418 422
419 while self.open_api.remained_data: 423 while self.open_api.remained_data:
420 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 424 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
421 self.open_api.comm_rq_data("opt10073_req", "opt10073", 2, "0328") 425 self.open_api.comm_rq_data("opt10073_req", "opt10073", 2, "0328")
422 426
423 today_profit_item_temp = {'date': [], 'code': [], 'code_name': [], 'amount': [], 'today_profit': [], 427 today_profit_item_temp = {'date': [], 'code': [], 'code_name': [], 'amount': [], 'today_profit': [],
...@@ -500,13 +504,13 @@ class collector_api(): ...@@ -500,13 +504,13 @@ class collector_api():
500 504
501 # 총 익절 종목 수(total_profitcut_count) 505 # 총 익절 종목 수(total_profitcut_count)
502 query = "select count(*) " \ 506 query = "select count(*) " \
503 - "from (select code from all_stocks where sell_rate >='%s' and sell_date like '%s' group by code)" 507 + "from (select code from all_stocks where sell_rate >='%s' and sell_date like '%s' group by code) temp"
504 rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall() 508 rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall()
505 jango.loc[0, 'total_profitcut_count'] = int(rows[0][0]) 509 jango.loc[0, 'total_profitcut_count'] = int(rows[0][0])
506 510
507 # 총 손절 종목 수(total_losscut_count) 511 # 총 손절 종목 수(total_losscut_count)
508 query = "select count(*) " \ 512 query = "select count(*) " \
509 - "from (select code from all_stocks where sell_rate < '%s' and sell_date like '%s' group by code)" 513 + "from (select code from all_stocks where sell_rate < '%s' and sell_date like '%s' group by code) temp"
510 rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall() 514 rows = self.engine_bot.execute(query % (0, self.open_api.today + "%%")).fetchall()
511 jango.loc[0, 'total_losscut_count'] = int(rows[0][0]) 515 jango.loc[0, 'total_losscut_count'] = int(rows[0][0])
512 516
...@@ -525,7 +529,7 @@ class collector_api(): ...@@ -525,7 +529,7 @@ class collector_api():
525 # 당일 구매 종목 수 (today_buy_count) 529 # 당일 구매 종목 수 (today_buy_count)
526 query = "UPDATE jango_data SET " \ 530 query = "UPDATE jango_data SET " \
527 "today_buy_count=" \ 531 "today_buy_count=" \
528 - "(select count(*) from (select code from all_stocks where buy_date like '%s' group by code)) " \ 532 + "(select count(*) from (select code from all_stocks where buy_date like '%s' group by code) temp) " \
529 "WHERE date='%s'" 533 "WHERE date='%s'"
530 self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0])) 534 self.engine_bot.execute(query % (rows[i][0] + "%%", rows[i][0]))
531 535
...@@ -539,8 +543,8 @@ class collector_api(): ...@@ -539,8 +543,8 @@ class collector_api():
539 543
540 # 총 보유 종목 수 (total_possess_count) 544 # 총 보유 종목 수 (total_possess_count)
541 query = "UPDATE jango_data SET " \ 545 query = "UPDATE jango_data SET " \
542 - "today_buy_total_possess_count=" \ 546 + "total_possess_count=" \
543 - "(select count(*) from (select code from all_stocks where sell_date = '0' group by code )) " \ 547 + "(select count(*) from (select code from all_stocks where sell_date = '0' group by code ) temp) " \
544 "WHERE date='%s'" 548 "WHERE date='%s'"
545 self.engine_bot.execute(query % (rows[i][0])) 549 self.engine_bot.execute(query % (rows[i][0]))
546 550
...@@ -554,27 +558,27 @@ class collector_api(): ...@@ -554,27 +558,27 @@ class collector_api():
554 # 예수금상세현황 558 # 예수금상세현황
555 self.open_api.reset_opw00018_output() 559 self.open_api.reset_opw00018_output()
556 560
557 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 561 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
558 self.open_api.set_input_value("비밀번호입력매체구분", 00) 562 self.open_api.set_input_value("비밀번호입력매체구분", 00)
559 self.open_api.set_input_value("조회구분", 1) 563 self.open_api.set_input_value("조회구분", 1)
560 self.open_api.comm_rq_data("opw00001_req", "opw00001", 0, "2000") 564 self.open_api.comm_rq_data("opw00001_req", "opw00001", 0, "2000")
561 565
562 # 계좌평가잔고내역 566 # 계좌평가잔고내역
563 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 567 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
564 self.open_api.comm_rq_data("opw00018_req", "opw00018", 0, "2000") 568 self.open_api.comm_rq_data("opw00018_req", "opw00018", 0, "2000")
565 569
566 while self.open_api.remained_data: 570 while self.open_api.remained_data:
567 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 571 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
568 self.open_api.comm_rq_data("opw00018_req", "opw00018", 2, "2000") 572 self.open_api.comm_rq_data("opw00018_req", "opw00018", 2, "2000")
569 573
570 # 일자별실현손익 574 # 일자별실현손익
571 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 575 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
572 self.open_api.set_input_value("시작일자", "20170101") 576 self.open_api.set_input_value("시작일자", "20170101")
573 self.open_api.set_input_value("종료일자", self.open_api.today) 577 self.open_api.set_input_value("종료일자", self.open_api.today)
574 578
575 self.open_api.comm_rq_data("opt10074_req", "opt10074", 0, "0329") 579 self.open_api.comm_rq_data("opt10074_req", "opt10074", 0, "0329")
576 while self.open_api.remained_data: 580 while self.open_api.remained_data:
577 - self.open_api.set_input_value("계좌번호", self.open_api.account_number) 581 + self.open_api.set_input_value("계좌번호", self.open_api.account_no)
578 self.open_api.set_input_value("시작일자", "20170101") 582 self.open_api.set_input_value("시작일자", "20170101")
579 self.open_api.set_input_value("종료일자", "20180930") 583 self.open_api.set_input_value("종료일자", "20180930")
580 584
......
...@@ -2,31 +2,32 @@ from sqlalchemy import * ...@@ -2,31 +2,32 @@ from sqlalchemy import *
2 from pandas import DataFrame 2 from pandas import DataFrame
3 import datetime 3 import datetime
4 4
5 -from daily_crawler import * 5 +from library.daily_crawler import *
6 -import cf 6 +from library.cf import *
7 7
8 # -* daily_buy_list *- 8 # -* daily_buy_list *-
9 # 일자별로 주식종목에 대한 데이터를 저장하는 데이터베이스 9 # 일자별로 주식종목에 대한 데이터를 저장하는 데이터베이스
10 10
11 class daily_buy_list(): 11 class daily_buy_list():
12 def __init__(self): 12 def __init__(self):
13 + self.cf=library.cf
13 self.variable_setting() 14 self.variable_setting()
14 15
15 # 변수 설정 16 # 변수 설정
16 def variable_setting(self): 17 def variable_setting(self):
17 self.today = datetime.datetime.today().strftime("%Y%m%d") 18 self.today = datetime.datetime.today().strftime("%Y%m%d")
18 self.today_detail = datetime.datetime.today().strftime("%Y%m%d%H%M") 19 self.today_detail = datetime.datetime.today().strftime("%Y%m%d%H%M")
19 - self.start_date = cf.start_daily_buy_list 20 + self.start_date = self.cf.start_daily_buy_list
20 self.engine_daily_craw = create_engine( 21 self.engine_daily_craw = create_engine(
21 - "mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + cf.db_port + "/daily_craw", 22 + "mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" + self.cf.db_port + "/daily_craw",
22 encoding='utf-8') 23 encoding='utf-8')
23 self.engine_daily_buy_list = create_engine( 24 self.engine_daily_buy_list = create_engine(
24 - "mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + cf.db_port + "/daily_buy_list", 25 + "mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" + self.cf.db_port + "/daily_buy_list",
25 encoding='utf-8') 26 encoding='utf-8')
26 27
27 # 설정한 날짜부터 현재까지 날짜 리스트를 저장하는 함수 28 # 설정한 날짜부터 현재까지 날짜 리스트를 저장하는 함수
28 def date_rows_setting(self): 29 def date_rows_setting(self):
29 - query = "select date from `gs글로벌` where date >= '%s' group by date" 30 + query = "select date from 대한항공 where date >= '%s' group by date"
30 self.date_rows = self.engine_daily_craw.execute(query % self.start_date).fetchall() 31 self.date_rows = self.engine_daily_craw.execute(query % self.start_date).fetchall()
31 32
32 # daily_buy_list 데이터베이스에 특정 이름(date)을 가진 테이블이 존재하는지 확인하는 함수 33 # daily_buy_list 데이터베이스에 특정 이름(date)을 가진 테이블이 존재하는지 확인하는 함수
...@@ -63,14 +64,15 @@ class daily_buy_list(): ...@@ -63,14 +64,15 @@ class daily_buy_list():
63 if not self.is_table_exist_daily_craw(code, code_name): 64 if not self.is_table_exist_daily_craw(code, code_name):
64 continue 65 continue
65 66
66 - query = f"select * from '{self.stock_item_all[i][0]}' where date = '{self.date_rows[k][0]}' " \ 67 + query = f"select * from {self.stock_item_all[i][0]} where date = '{self.date_rows[k][0]}' " \
67 f"group by date" 68 f"group by date"
68 rows = self.engine_daily_craw.execute(query).fetchall() 69 rows = self.engine_daily_craw.execute(query).fetchall()
69 multi_list += rows 70 multi_list += rows
70 71
71 if len(multi_list) != 0: 72 if len(multi_list) != 0:
72 df_temp = DataFrame(multi_list, 73 df_temp = DataFrame(multi_list,
73 - columns=['index', 'date', 'check_item', 'code', 'code_name', 'd1_diff_rate', 74 + columns=['index', 'date', 'check_item', 'code', 'code_name',
75 + 'd1_diff','d1_diff_rate',
74 'close', 'open', 'high', 'low','volume', 76 'close', 'open', 'high', 'low','volume',
75 'clo5', 'clo10', 'clo20', 'clo60', 'clo120', 77 'clo5', 'clo10', 'clo20', 'clo60', 'clo120',
76 "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate", 78 "clo5_diff_rate", "clo10_diff_rate","clo20_diff_rate",
......
...@@ -5,7 +5,7 @@ from sqlalchemy import create_engine ...@@ -5,7 +5,7 @@ from sqlalchemy import create_engine
5 import pandas as pd 5 import pandas as pd
6 from PyQt5.QtCore import * 6 from PyQt5.QtCore import *
7 7
8 -import cf 8 +import library.cf
9 9
10 pymysql.install_as_MySQLdb() 10 pymysql.install_as_MySQLdb()
11 11
...@@ -14,6 +14,7 @@ pymysql.install_as_MySQLdb() ...@@ -14,6 +14,7 @@ pymysql.install_as_MySQLdb()
14 14
15 class daily_crawler(): 15 class daily_crawler():
16 def __init__(self, db_name, daily_craw_db_name, daily_buy_list_db_name): 16 def __init__(self, db_name, daily_craw_db_name, daily_buy_list_db_name):
17 + self.cf=library.cf
17 # db_name==0인 경우는 simulator 18 # db_name==0인 경우는 simulator
18 if db_name != 0: 19 if db_name != 0:
19 self.db_name = db_name 20 self.db_name = db_name
...@@ -22,7 +23,7 @@ class daily_crawler(): ...@@ -22,7 +23,7 @@ class daily_crawler():
22 self.daily_buy_list_db_name = daily_buy_list_db_name 23 self.daily_buy_list_db_name = daily_buy_list_db_name
23 24
24 self.engine = create_engine( 25 self.engine = create_engine(
25 - "mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + cf.db_port + "/daily_craw", 26 + "mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" + self.cf.db_port + "/daily_craw",
26 encoding='utf-8') 27 encoding='utf-8')
27 self.daily_craw_db_con = self.engine.connect() 28 self.daily_craw_db_con = self.engine.connect()
28 29
......
...@@ -15,14 +15,15 @@ from sqlalchemy.pool import Pool ...@@ -15,14 +15,15 @@ from sqlalchemy.pool import Pool
15 import pymysql 15 import pymysql
16 pymysql.install_as_MySQLdb() 16 pymysql.install_as_MySQLdb()
17 17
18 -from Logger import * 18 +from library.Logger import *
19 -import cf 19 +import library.cf
20 -from Simulator_Api import * 20 +from library.simulator_api import *
21 21
22 # open_api에 tr요청을 보낼 때, 연속해서 보내면 오류가 발생하기 때문에 중간에 interval을 줘야 한다. 22 # open_api에 tr요청을 보낼 때, 연속해서 보내면 오류가 발생하기 때문에 중간에 interval을 줘야 한다.
23 TR_REQ_TIME_INTERVAL=0.5 # interval값을 저장하는 변수 23 TR_REQ_TIME_INTERVAL=0.5 # interval값을 저장하는 변수
24 code_pattern=re.compile(r'\d{6}') # 코드 패턴을 저장. 코드는 연속된 6자리의 숫자 24 code_pattern=re.compile(r'\d{6}') # 코드 패턴을 저장. 코드는 연속된 6자리의 숫자
25 25
26 +
26 # query문의 %를 %%로 변환하는 함수 27 # query문의 %를 %%로 변환하는 함수
27 def escape_percentage(conn,clauseelement,multiparmas,parmas): 28 def escape_percentage(conn,clauseelement,multiparmas,parmas):
28 if isinstance(clauseelement,str) and '%' in clauseelement and multiparmas is not None: 29 if isinstance(clauseelement,str) and '%' in clauseelement and multiparmas is not None:
...@@ -33,14 +34,18 @@ def escape_percentage(conn,clauseelement,multiparmas,parmas): ...@@ -33,14 +34,18 @@ def escape_percentage(conn,clauseelement,multiparmas,parmas):
33 clauseelement=replaced 34 clauseelement=replaced
34 return clauseelement,multiparmas,parmas 35 return clauseelement,multiparmas,parmas
35 36
37 +
36 # MySQL의 default sql_mode 설정 38 # MySQL의 default sql_mode 설정
37 -def setup_sql_mod(dbapi_connection): 39 +def setup_sql_mod(dbapi_connection,connection_record):
38 cursor=dbapi_connection.cursor() 40 cursor=dbapi_connection.cursor()
39 cursor.execute("SET sql_mode=''") 41 cursor.execute("SET sql_mode=''")
40 42
43 +
41 event.listen(Pool,'connect',setup_sql_mod) 44 event.listen(Pool,'connect',setup_sql_mod)
42 event.listen(Pool,'first_connect',setup_sql_mod) 45 event.listen(Pool,'first_connect',setup_sql_mod)
43 46
47 +
48 +# 키움증권 open_api를 사용하기 위한 클래스
44 class open_api(QAxWidget): 49 class open_api(QAxWidget):
45 def __init__(self): 50 def __init__(self):
46 super().__init__() 51 super().__init__()
...@@ -51,49 +56,51 @@ class open_api(QAxWidget): ...@@ -51,49 +56,51 @@ class open_api(QAxWidget):
51 56
52 # open_api 호출 횟수를 저장 57 # open_api 호출 횟수를 저장
53 self.rq_count=0 58 self.rq_count=0
54 - self.set_date()
55 self.tr_loop_count=0 59 self.tr_loop_count=0
56 self.call_time=datetime.datetime.now() 60 self.call_time=datetime.datetime.now()
57 61
62 + # 날짜 설정
63 + self.date_setting()
64 +
58 # open_api 연동 65 # open_api 연동
59 - self._create_instance() 66 + self._create_open_api_instance()
60 self._set_signal_slots() 67 self._set_signal_slots()
61 self.comm_connect() 68 self.comm_connect()
62 69
63 # 계좌정보 출력 70 # 계좌정보 출력
64 - self.get_account_info() 71 + self.account_info()
65 72
66 # 변수 설정 73 # 변수 설정
67 - self.set_variable() 74 + self.variable_setting()
68 -
69 - self.sf=Simulator_Api(self.simul_num,"real",self.db_name)
70 - logger.debug("알고리즘 번호 : %s",self.simul_api.simul_num)
71 - logger.debug("매수 알고리즘 번호 : %s",self.simul_api.buy_algorithm)
72 - logger.debug("매도 알고리즘 번호 : %s",self.simul_api.sell_algorithm)
73 75
76 + self.sf=simulator_api(self.simul_num,"real",self.db_name)
77 + logger.debug("알고리즘 번호 : %s", self.sf.simul_num)
78 + logger.debug("다음날 매수종목 선택 알고리즘 번호 : %s", self.sf.db_to_realtime_daily_buy_list_num)
79 + logger.debug("매도 알고리즘 번호 : %s", self.sf.sell_list_num)
80 +
74 # 시뮬레이션 데이터베이스에 setting_data 테이블이 존재하지 않는다면 생성 81 # 시뮬레이션 데이터베이스에 setting_data 테이블이 존재하지 않는다면 생성
75 if not self.sf.is_simul_table_exist(self.db_name,"setting_data"): 82 if not self.sf.is_simul_table_exist(self.db_name,"setting_data"):
76 - self.init_setting_data() 83 + self.init_db_setting_data()
84 + else:
85 + logger.debug("setting_data 테이블이 존재합니다.")
77 86
78 # invest unit 설정 87 # invest unit 설정
79 - self.set_simul_variable() 88 + self.sf_variable_setting()
80 - self.ohlcv=defaultdict(list) 89 + self.ohlcv=defaultdict(list) # o(open)h(high)l(low)c(close)v(volume)를 저장하는 데이터프레임 변수
81 90
82 - # 날짜 설정 91 + # 오늘 날짜를 저장하는 함수
83 - # -* date_setting 92 + def date_setting(self):
84 - def set_date(self): 93 + self.today=datetime.datetime.today().strftime("%Y%m%d") # 년월일
85 - self.today=datetime.datetime.today().strftime("%Y%m%d") 94 + self.today_detail=datetime.datetime.today().strftime("%Y%m%d%H%M") # 년월일시분
86 - self.today_time=datetime.datetime.today().strftime("%Y%m%d%H%M")
87 95
88 - # 키움 open_api 를 사용하기 위한 ocx controller 생성 96 + # 키움 open_api 를 사용하기 위한 ocx controller 생성 함수
89 - # -* create_open_api_instance 97 + def _create_open_api_instance(self):
90 - def _create_instance(self):
91 try: 98 try:
92 self.setControl("KHOPENAPI.KHOpenAPICtrl.1") 99 self.setControl("KHOPENAPI.KHOpenAPICtrl.1")
93 except Exception as e: 100 except Exception as e:
94 logger.critical(e) 101 logger.critical(e)
95 102
96 - # 이벤트 처리를 위한 slots 103 + # 이벤트 처리를 위한 slots 연동 함수
97 def _set_signal_slots(self): 104 def _set_signal_slots(self):
98 try: 105 try:
99 # 로그인 처리 이벤트 106 # 로그인 처리 이벤트
...@@ -121,11 +128,11 @@ class open_api(QAxWidget): ...@@ -121,11 +128,11 @@ class open_api(QAxWidget):
121 logger.critical(e) 128 logger.critical(e)
122 129
123 # 사용자의 계좌정보 저장 및 출력 130 # 사용자의 계좌정보 저장 및 출력
124 - def get_account_info(self): 131 + def account_info(self):
125 logger.debug("-* get_account_info 함수 *-") 132 logger.debug("-* get_account_info 함수 *-")
126 account_no=self.get_login_info("ACCNO") 133 account_no=self.get_login_info("ACCNO")
127 self.account_no=account_no.split(";")[0] 134 self.account_no=account_no.split(";")[0]
128 - logger.debug("계좌번호 : ", self.account_no) 135 + logger.debug("계좌번호 : "+ self.account_no)
129 136
130 # 원하는 사용자 정보 반환 137 # 원하는 사용자 정보 반환
131 # param : tag - ACCNO - 보유계좌리스트 138 # param : tag - ACCNO - 보유계좌리스트
...@@ -165,10 +172,10 @@ class open_api(QAxWidget): ...@@ -165,10 +172,10 @@ class open_api(QAxWidget):
165 self.remained_data=False 172 self.remained_data=False
166 173
167 # Request 요청에 따른 함수 처리 174 # Request 요청에 따른 함수 처리
168 - if sRQName == "opt10081_req" and self.purpose == "trader": 175 + if sRQName == "opt10081_req" and self.py_gubun == "trader":
169 logger.debug("주식일봉차트조회요청") 176 logger.debug("주식일봉차트조회요청")
170 self._opt10081(sRQName,sTrCode) 177 self._opt10081(sRQName,sTrCode)
171 - elif sRQName == "opt10081_req" and self.purpose == "collector": 178 + elif sRQName == "opt10081_req" and self.py_gubun == "collector":
172 logger.debug("주식일봉차트조회요청") 179 logger.debug("주식일봉차트조회요청")
173 self.collector_opt10081(sRQName,sTrCode) 180 self.collector_opt10081(sRQName,sTrCode)
174 elif sRQName == "opw00001_req": 181 elif sRQName == "opw00001_req":
...@@ -225,31 +232,31 @@ class open_api(QAxWidget): ...@@ -225,31 +232,31 @@ class open_api(QAxWidget):
225 return 232 return
226 233
227 chegyul_fail_amount=self.get_chejan_data(902) # 미체결 수량 234 chegyul_fail_amount=self.get_chejan_data(902) # 미체결 수량
228 - order_gubun=self.get_chejan_data(905) # 주문구분 235 + order_gubun=self.get_chejan_data(905) # 주문구분 (+매수 / -매도)
229 purchase_price=self.get_chejan_data(10) # 체결가 236 purchase_price=self.get_chejan_data(10) # 체결가
230 237
231 # 종목코드가 존재한다면 238 # 종목코드가 존재한다면
232 if code: 239 if code:
233 if chegyul_fail_amount!="": 240 if chegyul_fail_amount!="":
234 # 해당 종목을 보유하고 있지 않은 경우 241 # 해당 종목을 보유하고 있지 않은 경우
235 - if not self.is_all_stock_check(code): 242 + if not self.is_all_stocks_db_check(code):
236 # 해당 종목의 체결 실패 내역이 없다면 243 # 해당 종목의 체결 실패 내역이 없다면
237 - # transaction 테이블에 업데이트. 정상 체결 시 chegyul_check=0 244 + # all_stocks 테이블에 업데이트. 정상 체결 시 chegyul_check=0
238 if chegyul_fail_amount=="0": 245 if chegyul_fail_amount=="0":
239 logger.debug(code, "체결 완료") 246 logger.debug(code, "체결 완료")
240 self.db_to_all_stocks(order_num,code,0,purchase_price,0) 247 self.db_to_all_stocks(order_num,code,0,purchase_price,0)
241 # 체결 실패 내역이 존재한다면 248 # 체결 실패 내역이 존재한다면
242 - # transaction 테이블에 업데이트. 미체결 시 chegyul_check=1 249 + # all_stocks 테이블에 업데이트. 미체결 시 chegyul_check=1
243 else: 250 else:
244 logger.debug(code,"미체결") 251 logger.debug(code,"미체결")
245 self.db_to_all_stocks(order_num,code,1,purchase_price,0) 252 self.db_to_all_stocks(order_num,code,1,purchase_price,0)
246 253
247 # 매수하는 경우 254 # 매수하는 경우
248 elif order_gubun=="+매수": 255 elif order_gubun=="+매수":
249 - if chegyul_fail_amount!="0" and self.check_stock_chegyul(code): 256 + if chegyul_fail_amount!="0" and self.stock_chegyul_check(code):
250 logger.debug("미체결. 매수 진행중!") 257 logger.debug("미체결. 매수 진행중!")
251 pass 258 pass
252 - elif chegyul_fail_amount=="0" and self.check_stock_chegyul(code): 259 + elif chegyul_fail_amount=="0" and self.stock_chegyul_check(code):
253 logger.debug("매수 완료") 260 logger.debug("매수 완료")
254 self.end_invest_count_check(code) 261 self.end_invest_count_check(code)
255 else: 262 else:
...@@ -262,14 +269,14 @@ class open_api(QAxWidget): ...@@ -262,14 +269,14 @@ class open_api(QAxWidget):
262 self.sell_final_check(code) 269 self.sell_final_check(code)
263 else: 270 else:
264 logger.debug("부분 매도") 271 logger.debug("부분 매도")
265 - self.check_sell_chegyul_fail(code) 272 + self.sell_chegyul_fail_check(code)
266 273
267 else: 274 else:
268 logger.debug("Invalid order_gubun") 275 logger.debug("Invalid order_gubun")
269 else: 276 else:
270 logger.debug("Invalid chegyul_fail_amount value") 277 logger.debug("Invalid chegyul_fail_amount value")
271 else: 278 else:
272 - logger.debug("can't receive code value") 279 + logger.debug("can't receive code value from get_chejan_data(9001)")
273 280
274 # 국내주식 잔고전달 281 # 국내주식 잔고전달
275 elif sGubun=="1": 282 elif sGubun=="1":
...@@ -280,7 +287,8 @@ class open_api(QAxWidget): ...@@ -280,7 +287,8 @@ class open_api(QAxWidget):
280 logger.debug("Invlid _receive_chejan_data") 287 logger.debug("Invlid _receive_chejan_data")
281 288
282 # 해당 종목이 체결되었는지 확인하는 함수 289 # 해당 종목이 체결되었는지 확인하는 함수
283 - def check_stock_chegyul(self,code): 290 + # 미체결 항목이 존재하면 True를 반환
291 + def stock_chegyul_check(self,code):
284 query = f"SELECT chegyul_check FROM all_stocks " \ 292 query = f"SELECT chegyul_check FROM all_stocks " \
285 f"where code='{code}' and sell_date = '0' ORDER BY buy_date desc LIMIT 1" 293 f"where code='{code}' and sell_date = '0' ORDER BY buy_date desc LIMIT 1"
286 result = self.engine_bot.execute(query).fetchall() 294 result = self.engine_bot.execute(query).fetchall()
...@@ -289,9 +297,9 @@ class open_api(QAxWidget): ...@@ -289,9 +297,9 @@ class open_api(QAxWidget):
289 else: 297 else:
290 return False 298 return False
291 299
292 - # 매도 완료 후 DB 업데이트 300 + # 매도 완료 후 DB 업데이트
293 - def check_sell_end(self,code): 301 + def sell_final_check(self,code):
294 - query="select valuation_profit,rate,item_total_urchase,present_price" \ 302 + query="select valuation_profit,rate,item_total_purchase,present_price" \
295 "from possessed_item" \ 303 "from possessed_item" \
296 "where code={} limit 1" 304 "where code={} limit 1"
297 get_list=self.engine_bot.execute(query.format(code)).fetchall() 305 get_list=self.engine_bot.execute(query.format(code)).fetchall()
...@@ -299,7 +307,7 @@ class open_api(QAxWidget): ...@@ -299,7 +307,7 @@ class open_api(QAxWidget):
299 # 매도 완료 종목에 대해 DB 업데이트 307 # 매도 완료 종목에 대해 DB 업데이트
300 if get_list: 308 if get_list:
301 item = get_list[0] 309 item = get_list[0]
302 - query = f"""UPDATE transaction 310 + query = f"""UPDATE all_stocks
303 SET 311 SET
304 item_total_purchase = {item.item_total_purchase}, chegyul_check = 0, 312 item_total_purchase = {item.item_total_purchase}, chegyul_check = 0,
305 sell_date = '{self.today_detail}', valuation_profit = {item.valuation_profit}, 313 sell_date = '{self.today_detail}', valuation_profit = {item.valuation_profit},
...@@ -313,7 +321,7 @@ class open_api(QAxWidget): ...@@ -313,7 +321,7 @@ class open_api(QAxWidget):
313 logger.debug("보유 종목이 없습니다.") 321 logger.debug("보유 종목이 없습니다.")
314 322
315 # 매도 체결 실패시 DB 업데이트 323 # 매도 체결 실패시 DB 업데이트
316 - def check_sell_chegyul_fail(self,code): 324 + def sell_chegyul_fail_check(self,code):
317 query = f"UPDATE all_stocks SET chegyul_check='1' WHERE code='{code}' and sell_date = '0' " \ 325 query = f"UPDATE all_stocks SET chegyul_check='1' WHERE code='{code}' and sell_date = '0' " \
318 f"ORDER BY buy_date desc LIMIT 1" 326 f"ORDER BY buy_date desc LIMIT 1"
319 self.engine_JB.execute(query) 327 self.engine_JB.execute(query)
...@@ -330,9 +338,10 @@ class open_api(QAxWidget): ...@@ -330,9 +338,10 @@ class open_api(QAxWidget):
330 except Exception as e: 338 except Exception as e:
331 logger.critical(e) 339 logger.critical(e)
332 340
333 - # 거래이력(transaction)테이블에 현재 보유중인 종목이 있는지 확인하는 함수 341 + # 거래이력(all_stocks)테이블에 현재 보유중인 종목이 있는지 확인하는 함수
334 - def is_transaction_check(self,code): 342 + # 보유한 종목이 있는 경우 True 반환
335 - query = "select code from transaction " \ 343 + def is_all_stocks_db_check(self,code):
344 + query = "select code from all_stocks " \
336 "where code='%s' and (sell_date ='%s' or sell_date='%s') ORDER BY buy_date desc LIMIT 1" 345 "where code='%s' and (sell_date ='%s' or sell_date='%s') ORDER BY buy_date desc LIMIT 1"
337 rows = self.engine_bot.execute(query % (code, 0, "")).fetchall() 346 rows = self.engine_bot.execute(query % (code, 0, "")).fetchall()
338 if len(rows) != 0: 347 if len(rows) != 0:
...@@ -357,7 +366,6 @@ class open_api(QAxWidget): ...@@ -357,7 +366,6 @@ class open_api(QAxWidget):
357 def comm_rq_data(self,sRQName,sTrData,nPrevNext,sScrNo): 366 def comm_rq_data(self,sRQName,sTrData,nPrevNext,sScrNo):
358 self.exit_check() 367 self.exit_check()
359 ret=self.dynamicCall("CommRqData(QString, QString, int, QString", sRQName, sTrData, nPrevNext, sScrNo) 368 ret=self.dynamicCall("CommRqData(QString, QString, int, QString", sRQName, sTrData, nPrevNext, sScrNo)
360 -
361 if ret==-200: 369 if ret==-200:
362 logger.critical("요청 제한 횟수 초과") 370 logger.critical("요청 제한 횟수 초과")
363 371
...@@ -388,40 +396,39 @@ class open_api(QAxWidget): ...@@ -388,40 +396,39 @@ class open_api(QAxWidget):
388 396
389 # 변수 설정 397 # 변수 설정
390 # 실전투자인지 모의투자인지 여부를 확인하고 그에 해당하는 데이터베이스를 생성하는 함수 398 # 실전투자인지 모의투자인지 여부를 확인하고 그에 해당하는 데이터베이스를 생성하는 함수
391 - def set_variable(self): 399 + def variable_setting(self):
392 logger.debug("-* set variable 함수 *-") 400 logger.debug("-* set variable 함수 *-")
393 - self.cf=cf 401 + self.cf=library.cf
394 self.get_today_buy_list_code=0 402 self.get_today_buy_list_code=0
395 self.reset_opw00018_output() 403 self.reset_opw00018_output()
396 404
397 if self.account_no==self.cf.real_account_no: 405 if self.account_no==self.cf.real_account_no:
398 - logger.debug("실전투자 - 계좌번호 : ",self.account_no) 406 + logger.debug("실전투자 - 계좌번호 : "+self.account_no)
399 self.simul_num=self.cf.real_num 407 self.simul_num=self.cf.real_num
400 - self.set_database(cf.real_bot_name) 408 + self.db_name_setting(self.cf.real_bot_name)
401 self.mod_gubun=100 # 실전투자와 모의투자를 구분하는 변수 409 self.mod_gubun=100 # 실전투자와 모의투자를 구분하는 변수
402 410
403 elif self.account_no==self.cf.test_account_no: 411 elif self.account_no==self.cf.test_account_no:
404 - logger.debug("모의투자 - 계좌번호 : ",self.account_no) 412 + logger.debug("모의투자 - 계좌번호 : "+self.account_no)
405 self.simul_num=self.cf.test_num 413 self.simul_num=self.cf.test_num
406 - self.set_database(cf.test_bot_name) 414 + self.db_name_setting(self.cf.test_bot_name)
407 self.mod_gubun=1 415 self.mod_gubun=1
408 416
409 else: 417 else:
410 logger.debug("Invalid Account Number. Check the Config.py") 418 logger.debug("Invalid Account Number. Check the Config.py")
411 exit(1) 419 exit(1)
412 420
413 - self.jango_is_null=True 421 + self.jango_is_null=True # 더이상 투자할 금액이 남았는지 확인하는 변수
414 - self.py_gubun=False 422 + self.py_gubun=False # collector/trader을 구분하는 변수
415 423
416 # 데이터베이스 생성 및 엔진 설정 424 # 데이터베이스 생성 및 엔진 설정
417 - # -* db_name_setting 425 + def db_name_setting(self,db_name):
418 - def set_database(self,db_name):
419 self.db_name=db_name 426 self.db_name=db_name
420 conn=pymysql.connect( 427 conn=pymysql.connect(
421 - host=cf.db_ip, 428 + host=self.cf.db_ip,
422 - port=int(cf.db_port), 429 + port=int(self.cf.db_port),
423 - user=cf.db_id, 430 + user=self.cf.db_id,
424 - password=cf.db_pw, 431 + password=self.cf.db_pw,
425 charset='utf8mb4', 432 charset='utf8mb4',
426 cursorclass=pymysql.cursors.DictCursor 433 cursorclass=pymysql.cursors.DictCursor
427 ) 434 )
...@@ -430,17 +437,17 @@ class open_api(QAxWidget): ...@@ -430,17 +437,17 @@ class open_api(QAxWidget):
430 self.create_database(cursor) 437 self.create_database(cursor)
431 self.engine_bot = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + 438 self.engine_bot = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" +
432 self.cf.db_ip + ":" + self.cf.db_port + "/" + db_name, encoding='utf-8') 439 self.cf.db_ip + ":" + self.cf.db_port + "/" + db_name, encoding='utf-8')
433 - self.create_basic_database(cursor) 440 + self.basic_db_check(cursor)
434 441
435 conn.commit() 442 conn.commit()
436 conn.close() 443 conn.close()
437 444
438 - self.engine_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 445 + self.engine_craw = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
439 - cf.db_port + "/min_craw",encoding='utf-8') 446 + self.cf.db_port + "/min_craw",encoding='utf-8')
440 - self.engine_daily_craw = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" + 447 + self.engine_daily_craw = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":" +
441 - cf.db_port + "/daily_craw",encoding='utf-8') 448 + self.cf.db_port + "/daily_craw",encoding='utf-8')
442 - self.engine_daily_buy_list = create_engine("mysql+pymysql://" + cf.db_id + ":" + cf.db_pw + "@" + cf.db_ip + ":" 449 + self.engine_daily_buy_list = create_engine("mysql+pymysql://" + self.cf.db_id + ":" + self.cf.db_pw + "@" + self.cf.db_ip + ":"
443 - + cf.db_port + "/daily_buy_list",encoding='utf-8') 450 + + self.cf.db_port + "/daily_buy_list",encoding='utf-8')
444 451
445 event.listen(self.engine_craw,'before_execute',escape_percentage,retval=True) 452 event.listen(self.engine_craw,'before_execute',escape_percentage,retval=True)
446 event.listen(self.engine_daily_craw,'before_execute',escape_percentage,retval=True) 453 event.listen(self.engine_daily_craw,'before_execute',escape_percentage,retval=True)
...@@ -462,8 +469,7 @@ class open_api(QAxWidget): ...@@ -462,8 +469,7 @@ class open_api(QAxWidget):
462 469
463 # daily_craw(종목의 날짜별 데이터), daily_buy_list(날짜별 종목 데이터), min_craw(종목의 분별 데이터) 가 존재하는지 확인하는 함수 470 # daily_craw(종목의 날짜별 데이터), daily_buy_list(날짜별 종목 데이터), min_craw(종목의 분별 데이터) 가 존재하는지 확인하는 함수
464 # 존재하지 않는다면 새로 생성 471 # 존재하지 않는다면 새로 생성
465 - # -* basic_db_check 472 + def basic_db_check(self,cursor):
466 - def create_basic_database(self,cursor):
467 check_list = ['daily_craw', 'daily_buy_list', 'min_craw'] 473 check_list = ['daily_craw', 'daily_buy_list', 'min_craw']
468 query = "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA" 474 query = "SELECT SCHEMA_NAME FROM information_schema.SCHEMATA"
469 cursor.execute(query) 475 cursor.execute(query)
...@@ -478,10 +484,10 @@ class open_api(QAxWidget): ...@@ -478,10 +484,10 @@ class open_api(QAxWidget):
478 cursor.execute(create_db_query.format(check_name)) 484 cursor.execute(create_db_query.format(check_name))
479 485
480 if has_created and self.engine_bot.has_table('setting_data'): 486 if has_created and self.engine_bot.has_table('setting_data'):
481 - self.engine_bot.execute("UPDATE setting_data SET code_update = '0';") 487 + self.engine_bot.execute("UPDATE setting_data SET code_update = '0'")
482 488
483 # setting_data 테이블 생성 및 초기화하는 함수 489 # setting_data 테이블 생성 및 초기화하는 함수
484 - def init_setting_data(self): 490 + def init_db_setting_data(self):
485 logger.debug("-* init_setting_data 함수 *-") 491 logger.debug("-* init_setting_data 함수 *-")
486 492
487 df_setting_data_temp = {'limit_money': [], 'invest_unit': [], 'max_invest_unit': [], 493 df_setting_data_temp = {'limit_money': [], 'invest_unit': [], 'max_invest_unit': [],
...@@ -517,10 +523,10 @@ class open_api(QAxWidget): ...@@ -517,10 +523,10 @@ class open_api(QAxWidget):
517 df_setting_data.loc[0, 'min_crawler'] = str(0) # min_crawler(종목의 분별 데이터) 업데이트 날자 523 df_setting_data.loc[0, 'min_crawler'] = str(0) # min_crawler(종목의 분별 데이터) 업데이트 날자
518 df_setting_data.loc[0, 'daily_buy_list'] = str(0) # daily_buy_list(일별 종목 데이터) 업데이트 날짜 524 df_setting_data.loc[0, 'daily_buy_list'] = str(0) # daily_buy_list(일별 종목 데이터) 업데이트 날짜
519 525
520 - df_setting_data.to_sql('setting_data', self.engine_JB, if_exists='replace') 526 + df_setting_data.to_sql('setting_data', self.engine_bot, if_exists='replace')
521 527
522 - # simulator_fun 에서 설정한 변수를 가져오는 함수 528 + # simulator_api 에서 설정한 변수를 가져오는 함수
523 - def set_simul_variable(self): 529 + def sf_variable_setting(self):
524 logger.debug("-* set simul variable function *-") 530 logger.debug("-* set simul variable function *-")
525 # daily_buy_list에 저장된 가장 최신 날짜 531 # daily_buy_list에 저장된 가장 최신 날짜
526 self.date_rows_yesterday=self.sf.get_recent_daily_buy_list_date() 532 self.date_rows_yesterday=self.sf.get_recent_daily_buy_list_date()
...@@ -531,8 +537,8 @@ class open_api(QAxWidget): ...@@ -531,8 +537,8 @@ class open_api(QAxWidget):
531 logger.debug("all_stocks 테이블을 생성합니다") 537 logger.debug("all_stocks 테이블을 생성합니다")
532 # 테이블 생성 후 초기화 538 # 테이블 생성 후 초기화
533 self.invest_unit=0 539 self.invest_unit=0
534 - self.db_to_transaction(0,0,0,0,0) 540 + self.db_to_all_stocks(0,0,0,0,0)
535 - self.delete_all_stock("0") 541 + self.delete_all_stocks("0")
536 542
537 # setting_data에 invest_unit값이 없다면 설정 543 # setting_data에 invest_unit값이 없다면 설정
538 if not self.check_set_invest_unit(): 544 if not self.check_set_invest_unit():
...@@ -550,15 +556,16 @@ class open_api(QAxWidget): ...@@ -550,15 +556,16 @@ class open_api(QAxWidget):
550 self.sf.init_df_all_stocks() # all_stocks 테이블 데이터프레임 생성 556 self.sf.init_df_all_stocks() # all_stocks 테이블 데이터프레임 생성
551 557
552 # dataframe에 값 할당 558 # dataframe에 값 할당
553 - self.sf.df_transaction.loc[0, 'order_num'] = order_num # 주문번호 559 + self.sf.df_all_stocks.loc[0, 'order_num'] = order_num # 주문번호
554 - self.sf.df_transaction.loc[0, 'code'] = str(code) # 종목코드 560 + self.sf.df_all_stocks.loc[0, 'code'] = str(code) # 종목코드
555 - self.sf.df_transaction.loc[0, 'rate'] = float(rate) # 수익률 561 + self.sf.df_all_stocks.loc[0, 'rate'] = float(rate) # 수익률
556 - self.sf.df_transaction.loc[0, 'buy_date'] = self.today_detail # 구매날짜 562 + self.sf.df_all_stocks.loc[0, 'buy_date'] = self.today_detail # 구매날짜
557 - self.sf.df_all_item.loc[0, 'chegyul_check'] = chegyul_check # 체결확인 563 + self.sf.df_all_stocks.loc[0, 'chegyul_check'] = chegyul_check # 체결확인
558 564
559 - self.sf.df_all_item.loc[0, 'invest_unit'] = self.invest_unit # 투자기준금액 565 + self.sf.df_all_stocks.loc[0, 'invest_unit'] = self.invest_unit # 투자기준금액
560 - self.sf.df_all_item.loc[0, 'purchase_price'] = purchase_price # 구매금액 566 + self.sf.df_all_stocks.loc[0, 'purchase_price'] = purchase_price # 구매금액
561 567
568 + # 신규매수
562 if order_num != 0: 569 if order_num != 0:
563 recent_daily_buy_list_date=self.sf.get_recent_daily_buy_list_date() 570 recent_daily_buy_list_date=self.sf.get_recent_daily_buy_list_date()
564 # 구매 내역이 존재하는 경우 해당 데이터를 추가 571 # 구매 내역이 존재하는 경우 해당 데이터를 추가
...@@ -566,37 +573,36 @@ class open_api(QAxWidget): ...@@ -566,37 +573,36 @@ class open_api(QAxWidget):
566 # 특정 날짜, 특정 종목의 주가 데이터 573 # 특정 날짜, 특정 종목의 주가 데이터
567 df=self.sf.get_daily_buy_list_by_code(code,recent_daily_buy_list_date) 574 df=self.sf.get_daily_buy_list_by_code(code,recent_daily_buy_list_date)
568 if not df.empty: 575 if not df.empty:
569 - self.sf.df_transaction.loc[0, 'code_name'] = df.loc[0, 'code_name'] # 종목명 576 + self.sf.df_all_stocks.loc[0, 'code_name'] = df.loc[0, 'code_name'] # 종목명
570 577
571 - self.sf.df_transaction.loc[0, 'close'] = df.loc[0, 'close'] # 종가 578 + self.sf.df_all_stocks.loc[0, 'close'] = df.loc[0, 'close'] # 종가
572 - self.sf.df_transaction.loc[0, 'open'] = df.loc[0, 'open'] # 시가 579 + self.sf.df_all_stocks.loc[0, 'open'] = df.loc[0, 'open'] # 시가
573 - self.sf.df_transaction.loc[0, 'high'] = df.loc[0, 'high'] # 고가 580 + self.sf.df_all_stocks.loc[0, 'high'] = df.loc[0, 'high'] # 고가
574 - self.sf.df_transaction.loc[0, 'low'] = df.loc[0, 'low'] # 저가 581 + self.sf.df_all_stocks.loc[0, 'low'] = df.loc[0, 'low'] # 저가
575 - self.sf.df_transaction.loc[0, 'volume'] = df.loc[0, 'volume'] # 거래량 582 + self.sf.df_all_stocks.loc[0, 'volume'] = df.loc[0, 'volume'] # 거래량
576 583
577 - self.sf.df_transaction.loc[0,'d1_diff']=float(df.loc[0,'d1_diff']) # 전날대비 가격변동 584 + self.sf.df_all_stocks.loc[0,'d1_diff']=float(df.loc[0,'d1_diff']) # 전날대비 가격변동
578 - self.sf.df_transaction.loc[0, 'd1_diff_rate'] = float(df.loc[0, 'd1_diff_rate']) # 전날대비 가격변동률 585 + self.sf.df_all_stocks.loc[0, 'd1_diff_rate'] = float(df.loc[0, 'd1_diff_rate']) # 전날대비 가격변동률
579 586
580 - self.sf.df_transaction.loc[0, 'clo5'] = df.loc[0, 'clo5'] # 5일 이동평균선 587 + self.sf.df_all_stocks.loc[0, 'clo5'] = df.loc[0, 'clo5'] # 5일 이동평균선
581 - self.sf.df_transaction.loc[0, 'clo10'] = df.loc[0, 'clo10'] # 10일 이동평균선 588 + self.sf.df_all_stocks.loc[0, 'clo10'] = df.loc[0, 'clo10'] # 10일 이동평균선
582 - self.sf.df_transaction.loc[0, 'clo20'] = df.loc[0, 'clo20'] # 20일 이동평균선 589 + self.sf.df_all_stocks.loc[0, 'clo20'] = df.loc[0, 'clo20'] # 20일 이동평균선
583 - self.sf.df_transaction.loc[0, 'clo60'] = df.loc[0, 'clo60'] # 60일 이동평균선 590 + self.sf.df_all_stocks.loc[0, 'clo60'] = df.loc[0, 'clo60'] # 60일 이동평균선
584 - self.sf.df_transaction.loc[0, 'clo120'] = df.loc[0, 'clo120'] # 120일 이동평균선 591 + self.sf.df_all_stocks.loc[0, 'clo120'] = df.loc[0, 'clo120'] # 120일 이동평균선
585 592
586 if df.loc[0, 'clo5_diff_rate'] is not None: 593 if df.loc[0, 'clo5_diff_rate'] is not None:
587 - self.sf.df_transaction.loc[0, 'clo5_diff_rate'] = float(df.loc[0, 'clo5_diff_rate']) # 5일 이동평균선 변동률 594 + self.sf.df_all_stocks.loc[0, 'clo5_diff_rate'] = float(df.loc[0, 'clo5_diff_rate']) # 5일 이동평균선 변동률
588 if df.loc[0, 'clo10_diff_rate'] is not None: 595 if df.loc[0, 'clo10_diff_rate'] is not None:
589 - self.sf.df_transaction.loc[0, 'clo10_diff_rate'] = float(df.loc[0, 'clo10_diff_rate']) 596 + self.sf.df_all_stocks.loc[0, 'clo10_diff_rate'] = float(df.loc[0, 'clo10_diff_rate'])
590 if df.loc[0, 'clo20_diff_rate'] is not None: 597 if df.loc[0, 'clo20_diff_rate'] is not None:
591 - self.sf.df_transaction.loc[0, 'clo20_diff_rate'] = float(df.loc[0, 'clo20_diff_rate']) 598 + self.sf.df_all_stocks.loc[0, 'clo20_diff_rate'] = float(df.loc[0, 'clo20_diff_rate'])
592 if df.loc[0, 'clo60_diff_rate'] is not None: 599 if df.loc[0, 'clo60_diff_rate'] is not None:
593 - self.sf.df_transaction.loc[0, 'clo60_diff_rate'] = float(df.loc[0, 'clo60_diff_rate']) 600 + self.sf.df_all_stocks.loc[0, 'clo60_diff_rate'] = float(df.loc[0, 'clo60_diff_rate'])
594 if df.loc[0, 'clo120_diff_rate'] is not None: 601 if df.loc[0, 'clo120_diff_rate'] is not None:
595 - self.sf.df_transaction.loc[0, 'clo120_diff_rate'] = float(df.loc[0, 'clo120_diff_rate']) 602 + self.sf.df_all_stocks.loc[0, 'clo120_diff_rate'] = float(df.loc[0, 'clo120_diff_rate'])
596 603
597 - # null값을 0으로 변환 604 + self.sf.df_all_stocks = self.sf.df_all_stocks.fillna(0) # null값을 0으로 변환
598 - self.sf.df_all_item = self.sf.df_all_item.fillna(0) 605 + self.sf.df_all_stocks.to_sql('all_stocks', self.engine_bot, if_exists='append', dtype={
599 - self.sf.df_all_item.to_sql('transaction', self.engine_bot, if_exists='append', dtype={
600 'code_name': Text, 606 'code_name': Text,
601 'rate': Float, 607 'rate': Float,
602 'sell_rate': Float, 608 'sell_rate': Float,
...@@ -612,13 +618,13 @@ class open_api(QAxWidget): ...@@ -612,13 +618,13 @@ class open_api(QAxWidget):
612 }) 618 })
613 619
614 # all_stocks(거래내역) 테이블에서 특정 종목을 삭제하는 함수 620 # all_stocks(거래내역) 테이블에서 특정 종목을 삭제하는 함수
615 - def delete_transaction_item(self,code): 621 + def delete_all_stocks(self,code):
616 query=f"delete from all_stocks where code={code}" 622 query=f"delete from all_stocks where code={code}"
617 self.engine_bot.execute(query) 623 self.engine_bot.execute(query)
618 624
619 # setting_data 테이블에 invest_unit이 오늘 업데이트 되었는지 확인 625 # setting_data 테이블에 invest_unit이 오늘 업데이트 되었는지 확인
620 def check_set_invest_unit(self): 626 def check_set_invest_unit(self):
621 - query="select invest_unit, set_invest_unit from setting_data limit 1" 627 + query="select invest_unit,set_invest_unit from setting_data limit 1"
622 result=self.engine_bot.execute(query).fetchall() 628 result=self.engine_bot.execute(query).fetchall()
623 if result[0][1]==self.today: 629 if result[0][1]==self.today:
624 self.invest_unit=result[0][0] 630 self.invest_unit=result[0][0]
...@@ -629,31 +635,32 @@ class open_api(QAxWidget): ...@@ -629,31 +635,32 @@ class open_api(QAxWidget):
629 # 데이터베이스에서 invest_unit값을 가져오는 함수 635 # 데이터베이스에서 invest_unit값을 가져오는 함수
630 def get_invest_unit(self): 636 def get_invest_unit(self):
631 logger.debug("-* get_invest_unit function *-") 637 logger.debug("-* get_invest_unit function *-")
632 - query="select invest_unit from setting_data" 638 + query="select invest_unit from setting_data limit 1"
633 result=self.engine_bot.execute(query).fetchall() 639 result=self.engine_bot.execute(query).fetchall()
634 return result[0][0] 640 return result[0][0]
635 641
636 # invest_unit 항목 업데이트 642 # invest_unit 항목 업데이트
637 # 업데이트 완료 후 set_invest_unit에 업데이트 날짜 저장 643 # 업데이트 완료 후 set_invest_unit에 업데이트 날짜 저장
638 def set_invest_unit(self): 644 def set_invest_unit(self):
639 - self.get_deposit() 645 + self.get_d2_deposit()
640 - self.get_balance() 646 + self.check_balance()
641 - self.total_invest=self.change_format(str(int(self.deposit)+int(self.total_purchase_price))) 647 + self.total_invest=self.change_format(str(int(self.d2_deposit_before_format)+int(self.total_purchase_price)))
642 648
643 self.invest_unit=self.sf.invest_unit 649 self.invest_unit=self.sf.invest_unit
644 query=f"update setting_data set invest_unit='{self.invest_unit}', set_invest_unit='{self.today}'" 650 query=f"update setting_data set invest_unit='{self.invest_unit}', set_invest_unit='{self.today}'"
645 self.engine_bot.execute(query) 651 self.engine_bot.execute(query)
646 652
647 # 예수금 조회 및 저장 653 # 예수금 조회 및 저장
648 - def get_deposit(self): 654 + def get_d2_deposit(self):
649 self.set_input_value("계좌번호",self.account_no) 655 self.set_input_value("계좌번호",self.account_no)
650 self.set_input_value("비밀번호입력매체구분",00) 656 self.set_input_value("비밀번호입력매체구분",00)
651 self.set_input_value("조회구분",1) 657 self.set_input_value("조회구분",1)
652 self.comm_rq_data("opw00001_req","opw00001",0,"2000") 658 self.comm_rq_data("opw00001_req","opw00001",0,"2000")
653 659
654 # 잔고 조회 및 저장 660 # 잔고 조회 및 저장
655 - def get_balance(self): 661 + def check_balance(self):
656 self.reset_opw00018_output() 662 self.reset_opw00018_output()
663 +
657 self.set_input_value("계좌번호",self.account_no) 664 self.set_input_value("계좌번호",self.account_no)
658 self.comm_rq_data("opw00018_req","opw00018",0,"2000") 665 self.comm_rq_data("opw00018_req","opw00018",0,"2000")
659 # 다음페이지가 존재할 경우 계속해서 조회 666 # 다음페이지가 존재할 경우 계속해서 조회
...@@ -669,8 +676,8 @@ class open_api(QAxWidget): ...@@ -669,8 +676,8 @@ class open_api(QAxWidget):
669 'present_price':[],'valuation_profit':[],'rate':[],'item_total_purchase':[]} 676 'present_price':[],'valuation_profit':[],'rate':[],'item_total_purchase':[]}
670 677
671 possessed_item=DataFrame(possessed_item_data, 678 possessed_item=DataFrame(possessed_item_data,
672 - columns=['date','code','code_name','holding_amount','purchase_price', 679 + columns=['date','code','code_name','holding_amount','purchase_price',
673 - 'present_price','valuation_profit','rate','item_total_purchase']) 680 + 'present_price','valuation_profit','rate','item_total_purchase'])
674 681
675 for i in range(item_count): 682 for i in range(item_count):
676 item=self.opw00018_output['multi'][i] 683 item=self.opw00018_output['multi'][i]
...@@ -708,20 +715,20 @@ class open_api(QAxWidget): ...@@ -708,20 +715,20 @@ class open_api(QAxWidget):
708 else: 715 else:
709 chegyul_check=1 716 chegyul_check=1
710 elif self._data['주문구분']=='': 717 elif self._data['주문구분']=='':
711 - self.db_to_transaction(self.today,item.code,0,0,item.rate) 718 + self.db_to_all_stocks(self.today,item.code,0,0,item.rate)
712 continue 719 continue
713 else: 720 else:
714 continue 721 continue
715 722
716 - self.db_to_all_stocks(self.not_contract['주문번호'],item.code,chegyul_check,self.not_contract['체결가'],item.rate) 723 + self.db_to_all_stocks(self._data['주문번호'],item.code,chegyul_check,self._data['체결가'],item.rate)
717 724
718 - # posses_item 테이블을 업데이트 했을 경우 setting data 테이블에 업데이트 한 날짜를 표시 725 + # setting_data에 possessed_item 항목을 업데이트
719 - def setting_data_posses_stock(self): 726 + def setting_data_possessed_item(self):
720 - query="update setting_data set posses_stocks='%s'" 727 + query=f"update setting_data set possessed_item={self.today} limit 1"
721 - self.engine_bot.execute(query%self.today) 728 + self.engine_bot.execute(query)
722 729
723 # 특정 종목의 일자별 거래 데이터 조회 함수 730 # 특정 종목의 일자별 거래 데이터 조회 함수
724 - def get_date_data(self,code,code_name,date): 731 + def get_total_data(self,code,code_name,date):
725 self.ohlcv=defaultdict(list) 732 self.ohlcv=defaultdict(list)
726 self.set_input_value("종목코드",code) 733 self.set_input_value("종목코드",code)
727 self.set_input_value("기준일자",date) 734 self.set_input_value("기준일자",date)
...@@ -730,8 +737,8 @@ class open_api(QAxWidget): ...@@ -730,8 +737,8 @@ class open_api(QAxWidget):
730 # 한번에 600일치의 데이터를 가져온다 737 # 한번에 600일치의 데이터를 가져온다
731 self.comm_rq_data("opt10081_req","opt10081",0,"0101") 738 self.comm_rq_data("opt10081_req","opt10081",0,"0101")
732 739
733 - # stock_info 테이블이 존재하지 않는다면 600일치 이상의 전체 데이터를 가져와야 하므로 다음 페이지가 존재하지 않을 때까지 조회 740 + # 종목 테이블이 존재하지 않는다면 600일치 이상의 전체 데이터를 가져와야 하므로 다음 페이지가 존재하지 않을 때까지 조회
734 - if not self.is_stock_table_exist(code_name): 741 + if not self.is_craw_table_exist(code_name):
735 while self.remained_data==True: 742 while self.remained_data==True:
736 self.set_input_value("종목코드",code) 743 self.set_input_value("종목코드",code)
737 self.set_input_value("기준일자",date) 744 self.set_input_value("기준일자",date)
...@@ -747,20 +754,20 @@ class open_api(QAxWidget): ...@@ -747,20 +754,20 @@ class open_api(QAxWidget):
747 754
748 return df 755 return df
749 756
750 - # stock_info 데이터베이스가 존재하는지 확인하는 함수 757 + # daily_craw 데이터베이스에 종목 테이블이 존재하는지 확인하는 함수
751 - def is_stock_table_exist(self,code_name): 758 + def is_craw_table_exist(self,code_name):
752 - query = "select 1 from information_schema.tables where table_schema ='stock_info' and table_name = '{}'" 759 + query = "select 1 from information_schema.tables where table_schema ='daily_craw' and table_name = '{}'"
753 - result=self.engine_stock.execute(query.format(code_name)).fetchall() 760 + result=self.engine_daily_craw.execute(query.format(code_name)).fetchall()
754 if result: 761 if result:
755 return True 762 return True
756 else: 763 else:
757 return False 764 return False
758 765
759 - # stock_info의 특정 종목 테이블에서 마지막으로 저장된 날짜를 가져오는 함수 766 + # daily_craw의 특정 종목 테이블에서 마지막으로 저장된 날짜를 가져오는 함수
760 # 저장된 데이터가 없다면 '0'문자를 반환 767 # 저장된 데이터가 없다면 '0'문자를 반환
761 - def get_latest_date_from_stock_info(self,code_name): 768 + def get_daily_craw_db_last_date(self,code_name):
762 query="select date from {} order by date desc limit 1" 769 query="select date from {} order by date desc limit 1"
763 - result=self.engine_stock.execute(query.format(code_name)).fetchall() 770 + result=self.engine_daily_craw.execute(query.format(code_name)).fetchall()
764 if len(result): 771 if len(result):
765 return result[0][0] 772 return result[0][0]
766 else: 773 else:
...@@ -768,7 +775,7 @@ class open_api(QAxWidget): ...@@ -768,7 +775,7 @@ class open_api(QAxWidget):
768 775
769 # 체결이 완료되었는지 확인하고 all_stocks(거래내역)테이블을 업데이트 776 # 체결이 완료되었는지 확인하고 all_stocks(거래내역)테이블을 업데이트
770 def check_chegyul(self): 777 def check_chegyul(self):
771 - query="select code from all_stocks where chegyul_check='1' and (sell_date='0' or sell_date=''" 778 + query="select code from all_stocks where chegyul_check='1' and (sell_date='0' or sell_date='')"
772 result=self.engine_bot.execute(query).fetchall() 779 result=self.engine_bot.execute(query).fetchall()
773 780
774 for r in result: 781 for r in result:
...@@ -779,40 +786,24 @@ class open_api(QAxWidget): ...@@ -779,40 +786,24 @@ class open_api(QAxWidget):
779 786
780 query=f"update all_stocks set chegyul_check='0' where code='{r.code}' and sell_data='0' " \ 787 query=f"update all_stocks set chegyul_check='0' where code='{r.code}' and sell_data='0' " \
781 f"order by buy_date desc limit 1" 788 f"order by buy_date desc limit 1"
782 - # 거래가 완료된 항목은 주문번호 등 데이터가 존재하지 않음 789 + # 과거에 거래한 내역이 존재하는 경우 opt10076 조회 시 주문번호 등의 데이터가 존재하지 않음
783 # 거래가 완료된 항목에 대해서 contract_check항목을 '0'으로 업데이트 790 # 거래가 완료된 항목에 대해서 contract_check항목을 '0'으로 업데이트
784 - if not self.not_contract['주문번호']: 791 + if not self._data['주문번호']:
785 self.engine_bot.execute(query) 792 self.engine_bot.execute(query)
786 # 미체결 수량이 없을 경우 contract_check항목을 '0'으로 업데이트 793 # 미체결 수량이 없을 경우 contract_check항목을 '0'으로 업데이트
787 - elif self.not_contract['미체결수량']==0: 794 + elif self._data['미체결수량']==0:
788 logger.debug("미체결 항목이 없습니다") 795 logger.debug("미체결 항목이 없습니다")
789 self.engine_bot.execute(query) 796 self.engine_bot.execute(query)
790 else: 797 else:
791 logger.debug("미체결 종목이 존재합니다") 798 logger.debug("미체결 종목이 존재합니다")
792 799
800 + # 매도한 후, 보유종목(possessed_item) 내역과 거래내역(all_stocks) 내역의 데이터를 맞추는 함수
801 + # 거래내역 테이블에서 매도처리되지 않은 항목을 업데이트
802 + def sell_final_check2(self, code):
803 + query = "UPDATE all_stocks SET " \
804 + "chegyul_check='%s', sell_date ='%s' WHERE code='%s' and sell_date ='%s' ORDER BY buy_date desc LIMIT 1"
793 805
794 - # 매도했을 경우 possessed_item(보유종목) 테이블에서 항목을 삭제 806 + self.engine_bot.execute(query % (0, self.today_detail, code, 0))
795 - def delete_possessed_item(self,code):
796 - query=f"delete from possessed_item where code={code}"
797 - self.engine_bot.execute(query)
798 -
799 - # 매도한 후 all_stocks 테이블 업데이트
800 - def sell_final_check(self,code):
801 - query=f"SELECT valuation_profit, rate, item_total_purchase, present_price FROM possessed_item " \
802 - f"WHERE code='{code}' LIMIT 1"
803 - result=self.engine_bot.execute(query).fetchall()
804 -
805 - if result:
806 - item = result[0]
807 - query=f"update all_stocks set " \
808 - f"item_total_purchase={item.item_total_purchase}, chegyul_check=0, " \
809 - f"sell_date={self.today_time}, valuation_profit={item.valuation_profit}," \
810 - f"sell_rate={item.rate}, sell_price={item.present_price} " \
811 - f"where code='{code}' and sell_date='0' order by buy_date desc limit 1"
812 - self.engine_bot.execute(query)
813 -
814 - # 매도한 항목을 possessed_item(보유종목) 테이블에서 삭제
815 - self.engine_bot.execute(f"DELETE FROM possessed_item WHERE code = '{code}'")
816 807
817 # 매도했을 때, possessed_item에서 삭제되었지만 all_stocks에 sell_date 칼럼이 업데이트 되지 않은 항목들을 처리하는 함수 808 # 매도했을 때, possessed_item에서 삭제되었지만 all_stocks에 sell_date 칼럼이 업데이트 되지 않은 항목들을 처리하는 함수
818 def final_chegyul_check(self): 809 def final_chegyul_check(self):
...@@ -830,25 +821,12 @@ class open_api(QAxWidget): ...@@ -830,25 +821,12 @@ class open_api(QAxWidget):
830 query = f"UPDATE setting_data SET final_chegyul_check='{self.today}' limit 1" 821 query = f"UPDATE setting_data SET final_chegyul_check='{self.today}' limit 1"
831 self.engine_bot.execute(query) 822 self.engine_bot.execute(query)
832 823
833 - # 가지고 있던 종목을 판매하여 posses_item테이블에 내역이 존재하지 않지만 transaction_history에 매도처리가 되지 않은 항목 업데이트
834 - def sell_check(self,code):
835 - query="update transaction_history" \
836 - "set" \
837 - "contract_check='%s', sell_date='%s'" \
838 - "where code='%s' and sell_date='%s'"
839 - self.engine_bot.execute(query%(0,self.today_time,code,0))
840 -
841 # 현재 보유하고 있는 종목의 수를 반환하는 함수 824 # 현재 보유하고 있는 종목의 수를 반환하는 함수
842 def get_count_possessed_item(self): 825 def get_count_possessed_item(self):
843 query="select count(*) from possessed_item" 826 query="select count(*) from possessed_item"
844 result=self.engine_bot.execute(query).fetchall() 827 result=self.engine_bot.execute(query).fetchall()
845 return result[0][0] 828 return result[0][0]
846 829
847 - # setting_data에 possessed_item 항목을 업데이트
848 - def set_setting_data_possessed_item(self):
849 - query=f"update setting_data set possessed_item={self.today} limit 1"
850 - self.engine_bot.execute(query)
851 -
852 # 특정 종목의 틱(1분별) 데이터 조회 함수 830 # 특정 종목의 틱(1분별) 데이터 조회 함수
853 def get_total_data_min(self,code,code_name,start): 831 def get_total_data_min(self,code,code_name,start):
854 self.ohlcv=defaultdict(list) 832 self.ohlcv=defaultdict(list)
...@@ -876,12 +854,18 @@ class open_api(QAxWidget): ...@@ -876,12 +854,18 @@ class open_api(QAxWidget):
876 self.set_input_value("수정주가구분",1) 854 self.set_input_value("수정주가구분",1)
877 self.comm_rq_data("opt10080_req","opt10080",2,"1999") 855 self.comm_rq_data("opt10080_req","opt10080",2,"1999")
878 856
879 - if self.ohlcv['date'][-1]<self.craw_db_last_min: 857 + if self.ohlcv['date'][-1] < self.craw_db_last_min:
880 break 858 break
881 - 859 + """
860 + if self.craw_table_exist:
861 + if self.ohlcv['date'][-1]<self.craw_db_last_min:
862 + break
863 + else:
864 + break
865 + """
882 time.sleep(TR_REQ_TIME_INTERVAL) 866 time.sleep(TR_REQ_TIME_INTERVAL)
883 867
884 - if len(self.ohlcv['date']==0 or self.ohlcv['date'][0]==''): 868 + if len(self.ohlcv['date'])==0 or self.ohlcv['date'][0]=='':
885 return [] 869 return []
886 if self.ohlcv['date']=='': 870 if self.ohlcv['date']=='':
887 return [] 871 return []
...@@ -890,41 +874,6 @@ class open_api(QAxWidget): ...@@ -890,41 +874,6 @@ class open_api(QAxWidget):
890 874
891 return df 875 return df
892 876
893 - # 특정 종목의 일자별 거래 데이터 조회 함수
894 - def get_total_data(self,code,code_name,date):
895 - logger.debug("-* get_total_data function *-")
896 -
897 - self.ohlcv=defaultdict(list)
898 - self.set_input_value("종목코드",code)
899 - self.set_input_value("기준일자",date)
900 - self.set_input_value("수정주가구분",1)
901 -
902 - self.comm_rq_data("opt10081_req","opt10081",0,"0101")
903 -
904 - if not self.is_craw_table_exist(code_name):
905 - while self.remained_data:
906 - self.set_input_value("종목코드", code)
907 - self.set_input_value("기준일자", date)
908 - self.set_input_value("수정주가구분", 1)
909 - self.comm_rq_data("opt10081_req", "opt10081", 2, "0101")
910 -
911 - if len(self.ohlcv)==0:
912 - return []
913 - if self.ohlcv['date']=='':
914 - return []
915 -
916 - df=DataFrame(self.ohlcv,columns=['date','open','high','low','close','volume'])
917 - return df
918 -
919 - # daily_craw 데이터베이스에 {code_name} 테이블이 존재하는지 확인하는 함수
920 - def is_craw_table_exist(self,code_name):
921 - query="select 1 from information_schema.tables where table_schema='daily_craw' and table_name='{}'"
922 - result=self.engine_daily_craw.execute(query.format(code_name))
923 - if result:
924 - return True
925 - else:
926 - return False
927 -
928 # min_craw 데이터베이스에 {code_name} 테이블이 존재하는지 확인하는 함수 877 # min_craw 데이터베이스에 {code_name} 테이블이 존재하는지 확인하는 함수
929 def is_min_craw_table_exist(self,code_name): 878 def is_min_craw_table_exist(self,code_name):
930 query = "select 1 from information_schema.tables where table_schema ='min_craw' and table_name = '{}'" 879 query = "select 1 from information_schema.tables where table_schema ='min_craw' and table_name = '{}'"
...@@ -945,7 +894,7 @@ class open_api(QAxWidget): ...@@ -945,7 +894,7 @@ class open_api(QAxWidget):
945 894
946 # min_craw 테이블에서 마지막에 저장한 행의 시간(분) 정보를 가져오는 함수 895 # min_craw 테이블에서 마지막에 저장한 행의 시간(분) 정보를 가져오는 함수
947 def get_craw_db_last_min(self,code_name): 896 def get_craw_db_last_min(self,code_name):
948 - query = f"SELECT date from `{code_name}` order by date desc limit 1" 897 + query = f"SELECT date from {code_name} order by date desc limit 1"
949 result = self.engine_craw.execute(query).fetchall() 898 result = self.engine_craw.execute(query).fetchall()
950 if len(result): 899 if len(result):
951 return result[0][0] 900 return result[0][0]
...@@ -953,15 +902,6 @@ class open_api(QAxWidget): ...@@ -953,15 +902,6 @@ class open_api(QAxWidget):
953 else: 902 else:
954 return str(0) 903 return str(0)
955 904
956 - # min_craw 테이블에서 마지막에 저장한 행의 날짜 정보를 가져오는 함수
957 - def get_craw_db_last_date(self,code_name):
958 - query = f"SELECT date from `{code_name}` order by date desc limit 1"
959 - result = self.engine_craw.execute(query).fetchall()
960 - if len(result):
961 - return result[0][0]
962 - else:
963 - return str(0)
964 -
965 # 특정 종목의 특정 날짜의 특정 데이터(시가/종가/고가/저가/거래량)를 반환하는 함수 905 # 특정 종목의 특정 날짜의 특정 데이터(시가/종가/고가/저가/거래량)를 반환하는 함수
966 def get_one_day_option_data(self,code,start,option): 906 def get_one_day_option_data(self,code,start,option):
967 self.ohlcv=defaultdict(list) 907 self.ohlcv=defaultdict(list)
...@@ -1040,24 +980,24 @@ class open_api(QAxWidget): ...@@ -1040,24 +980,24 @@ class open_api(QAxWidget):
1040 self.engine_bot.execute(query) 980 self.engine_bot.execute(query)
1041 981
1042 # possessed_item 테이블에 중복으로 데이터가 반영되는 것을 막기 위해 possessed_item에서 해당 종목 삭제 982 # possessed_item 테이블에 중복으로 데이터가 반영되는 것을 막기 위해 possessed_item에서 해당 종목 삭제
1043 - query = f"delete from possessed_item where code ={code}" 983 + query = f"delete from possessed_item where code ='{code}'"
1044 self.engine_bot.execute(query) 984 self.engine_bot.execute(query)
1045 985
1046 - # 잔액이 생겨서 다시 매수할 수 있는 상황이 되었을 경우, setting_data의 today_buy_stop 옵션을 0으로 변경 986 + # 잔액이 생겨서 다시 매수할 수 있는 상황이 되었을 경우, setting_data의 today_buy_stop 옵션을 0으로 변경
1047 - def reset_buy_check(self): 987 + def buy_check_reset(self):
1048 query = "UPDATE setting_data SET today_buy_stop='0' WHERE id='1'" 988 query = "UPDATE setting_data SET today_buy_stop='0' WHERE id='1'"
1049 self.engine_bot.execute(query) 989 self.engine_bot.execute(query)
1050 990
1051 - # 투자 가능한 잔액이 부족하거나, 매수할 종목이 더 이상 없는 경우 setting_data의 today_buy_stop옵션을 0으로 변경 991 + # 투자 가능한 잔액이 부족하거나, 매수할 종목이 더 이상 없는 경우 setting_data의 today_buy_stop 옵션을 당일 날짜로 변경
1052 - # 더이상 매수하지 않음 992 + # today_buy_stop!=0인 경우, 더이상 매수하지 않음
1053 def buy_check_stop(self): 993 def buy_check_stop(self):
1054 query = f"UPDATE setting_data SET today_buy_stop='{self.today}' limit 1" 994 query = f"UPDATE setting_data SET today_buy_stop='{self.today}' limit 1"
1055 self.engine_bot.execute(query) 995 self.engine_bot.execute(query)
1056 996
1057 # 잔액을 확인하는 함수 997 # 잔액을 확인하는 함수
1058 - # 잔액이 부족하여 더이상 투자를 진행할 수 없는 경우, janfo_is_null을 True로 설정한 후 False 반환 998 + # 잔액이 부족하여 더이상 투자를 진행할 수 없는 경우, jango_is_null을 True로 설정한 후 False 반환
1059 - def check_jango(self): 999 + def jango_check(self):
1060 - self.get_deposit() 1000 + self.get_d2_deposit()
1061 try: 1001 try:
1062 if int(self.d2_deposit_before_format) > (int(self.sf.limit_money)): 1002 if int(self.d2_deposit_before_format) > (int(self.sf.limit_money)):
1063 self.jango_is_null = False # trade 루프를 돌다가 잔액이 부족해졌을 때 루프를 빠져나오기 위한 변수 1003 self.jango_is_null = False # trade 루프를 돌다가 잔액이 부족해졌을 때 루프를 빠져나오기 위한 변수
...@@ -1069,10 +1009,10 @@ class open_api(QAxWidget): ...@@ -1069,10 +1009,10 @@ class open_api(QAxWidget):
1069 logger.critical(e) 1009 logger.critical(e)
1070 1010
1071 # today_buy_stop 칼럼을 확인하는 함수 1011 # today_buy_stop 칼럼을 확인하는 함수
1072 - # setting_data테이블의 today_buy_stop 칼럼에 오늘 날짜가 적혀있는 경우 매수 중지 1012 + # setting_data 테이블의 today_buy_stop 칼럼에 오늘 날짜가 적혀있는 경우 매수 중지
1073 def buy_check(self): 1013 def buy_check(self):
1074 query = "select today_buy_stop from setting_data limit 1" 1014 query = "select today_buy_stop from setting_data limit 1"
1075 - result = self.engine_JB.execute(sql).fetchall()[0][0] 1015 + result = self.engine_bot.execute(query).fetchall()[0][0]
1076 1016
1077 if result != self.today: 1017 if result != self.today:
1078 return True 1018 return True
...@@ -1083,7 +1023,7 @@ class open_api(QAxWidget): ...@@ -1083,7 +1023,7 @@ class open_api(QAxWidget):
1083 def buy_num_count(self,invest_unit,present_price): 1023 def buy_num_count(self,invest_unit,present_price):
1084 return int(invest_unit/present_price) 1024 return int(invest_unit/present_price)
1085 1025
1086 - # 거래 함수 1026 + # 매수 함수
1087 def trade(self): 1027 def trade(self):
1088 # 실시간 현재가(close)를 저장 1028 # 실시간 현재가(close)를 저장
1089 # 현재시점의 종가(close)는 현재가와 같다 1029 # 현재시점의 종가(close)는 현재가와 같다
...@@ -1099,22 +1039,23 @@ class open_api(QAxWidget): ...@@ -1099,22 +1039,23 @@ class open_api(QAxWidget):
1099 if min_buy_limit < current_price < max_buy_limit: 1039 if min_buy_limit < current_price < max_buy_limit:
1100 buy_num = self.buy_num_count(self.invest_unit, int(current_price)) 1040 buy_num = self.buy_num_count(self.invest_unit, int(current_price))
1101 logger.debug( 1041 logger.debug(
1102 - "매수+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- code :%s, 목표가: %s, 현재가: %s, 매수량: %s, min_buy_limit: %s, max_buy_limit: %s , invest_limit_rate: %s,예수금: %s , today : %s, today_min : %s, date_rows_yesterday : %s, invest_unit : %s, real_invest_unit : %s +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-", 1042 + "매수 - code :%s, 목표가: %s, 현재가: %s, 매수량: %s, min_buy_limit: %s, max_buy_limit: %s , invest_limit_rate: %s,예수금: %s , today : %s, today_min : %s, date_rows_yesterday : %s, invest_unit : %s, real_invest_unit : %s",
1103 self.get_today_buy_list_code, self.get_today_buy_list_close, current_price, buy_num, min_buy_limit, 1043 self.get_today_buy_list_code, self.get_today_buy_list_close, current_price, buy_num, min_buy_limit,
1104 max_buy_limit, self.sf.invest_limit_rate, self.d2_deposit_before_format, self.today, self.today_detail, 1044 max_buy_limit, self.sf.invest_limit_rate, self.d2_deposit_before_format, self.today, self.today_detail,
1105 self.date_rows_yesterday, self.invest_unit, int(current_price) * int(buy_num)) 1045 self.date_rows_yesterday, self.invest_unit, int(current_price) * int(buy_num))
1106 1046
1107 # 03 시장가 매수 1047 # 03 시장가 매수
1108 # 4번째 parameter: 1: 신규매수 / 2: 신규매도 / 3:매수취소 / 4:매도취소 / 5: 매수정정 / 6:매도정정 1048 # 4번째 parameter: 1: 신규매수 / 2: 신규매도 / 3:매수취소 / 4:매도취소 / 5: 매수정정 / 6:매도정정
1109 - self.send_order("send_order_req", "0101", self.account_number, 1, self.get_today_buy_list_code, buy_num, 0, 1049 + self.send_order("send_order_req", "0101", self.account_no, 1, self.get_today_buy_list_code, buy_num, 0,
1110 "03", "") 1050 "03", "")
1111 1051
1112 # 만약 sf.only_nine_buy가 False 이면, 매도 후에 잔액이 생기면 다시 매수를 시작 1052 # 만약 sf.only_nine_buy가 False 이면, 매도 후에 잔액이 생기면 다시 매수를 시작
1113 # sf.only_nine_buy가 True이면 1회만 매수, 1회 매수 시 잔액이 부족해지면 바로 매수 중단 1053 # sf.only_nine_buy가 True이면 1회만 매수, 1회 매수 시 잔액이 부족해지면 바로 매수 중단
1114 - if not self.jango_check() and self.sf.use_nine: 1054 + if not self.jango_check() and self.sf.only_nine_buy:
1115 # setting_data에 today_buy_stop을 1 로 설정 1055 # setting_data에 today_buy_stop을 1 로 설정
1116 self.buy_check_stop() 1056 self.buy_check_stop()
1117 1057
1058 + # 오늘 매수할 종목 리스트를 가져오는 함수
1118 def get_today_buy_list(self): 1059 def get_today_buy_list(self):
1119 # 구매할 목록을 저장하는 테이블(realtime_daily_buy_list)이 존재하지 않거나, 테이블 내에 항목이 존재하지 않는다면 return 1060 # 구매할 목록을 저장하는 테이블(realtime_daily_buy_list)이 존재하지 않거나, 테이블 내에 항목이 존재하지 않는다면 return
1120 if self.sf.is_simul_table_exist(self.db_name, "realtime_daily_buy_list"): 1061 if self.sf.is_simul_table_exist(self.db_name, "realtime_daily_buy_list"):
...@@ -1145,10 +1086,10 @@ class open_api(QAxWidget): ...@@ -1145,10 +1086,10 @@ class open_api(QAxWidget):
1145 self.trade() 1086 self.trade()
1146 1087
1147 # 모든 매수를 마쳤으면 더이상 매수 하지 않도록 설정 1088 # 모든 매수를 마쳤으면 더이상 매수 하지 않도록 설정
1148 - if self.sf.use_nine: 1089 + if self.sf.only_nine_buy:
1149 self.buy_check_stop() 1090 self.buy_check_stop()
1150 1091
1151 - # 보유하고 있는 종목에 대해 all_stocks(거래내역) 테이블을 업데이트 1092 + # 보유하고 있는 종목에 대해 all_stocks(거래내역) 테이블의 rate(수익률) 관련 칼럼을 업데이트
1152 def rate_check(self): 1093 def rate_check(self):
1153 query = "select code,holding_amount,purchase_price,present_price,valuation_profit,rate,item_total_purchase "\ 1094 query = "select code,holding_amount,purchase_price,present_price,valuation_profit,rate,item_total_purchase "\
1154 "from possessed_item group by code" 1095 "from possessed_item group by code"
...@@ -1159,8 +1100,8 @@ class open_api(QAxWidget): ...@@ -1159,8 +1100,8 @@ class open_api(QAxWidget):
1159 code = result[k][0] 1100 code = result[k][0]
1160 holding_amount = result[k][1] 1101 holding_amount = result[k][1]
1161 purchase_price = result[k][2] 1102 purchase_price = result[k][2]
1162 - present_price =result[k][3] 1103 + present_price = result[k][3]
1163 - valuation_profit=result[k][4] 1104 + valuation_profit = result[k][4]
1164 rate = result[k][5] 1105 rate = result[k][5]
1165 item_total_purchase = result[k][6] 1106 item_total_purchase = result[k][6]
1166 1107
...@@ -1171,24 +1112,6 @@ class open_api(QAxWidget): ...@@ -1171,24 +1112,6 @@ class open_api(QAxWidget):
1171 f"where code='{code}' and sell_date = '0'" 1112 f"where code='{code}' and sell_date = '0'"
1172 self.engine_bot.execute(query) 1113 self.engine_bot.execute(query)
1173 1114
1174 - # 매도 후 possessed_item(보유종목) 테이블에는 없지만,
1175 - # all_stocks(거래내역) 테이블에 sell_date가 업데이트되지 않은 항목을 처리하는 함수
1176 - def sell_final_check2(self,code):
1177 - query = f"UPDATE all_stocks SET chegyul_check='0', sell_date ='{self.today_time}' " \
1178 - f"WHERE code='{code}' and sell_date ='0' ORDER BY buy_date desc LIMIT 1"
1179 - self.engine_bot.execute(query)
1180 -
1181 - # all_stocks(거래내역) 테이블에서 현재 보유중인 종목이 존재하는지 확인하는 함수
1182 - def is_all_stock_check(self,code):
1183 - query = f"select code from all_stocks where code='{code}' and (sell_date ='0' or sell_date='') " \
1184 - f"ORDER BY buy_date desc LIMIT 1"
1185 - result=self.engine_bot.execute(query).fetchall()
1186 - if len(result) != 0:
1187 - return True
1188 - else:
1189 - return False
1190 -
1191 -
1192 # 주식일봉차트조회 요청 함수 - 하나의 데이터만 저장 1115 # 주식일봉차트조회 요청 함수 - 하나의 데이터만 저장
1193 def _opt10081(self, sRQName, sTrCode): 1116 def _opt10081(self, sRQName, sTrCode):
1194 code = self._get_comm_data(sTrCode, sRQName, 0, "종목코드") 1117 code = self._get_comm_data(sTrCode, sRQName, 0, "종목코드")
...@@ -1313,8 +1236,11 @@ class open_api(QAxWidget): ...@@ -1313,8 +1236,11 @@ class open_api(QAxWidget):
1313 1236
1314 for key in outputs: 1237 for key in outputs:
1315 if key not in ['주문번호','원주문번호','주문시간','종목코드']: 1238 if key not in ['주문번호','원주문번호','주문시간','종목코드']:
1316 - self._data[key]=int(self._get_comm_data(sTrCode,sRQName,0,key)) 1239 + try:
1317 - continue 1240 + self._data[key]=int(self._get_comm_data(sTrCode,sRQName,0,key))
1241 + continue
1242 + except ValueError:
1243 + pass
1318 self._data[key]=self._get_comm_data(sTrCode,sRQName,0,key) 1244 self._data[key]=self._get_comm_data(sTrCode,sRQName,0,key)
1319 1245
1320 # _opt10073 결과를 담는 변수를 초기화하는 함수 1246 # _opt10073 결과를 담는 변수를 초기화하는 함수
...@@ -1359,12 +1285,11 @@ class open_api(QAxWidget): ...@@ -1359,12 +1285,11 @@ class open_api(QAxWidget):
1359 # 데이터베이스로부터 보유하고 있는 종목의 보유량(holding amount)을 가져오는 함수 1285 # 데이터베이스로부터 보유하고 있는 종목의 보유량(holding amount)을 가져오는 함수
1360 def get_holding_amount(self,code): 1286 def get_holding_amount(self,code):
1361 logger.debug("-* get_holding_amount function *-") 1287 logger.debug("-* get_holding_amount function *-")
1362 - query=f"select holding_amount from possessed_item where code={code}" 1288 + query=f"select holding_amount from possessed_item where code='{code}'"
1363 result=self.engine_bot.execute(query).fetchall() 1289 result=self.engine_bot.execute(query).fetchall()
1364 if len(result): 1290 if len(result):
1365 return result[0][0] 1291 return result[0][0]
1366 else: 1292 else:
1367 - logger.debug("Holding amount is empty.")
1368 return False 1293 return False
1369 1294
1370 # open_api로부터 받아온 데이터의 형식을 변형하는 함수 1295 # open_api로부터 받아온 데이터의 형식을 변형하는 함수
...@@ -1426,9 +1351,9 @@ class open_api(QAxWidget): ...@@ -1426,9 +1351,9 @@ class open_api(QAxWidget):
1426 self.rq_count+=1 1351 self.rq_count+=1
1427 1352
1428 logger.debug(self.rq_count) 1353 logger.debug(self.rq_count)
1429 - if self.rq_count==cf.max_api_call: 1354 + if self.rq_count==self.cf.max_api_call:
1430 sys.exit(1) 1355 sys.exit(1)
1431 1356
1432 if __name__=="__main__": 1357 if __name__=="__main__":
1433 app=QApplication(sys.argv) 1358 app=QApplication(sys.argv)
1434 - a=Open_Api()
...\ No newline at end of file ...\ No newline at end of file
1359 + a=open_api()
...\ No newline at end of file ...\ No newline at end of file
......
1 -from PyQt5.QtWidgets import *
2 -from PyQt5.QAxContainer import *
3 -from PyQt5.QtCore import *
4 -from PyQt5.QtTest import *
5 -from pandas import DataFrame
6 -import sys
7 -import errCode
8 -
9 -TR_REQ_TIME_INTERVAL = 3600
10 -
11 -class OpenApi(QAxWidget):
12 - def __init__(self):
13 - super().__init__()
14 -
15 - # event_loop list
16 - self.tr_event_loop=QEventLoop()
17 - self.login_event_loop=QEventLoop()
18 -
19 - # variable list
20 - self.account_no=None # 계좌번호
21 - self.ohlcv = None # 거래정보(시가,종가,고가,저가,거래량)
22 - self.remained_data=None # 다음페이지 존재여부
23 -
24 - # screen number list
25 - self.screen_data_req="0101" # 거래 데이터
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,"거래량")
45 -
46 - self.ohlcv['date'].append(date)
47 - self.ohlcv['open'].append(int(open))
48 - self.ohlcv['high'].append(int(high))
49 - self.ohlcv['low'].append(int(low))
50 - self.ohlcv['close'].append(int(close))
51 - self.ohlcv['volumn'].append(int(volume))
52 -
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
80 -
81 - try:
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
165 - except Exception as e:
166 - print(e)
167 - sys.exit()
168 -
169 - # 키움 api를 사용하기 위한 ocx controller 저장
170 - def create_instance(self):
171 - try:
172 - self.setControl("KHOPENAPI.KHOpenAPICtrl.1")
173 - except Exception as e:
174 - print(e)
175 - sys.exit()
176 -
177 - # event처리를 위한 slot
178 - def _signal_slots(self):
179 - try:
180 - self.OnEventConnect.connect(self._login_slot)
181 - self.OnReceiveTrData.connect(self._receive_tr_data)
182 - except Exception as e:
183 - print(e)
184 - sys.exit()
185 -
186 - # 수동 로그인설정인 경우 로그인창을 출력해서 로그인을 시도
187 - # 자동로그인 설정인 경우 로그인창 출력없이 로그인을 시도
188 - def comm_connect(self):
189 - try:
190 - self.dynamicCall("CommConnect()")
191 - self.login_event_loop.exec_()
192 - except Exception as e:
193 - print(e)
194 - sys.exit()
195 -
196 - # 로그인 이벤트 처리 slot
197 - # param : code - 로그인 성공 시 0
198 - # 실패 시 에러코드 출력
199 - def _login_slot(self,code):
200 - try:
201 - result=errCode.errors(code)
202 - if code==0:
203 - print("Connected",result[1])
204 - else:
205 - print("Failed to connect",result[1])
206 - self.login_event_loop.exit()
207 - except Exception as e:
208 - print(e)
209 - sys.exit()
210 -
211 - # 조회요청시 TR의 Input값을 지정하는 함수
212 - # param : sId - TR에 명시된 Input이름
213 - # svalue - Input이름으로 지정한 값
214 - def _set_input_value(self,sId,sValue):
215 - try:
216 - self.dynamicCall("SetInputValue(QString, QString)", sId, sValue)
217 - except Exception as e:
218 - print(e)
219 - sys.exit()
220 -
221 - # 조회요청함수
222 - # param : sRQName - 사용자 구분명
223 - # sTrCode - 조회하려는 TR이름
224 - # nPrevNext - 연속조회여부
225 - # sScreenNo - 화면번호
226 - def _comm_rq_data(self,sRQName,sTrData,nPrevNext,sScrNo):
227 - self.dynamicCall("CommRqData(QString, QString, int, QString", sRQName, sTrData, nPrevNext, sScrNo)
228 - self.tr_event_loop.exec_()
229 -
230 - # OnReceiveTRData()이벤트가 호출될때 조회데이터를 얻어오는 함수
231 - # param : sTrCode - TR 이름
232 - # sRecordName - 레코드이름
233 - # nIndex - TR반복부
234 - # sItemName - TR에서 얻어오려는 출력항목이름
235 - def _get_comm_data(self,sTrCode,sRecordName,nIndex,sItemName):
236 - ret = self.dynamicCall("GetCommData(QString, QString, int, QString", sTrCode, sRecordName, nIndex, sItemName)
237 - return ret.strip()
238 -
239 - # 조회수신한 멀티데이터의 갯수(반복)을 얻는다
240 - # param : sTrCode - tr이름
241 - # sRecordName - 레코드 이름
242 - def _get_repeat_cnt(self,sTrCode,sRecordName):
243 - try:
244 - ret=self.dynamicCall("GetRepeatCnt(QString, QString)",sTrCode,sRecordName)
245 - return ret
246 - except Exception as e:
247 - print(e)
248 - sys.exit()
249 -
250 -if __name__ == "__main__":
251 - app = QApplication(sys.argv)
252 - OpenApi()
...\ No newline at end of file ...\ No newline at end of file