class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) #self.show() ######################################################################### # Load Class self.kiwoom = Kiwoom() self.kiwoom.comm_connect() #self.holicAgent = holic_agent.HolicAgent() self.mholicstock = modelholicstock.ModelHolicStock() self.server = self.kiwoom.getLoginInfo("GetServerGubun") if len(self.server) == 0 or self.server != "1": self.serverGubun = "==== PROD ====" else: self.serverGubun = "DEV" ######################################################################### #메인 타이머 self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) # Timer auto 실행 self.timer_auto = QTimer(self) self.timer_auto.start(1000 * 10) self.timer_auto.timeout.connect(self.timer_auto_timeout) accouns_num = int(self.kiwoom.getLoginInfo("ACCOUNT_CNT")) accounts = self.kiwoom.getLoginInfo("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.accountComboBox.addItems(accounts_list) ######################################################################### # Event Callback connect self.pushButton.clicked.connect(self.send_order) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton_2.clicked.connect(self.check_balance) self.btn_autoorder.clicked.connect(self.start_auto_order) self.btn_stopautoorder.clicked.connect(self.stop_auto_order) self.btn_start_mon.clicked.connect(self.automated_stock_mon) self.btn_start_analysis.clicked.connect(self.analysis_condition) ######################################################################### # 메인 변수 self.df_condition = pd.DataFrame() self.df_anaysis = pd.DataFrame() ##################################################################################################### Analisys def automated_stock_mon(self): ''' DB에 저장된 항목 / 조건검색 항목 DB 저장. :return: ''' print("[automated_stock_mon]") #df_minute_data = self.kiwoom.get_min_chart("039490", "5") #print(df_minute_data) # CONDITIN 종목에 대한 정보 확보 self.kiwoom.get_condition() for idx in range(len(self.kiwoom.condition_name_list)): #print(self.kiwoom.condition_name_list[idx]) if self.kiwoom.condition_name_list[idx] != '': self.kiwoom.send_condition(idx) print("#### total condition list : " + self.kiwoom.conditionStockItem) # 학습 대상 선정 ''' 매수가 완료된 종목에 대한 변동이 필요함. ''' # stock list 획득 #self.mystock_list = self.mholicstock.read_my_stock('buy') #print("#### total mystock list : " + self.mystock_list) # [0. 조건검색 결과 + 저장된 리스트 ] #for j in range(len(self.mystock_list)): # self.kiwoom.conditionStockItem += str(self.mystock_list[j][0]) + ';' #print(self.kiwoom.conditionStockItem) # [1. kiwoom get DATA ] self.kiwoom.comm_kw_rq_data(self.kiwoom.conditionStockItem) # [2. 조회된 데이타에 대한 DATA 분석 ret=df ] self.df_condition = pd.DataFrame.from_dict( self.kiwoom.automatedStockDict, orient='index') print(self.df_condition) #print(self.df_main_list.loc[:, ['code']].to_dict() ) # [3. Display Qt MainTableWidget ] dict_count = len(self.kiwoom.automatedStockDict) header_list = [ 'signal', 'weight', 'name', 'cprice', 'updown', 'rate', 'volume', 'code', 'date' ] column_idx_lookup = { header_list[i]: i for i in range(0, len(header_list)) } #column_idx_lookup = {'date': 0, 'code': 1, 'name': 2, 'cprice': 3, 'updown': 4, 'rate': 5, 'volume': 6} #print(column_idx_lookup) self.tableAutomatedStock.setColumnCount(len(header_list)) self.tableAutomatedStock.setRowCount(dict_count) self.tableAutomatedStock.setHorizontalHeaderLabels(header_list) if not isinstance(self.kiwoom.automatedStockDict, collections.Iterable): raise ParameterTypeError() #print("loop start ") for row, stocK_value in enumerate( self.kiwoom.automatedStockDict.items()): #print(stocK_value[1]) for key, value in stocK_value[1].items(): #print("key : {}, value: {}".format(key, value)) col = column_idx_lookup[key] item = QTableWidgetItem(value) if key == 'name': item.setTextAlignment(Qt.AlignVCenter | Qt.AlignLeft) else: item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableAutomatedStock.setItem(row, col, item) self.tableAutomatedStock.resizeRowsToContents() self.tableAutomatedStock.resizeColumnsToContents() def analysis_condition(self): # [3. 각종목에 대한 분봉 데이타 획득 1분 / 3분 / 5분 ] for index, row in self.df_condition.iterrows(): print(row['name'], row['code']) self.df_anaysis = self.kiwoom.get_min_chart(row['code'], '5') self.df_anaysis['code'] = row['code'] #print(self.df_anaysis) #sself.mholicstock.insert_stock_data(self.df_anaysis) prep_data = data_manager.preprocess(self.df_anaysis) print(prep_data) ############################################################### # 자동주문 및 수동 주문 # ############################################################### def init_auto_order(self): self.selectedCondition = '' #선택된 조건식 self.profit_Rate = '' #이익률 self.loss_Rate = '' #손절률 self.limit_Buying_Per_Stock = '' #종목당 매수금액 self.limit_Buying_Stock_Number = '' #매입 제한 종목개수 # 한번의 주문이 진행 되고 나면 다시 셋팅 하는 과정을 가져감. # 예수금상세현황요청을 하여야 하는지 종목 갯수에 대한 확인을 진행 해야 하는지 def start_auto_order(self): # 자동 주문 print("[ start_auto_order ]") print(self.df_machined_stock_item) # 시간에 따라 타임 아웃 나올때 마다 주문 프로세스를 호출함. self.isAutomaticOrder = True def stop_auto_order(self): print("[ stop_auto_order ] Finished Order... ") self.isAutomaticOrder = False def set_auto_order_stocks(self): fileList = ["buy_list.txt", "sell_list.txt"] automatedStocks = [] try: for file in fileList: # utf-8로 작성된 파일을 # cp949 환경에서 읽기위해서 encoding 지정 with open(file, 'rt', encoding='utf-8') as f: stocksList = f.readlines() automatedStocks += stocksList except Exception as e: e.msg = "setAutomatedStocks() 에러" self.showDialog('Critical', e) return # 테이블 행수 설정 cnt = len(automatedStocks) self.automatedStocksTable.setRowCount(cnt) # 테이블에 출력 for i in range(cnt): stocks = automatedStocks[i].split(';') for j in range(len(stocks)): if j == 1: name = self.kiwoom.getMasterCodeName(stocks[j].rstrip()) item = QTableWidgetItem(name) else: item = QTableWidgetItem(stocks[j].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.automatedStocksTable.setItem(i, j, item) self.automatedStocksTable.resizeRowsToContents() def send_order(self): order_type_lookup = {'신규매수': 1, '신규매도': 2, '매수취소': 3, '매도취소': 4} hoga_lookup = {'지정가': "00", '시장가': "03"} account = self.accountComboBox.currentText() order_type = self.comboBox_2.currentText() code = self.lineEdit.text() hoga = self.comboBox_3.currentText() num = self.spinBox.value() price = self.spinBox_2.value() self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "") # 성공 여부에 대한 확인도 필요 self.reset_order() def reset_order(self): print("#### reset order ") self.accountComboBox.setCurrentIndex(0) self.comboBox_2.setCurrentIndex(0) self.lineEdit.setText('') self.comboBox_3.setCurrentIndex(0) self.spinBox.setValue(0) self.spinBox_2.setValue(0) ############################################################### # 예수금 및 보유 종목 정보 ############################################################### def check_balance(self): print("#### cb_check_balance called.") self.kiwoom.reset_opw00018_output() account_number = self.kiwoom.getLoginInfo("ACCNO") account_number = account_number.split(';')[0] self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(0.2) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") # opw00001 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") # balance item = QTableWidgetItem(self.kiwoom.d2_deposit) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, 0, item) for i in range(1, 6): item = QTableWidgetItem(self.kiwoom.opw00018_output['single'][i - 1]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, i, item) self.tableWidget.resizeRowsToContents() self.tableWidget.resizeColumnsToContents() # Item list item_count = len(self.kiwoom.opw00018_output['multi']) self.tableWidget_2.setRowCount(item_count) for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] for i in range(len(row)): item = QTableWidgetItem(row[i]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget_2.setItem(j, i, item) self.tableWidget_2.resizeRowsToContents() self.tableWidget_2.resizeColumnsToContents() ############################################################### # 공통함수 # ############################################################### def code_changed(self): code = self.lineEdit.text() name = self.kiwoom.get_master_code_name(code) self.lineEdit_2.setText(name) def timeout(self): """ 타임아웃 이벤트가 발생하면 호출되는 메서드 """ current_time = QTime.currentTime() text_time = current_time.toString("hh:mm:ss") time_msg = "현재시간: " + text_time state = self.kiwoom.GetConnectState() if state == 1: state_msg = "server connected" else: state_msg = "not connected" self.statusbar.showMessage(state_msg + " | " + time_msg) def timer_auto_timeout(self): print('time_auto ---- ') if self.checkBox.isChecked(): self.check_balance()
class Form(QtWidgets.QDialog): def __init__(self, parent=None): QtWidgets.QDialog.__init__(self, parent) self.ui = uic.loadUi("mainwindow.ui") self.time_start = 0 self.time_end = 0 self.upperLimit = 0 self.lowerLimit = 0 self.data = None # 주식 table self.item = 0 self.kiwoom = Kiwoom() # 함수 바인딩 부분 self.ui.btnStart.clicked.connect(self.start) # 인공지능 투자 실행 self.ui.btnEnd.clicked.connect(self.end) # 인공지능 투자 종료 self.ui.btnAccountInfo.clicked.connect( self.check_balance) # 계좌 정보 가져오기 self.ui.btnSellPriceApply.clicked.connect(self.sellPriceApply) self.ui.btnSellPriceCancel.clicked.connect(self.sellPriceCancel) self.ui.actionLogIn.triggered.connect(self.login) self.ui.actionLogOut.triggered.connect(self.logout) self.ui.actionLogState.triggered.connect(self.logState) self.ui.show() # self.ui.previewSmall.setPixmap(QPixmap('cat04_256.png')) def check_balance(self): self.kiwoom.reset_opw00018_output() account_number = self.kiwoom.get_login_info('ACCNO') # 계좌번호를 가져옴 account_number = account_number.split(';')[0] #가져온 계좌번호를 통해 보유하고 있는 종목을 가져오 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(0.2) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") #현재 내 계좌 현황 self.item = self.kiwoom.opw00018_output['single'] self.ui.lblTotalBuy.setText(self.item[0]) self.ui.lblTotalEvaluation.setText(self.item[1]) self.ui.lblEvalProfit.setText(self.item[2]) self.ui.lblEvalProfitRatio.setText(self.item[3]) self.ui.lblTotalAssets.setText(self.item[4]) self.ui.lblRemainAssets.setText(str(self.item[5])) #보유 주식에 대한 정보 출력 item_count = len(self.kiwoom.opw00018_output['multi']) self.ui.tblWgtTable.setRowCount(item_count) for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] for i in range(len(row)): item = QTableWidgetItem(row[i]) #item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.ui.tblWgtTable.setItem(j, i, item) self.ui.tblWgtTable.resizeRowsToContents() def start(self): now = datetime.datetime.now().strftime('%Y%m%d') self.data = self.getData("038160", now) # 데이터 얻어오기 print(self.data) print('Done') result = self.analysis() # 분석(LSTM) self.trade_stocks() # 매입 요청 self.monitoring() # TODO: 멀티쓰레딩으로 구현하기. 적정 주가 매도 def end(self): # TODO: monitoring을 종료시키기 self.ui.lblRunningTime.setText('0:00:00') #개인 계좌 정보 및 보유 주식목록 가져오기 def getData(self, code, start): self.kiwoom.ohlcv = { 'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': [] } self.kiwoom.set_input_value("종목코드", code) # 가져오고자 하는 종목에 대한 종목코드 self.kiwoom.set_input_value("기준일자", start) # 가자오고자 하는 종목의 일자 self.kiwoom.set_input_value("수정주가부분", 1) self.kiwoom.comm_rq_data("opt10081_req", "opt10081", 0, "0101") time.sleep(0.2) #tr요청시 0.2초 간격을 주기 위해 사용 df = DataFrame(self.kiwoom.ohlcv, columns=['open', 'high', 'low', 'close', 'volume'], index=self.kiwoom.ohlcv['date']) df.to_csv(code + '.csv') return df def analysis(self): BUFSIZE = 2**30 # about 1 GB async def tcp_echo_client(message): reader, writer = await asyncio.open_connection('127.0.0.1', 13513) print(f'Send: {message!r}') # writer.write(message.encode()) self.data.to_csv('./code_tests/data.csv') # 파일을 먼저 저장해준 다음 with open('./code_tests/data.csv', 'rb') as f: d = f.read() writer.write(d) # 저장된 메세지만 날리기 data = await reader.read(BUFSIZE) print(f'Received: {data.decode()!r}') print('Close the connection') writer.close() asyncio.run(tcp_echo_client('Hello World!')) def trade_stocks(self): hoga_lookup = {'지정가': "00", '시장가': "03"} #주식 거래 시 필요한 계좌번호 추출 account = self.kiwoom.get_login_info('ACCNO') # 계좌번호를 가져옴 account = account.split(';')[0] self.check_balance() remain_deposit = self.item[5] f = open("buy_list.txt", "rt") total_list = f.readlines() f.close() row_count = len(total_list) for j in range(row_count): row_data = total_list[j] split_row_data = row_data.split(';') if float(split_row_data[2]) > 0: code = split_row_data[0] hoga = '시장가' self.kiwoom.set_input_value("종목코드", code) price = self.kiwoom._opt10001("opt_10001_req", "opt10001") num = int(int(remain_deposit) / int(price)) self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, 0, hoga_lookup[hoga], "") def analysis(self): #TODO: 기본적으로 LSTM pass #TODO: 내일하기 def buy(self): res = self.kiwoom.dynamicCall("GetLoginInfo(\"USER_NAME\")") print(res) # pass def monitoring(self): self.monitoringThread = MonitoringThread() # 쓰레드 생성 self.ui.btnEnd.clicked.connect(self.monitoringThread.terminate) self.monitoringThread.sigUpdate.connect(self.updated) self.monitoringThread.start() # 쓰레드 시작 def updated(self, duringTime): self.ui.lblRunningTime.setText("%s" % datetime.timedelta(seconds=duringTime)) def sellPriceApply(self): self.upperLimit = self.ui.txtUpperLimit.text() self.lowerLimit = self.ui.txtLowerLimit.text() QMessageBox.about(self, "판매가 설정", "적용되었습니다.") def sellPriceCancel(self): self.ui.txtUpperLimit.setText('') self.ui.txtLowerLimit.setText('') def login(self): # self.kiwoom = QAxWidget("KHOPENAPI.KHOpenAPICtrl.1") self.kiwoom.comm_connect() def logout(self): pass def logState(self): ret = self.kiwoom.dynamicCall("GetConnectState()") _logState = "로그인 되어 있습니다." if ret else "로그인 되어 있지 않습니다." QMessageBox.about(self, "로그인 상태", _logState)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) #인스턴스 생성 후 로그인 self.kiwoom = Kiwoom() self.kiwoom.comm_connect() #1초타이머 self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) #10초 타이머 self.timer2 = QTimer(self) self.timer2.start(10000) self.timer2.timeout.connect(self.timeout2) #계좌수 및 계좌번호 accounts_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accounts_num] #UI에 기능추가 self.comboBox.addItems(accounts_list) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton.clicked.connect(self.send_order) self.pushButton_2.clicked.connect(self.check_balance) #라인에딧의 텍스트 받아와 라인에딧2에 종목명 출력 def code_changed(self): code = self.lineEdit.text() name = self.kiwoom.get_master_code_name(code) self.lineEdit_2.setText(name) #주문요청 def send_order(self): order_type_lookup = {'신규매수':1, '신규매도':2, '매수취소':3, '매도취소':4} hoga_lookup = {'지정가': "00", '시장가': "03"} account = self.comboBox.currentText() order_type = self.comboBox_2.currentText() code = self.lineEdit.text() hoga = self.comboBox_3.currentText() num = self.spinBox.Value() price = self.spinBox_2.value() self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "") #현 계좌/투자정보 조회 def check_balance(self): self.kiwoom.reset_opw00018_output() account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(0.2) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") # opw00001 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") # balance item = QTableWidgetItem(self.kiwoom.d2_deposit) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, 0, item) for i in range(1, 6): item = QTableWidgetItem(self.kiwoom.opw00018_output['single'][i - 1]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, i, item) self.tableWidget.resizeRowsToContents() # Item list item_count = len(self.kiwoom.opw00018_output['multi']) self.tableWidget_2.setRowCount(item_count) for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] for i in range(len(row)): item = QTableWidgetItem(row[i]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget_2.setItem(j, i, item) self.tableWidget_2.resizeRowsToContents() def timeout(self): current_time = QTime.currentTime() text_time = current_time.toString("hh:mm:ss") time_msg = "현재시간: " + text_time state = self.kiwoom.get_connect_state() if state == 1: state_msg = "서버 연결 중" else: state_msg = "서버 미 연결 중" self.statusbar.showMessage(state_msg + " | " + time_msg) def timeout2(self): if self.checkBox.isChecked(): self.check_balance()