Showing
16 changed files
with
653 additions
and
952 deletions
proj/collector.py
0 → 100644
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 |
proj/data_collector.py
deleted
100644 → 0
proj/errCode.py
deleted
100644 → 0
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
proj/library/__pycache__/cf.cpython-37.pyc
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
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 | ... | ... |
proj/open_api.py
deleted
100644 → 0
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 |
-
Please register or login to post a comment