이하영

collector 추가

1 +import pymysql
2 +pymysql.install_as_MySQLdb()
3 +import sys
4 +
5 +from library.collector_api import *
6 +
7 +class Collector:
8 + def __init__(self):
9 + self.collector_api=collector_api()
10 +
11 + def collecting(self):
12 + self.collector_api.code_update_check()
13 +
14 +if __name__=="__main__":
15 + app=QApplication(sys.argv)
16 + c=Collector()
17 + c.collecting()
...\ No newline at end of file ...\ No newline at end of file
1 -import pymysql
2 -
3 -pymysql.install_as_MySQLdb()
4 -
5 -class Collector:
6 - def __init__(self):
...\ No newline at end of file ...\ No newline at end of file
1 -def errors(err_code):
2 - err_dict={0:('OP_ERR_NONE','정상처리'),
3 - -10:('OP_ERR_FAIL','실패'),
4 - -100:('OP_ERR_LOGIN','사용자정보교환실패'),
5 - -101:('OP_ERR_CONNECT','서버접속실패'),
6 - -102:('OP_ERR_VERSION','버전처리실패'),
7 - -103:('OP_ERR_FAIRWALL','개인방화벽실패'),
8 - -104:('OP_ERR_MEMORY','메모리보호실패'),
9 - -105:('OP_ERR_INPUT','함수입력값오류'),
10 - -106:('OP_ERR_SOCKET_CLOSED','통신연결종료'),
11 - -200:('OP_ERR_SISE_OVERFLOW','시세조회과부화'),
12 - -201:('OP_ERR_RQ_STRUCT_FAIL','전문작성초기화실패'),
13 - -202:('OP_ERR_RQ_STRING_FAIL','전문작성입력값오류'),
14 - -203:('OP_ERR_NO_DATA','데이터없음'),
15 - -204:('OP_ERR_OVER_MAX_DATA','조회가능한종목수초과'),
16 - -205:('OP_ERR_DATA_RCV_FAIL','데이터수신실패'),
17 - -206:('OP_ERR_OVER_MAX_FID','조회가능한FID수초과'),
18 - -207:('OP_ERR_REAL_CANCEL','실시간해제오류'),
19 - -300:('OP_ERR_ORD_WRONG_INPUT','입력값오류'),
20 - -301:('OP_ERR_ORD_WRONG_ACCNO','계좌비밀번호없음'),
21 - -302:('OP_ERR_OTHER_ACC_USE','타인계좌사용오류'),
22 - -303:('OP_ERR_MIS_2BILL_EXC','주문가격이20억원을초과'),
23 - -304:('OP_ERR_MIS_5BILL_EXC','주문가격이50억원을초과'),
24 - -305:('OP_ERR_MIS_1PER_EXC','주문수량이총발행주수의1 % 초과오류'),
25 - -306:('OP_ERR_MIS_3PER_EXC','주문수량이총발행주수의3 % 초과오류'),
26 - -307:('OP_ERR_SEND_FAIL','주문전송실패'),
27 - -308:('OP_ERR_ORD_OVERFLOW','주문전송과부화'),
28 - -309:('OP_ERR_MIS_300CNT_EXC','주문수량300계약초과'),
29 - -310:('OP_ERR_MIS_500CNT_EXC','주문수량500계약초과'),
30 - -340:('OP_ERR_ORD_WRONG_ACCINFO','계좌정보없음'),
31 - -500:('OP_ERR_ORD_SYMCODE_EMPTY','종목코드없음')
32 - }
33 -
34 - result=err_dict[err_code]
35 - return result
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
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=""
......
This diff is collapsed. Click to expand it.
...@@ -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
......
This diff is collapsed. Click to expand it.
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