def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.timer2 = QTimer(self) self.timer2.start(1000 *10) self.timer2.timeout.connect(self.timeout2) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] 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) self.load_buy_sell_list()
def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) 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)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.timer2 = QTimer(self) self.timer2.start(1000 *10) self.timer2.timeout.connect(self.timeout2) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] 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) self.load_buy_sell_list() def trade_stocks(self): hoga_lookup = {'지정가': "00", '시장가': "03"} f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() f = open("sell_list.txt", 'rt') sell_list = f.readlines() f.close() # account account = self.comboBox.currentText() # buy list for row_data in buy_list: split_row_data = row_data.split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] if split_row_data[-1].rstrip() == '매수전': self.kiwoom.send_order("send_order_req", "0101", account, 1, code, num, price, hoga_lookup[hoga], "") # sell list for row_data in sell_list: split_row_data = row_data.split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] if split_row_data[-1].rstrip() == '매도전': self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "") # buy list for i, row_data in enumerate(buy_list): buy_list[i] = buy_list[i].replace("매수전", "주문완료") # file update f = open("buy_list.txt", 'wt') for row_data in buy_list: f.write(row_data) f.close() # sell list for i, row_data in enumerate(sell_list): sell_list[i] = sell_list[i].replace("매도전", "주문완료") # file update f = open("sell_list.txt", 'wt') for row_data in sell_list: f.write(row_data) f.close() def load_buy_sell_list(self): f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() f = open("sell_list.txt", 'rt') sell_list = f.readlines() f.close() row_count = len(buy_list) + len(sell_list) self.tableWidget_4.setRowCount(row_count) # buy list for j in range(len(buy_list)): row_data = buy_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rsplit()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_4.setItem(j, i, item) # sell list for j in range(len(sell_list)): row_data = sell_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rstrip()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_4.setItem(len(buy_list) + j, i, item) self.tableWidget_4.resizeRowsToContents() 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 timeout(self): market_start_time = QTime(9, 0, 0) current_time = QTime.currentTime() if current_time > market_start_time and self.trade_stocks_done is False: self.trade_stocks() self.trade_stocks_done = True 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() 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()
class TrTrader(): def __init__(self, simctrl_instance=None): self.ext_command_last_excution_time_ = datetime.now( ) # last execution set to __init__ time initiation if USE_SIMULATOR: self.km = Simulator(simctrl_instance) else: self.km = Kiwoom() if not self.km.connect_status: tl_print("System exits") sys.exit() self.bounds_table = bounds_prep() self.prev_mbf_exists = os.path.exists(MASTER_BOOK_FILE) self.trtrade_list = pd.DataFrame( columns=['code', 'amount', 'buy_sell', 'note']) self.master_book_initiator(START_CASH, replace=CREATE_NEW_MASTER_BOOK) if not USE_SIMULATOR: self.master_book_integrity_checker() def close_(self): self.write_master_book_to_Excel(self.master_book) self.status_print(to_file=True) if not USE_SIMULATOR: self.status_print(to_file=False) # print to screen too def __del__(self): del self.km def run_(self): self.execute_external_control_command( ) # web-based control through AWS cash = self.trendtrading_mainlogic( ) # returns cash amount if all trtrade_list buy_sells are executed self.load_external_trade_list(cash) trtrade_list_yetitems = self.trtrade_list.loc[self.trtrade_list['note'] == 'yet'] if len(trtrade_list_yetitems) == 0: if PRINT_TO_SCREEN: tl_print( time.strftime("t%H:%M:%S") ) #, end="\r") # Exception for trade_log_print (tl_print) # print('.', end='') if USE_SIMULATOR: return False else: self.trade_stocks() self.status_print(to_file=False) # print to screen too if USE_SIMULATOR: return True self.status_print(to_file=True) def load_external_trade_list(self, cash): # if a file that contains a list of stocks to be traded exists, load it if os.path.exists(EXTERNAL_LIST_FILE): el = TrTrader.read_external_buysell_list() self.external_list_prep(cash, el) # when USE_SIMULATOR, each run_() run will load external list created at SimController if USE_SIMULATOR: self.external_list_prep(cash, self.km.simctrl.ext_list_gen()) def external_list_prep(self, cash, el): bk = self.km.get_account_stock_list(ACCOUNT_NO) for i in el.index: if el.at[i, 'code'] in TRENDTRADE_EXCEPT_LIST: tl_print( "*** WARNING: External buysell list contains item in TRENDTRADE_EXCEPT_LIST: ", el.at[i, 'code'], " - this item ignored") el = el.drop(i) continue cprice = self.km.get_price(el.at[i, 'code']) if cprice == 0: tl_print( "*** WARNING: External list contains item with zero current price: ", el.at[i, 'code'], " - this item ignored") el = el.drop(i) continue if el.at[i, 'buy_sell'] == 'buy': if el.at[i, 'code'] in list(bk['code']): tl_print( "*** WARNING: External list contains item in current trtrading list: ", el.at[i, 'code'], " - this item ignored") el = el.drop(i) continue if el.at[i, 'amount'] == 0: el.at[i, 'amount'] = int(round(TICKET_SIZE / cprice)) tl_print( "*** External list contains item with buy quantity set to zero: ", el.at[i, 'code'], " - buy quanity set to TICKET_SIZE") ticket = int( round(cprice * el.at[i, 'amount'] * self.tax_fee_adjustment('buy'))) if cash > ticket * MIN_CASH_FOR_PURCHASE_RATE: cash = cash - ticket else: tl_print( "Exception: Cash is not enough for external list purchase: " + el.at[i, 'code']) raise Exception() else: # 'sell' if el.at[i, 'code'] not in list(bk['code']): tl_print( "*** WARNING: External list contains sell item not in current trtrading list: ", el.at[i, 'code'], " - this item ignored") continue ci = bk.loc[bk['code'] == el.at[i, 'code']] if el.at[i, 'amount'] == 0: el.at[i, 'amount'] = int(ci['nshares']) tl_print( "*** External list contains item with sell quantity set to zero: ", el.at[i, 'code'], " - sell quanity set to max") elif el.at[i, 'amount'] > int(ci['nshares']): el.at[i, 'amount'] = int(ci['nshares']) tl_print( "*** WARNING: External list contains item with sell quantity exceeding current quantity: ", el.at[i, 'code'], " - sell quanity set to max") else: pass ticket = int( round(cprice * el.at[i, 'amount'] * self.tax_fee_adjustment('sell'))) cash = cash + ticket if len(el) > 0: tl_print('External buy_sell list loaded') self.trtrade_list = self.trtrade_list.append(el) self.trtrade_list = self.trtrade_list.reset_index(drop=True) def trade_stocks(self): ################################################## # MAY NEED TO MODIFY TO SELL FIRST AND THEN BUY bs_lookup = {'buy': 1, 'sell': 2} self.tr_data = [] self.tr_data_res_ = [] for i in self.trtrade_list.index: if self.trtrade_list["note"][ i] == 'yet': # or self.trtrade_list["note"][i] == 'failed': ############################### For failed, re running of tr-mainlogic would result in adding the same item res = self.km.send_order( "send_order_req", "0101", ACCOUNT_NO, bs_lookup[self.trtrade_list["buy_sell"][i]], self.trtrade_list["code"][i], self.trtrade_list["amount"][i], 0, '03', "") # trade in market price, price = 0, hoga = '3' if res[0] == 0 and res[1] != "": # success self.trtrade_list.at[i, "note"] = 'ordered' self._write_transaction_to_master_book( self.km.chejan_finish_data[0], self.km.chejan_finish_data[1], self.km.chejan_finish_data[2], self.km.chejan_finish_data[3], self.km.chejan_finish_data[4], self.km.chejan_finish_data[5]) self.km.chejan_finish_data.append(self.tr_data_res_) self.tr_data.append(self.km.chejan_finish_data) self.km.chejan_finish_data = [] # self.tr_data = [stock_code, stock_name, buy_sell, avg_price, int(pv), tr_time, [invtotal, ret]] else: tl_print("--- Error in order processing: ", self.trtrade_list['code'][i]) self.trtrade_list.at[i, "note"] = 'failed' def trendtrading_mainlogic(self): # Trend trading logic # [step 0] for active set copy, do the following mb_active = self.master_book.loc[self.master_book['active']] cash = self.master_book.at[ self.master_book.index[-1], 'cash'] # to be cash after the trtrade_list generated by a trendtrading_mainlogic run is excuted book_cash = cash # cash to be written at the last line of master_book if USE_SIMULATOR: tr_time = self.km.simctrl.sim_time else: tr_time = time.ctime() # [step 1] update cprice, cvalue, retrate for i in mb_active.index: updated_price = self.km.get_price(mb_active.at[i, 'code']) updated_value = int( round(updated_price * mb_active.at[i, 'nshares'] * self.tax_fee_adjustment('sell'))) updated_rr = round(updated_value / mb_active.at[i, 'invtotal'] - 1, 4) # return rate mb_active.at[i, 'cprice'] = updated_price mb_active.at[i, 'cvalue'] = updated_value mb_active.at[i, 'retrate'] = updated_rr # [step 2] for dec_made == SUSPEND or EXCEPT, check if rr is back up to LB # then dec_made = released, update dec_time # otherwise, leave it as is if mb_active.at[i, 'dec_made'] == "SUSPEND" or mb_active.at[ i, 'dec_made'] == "EXCEPT": if updated_rr >= mb_active.at[i, 'LB']: mb_active.at[i, 'dec_made'] = "released" mb_active.at[i, 'dec_time'] = tr_time self.master_book.loc[i, 'active'] = False new_line = mb_active.loc[mb_active.index == i] new_line.at[i, 'cash'] = book_cash new_line.index = [len(self.master_book)] self.master_book = self.master_book.append(new_line) # [step 3] for dec_made != SUSPEND and != "EXCEPT": compare rr with LLB, LB, UB else: # if mb_active.at[i, 'dec_made'] != "SUSPEND" and mb_active.at[i, 'dec_made'] != "EXCEPT": # if hits LLB, suspend trading until it reaches LB: dec_made = SUSPEND, update dec_time if updated_rr <= mb_active.at[i, 'LLB']: mb_active.at[i, 'dec_made'] = "SUSPEND" mb_active.at[i, 'dec_time'] = tr_time self.master_book.loc[i, 'active'] = False new_line = mb_active.loc[mb_active.index == i] new_line.at[i, 'cash'] = book_cash new_line.index = [len(self.master_book)] self.master_book = self.master_book.append(new_line) # if in between LLB and LB, sell (at loss): add this item to the trtrade_list (sell), code and quantity, DO NOT CHANGE MASTER BOOK else: if updated_rr <= mb_active.at[i, 'LB']: self.trtrade_list.loc[len(self.trtrade_list)] = [ self.master_book.at[i, 'code'], int(self.master_book.at[i, 'nshares']), 'sell', 'yet' ] tl_print("Situation 1 - lower than LB: ", self.master_book.at[i, 'code'], " sell") ######################### cash = cash + updated_value # if in between LB and UB: hold elif updated_rr < mb_active.at[i, 'UB']: pass # if hits UB: else: # elif no_repurchase = MAX_ELEVATION: add this item to the trade_list (sell), DO NOT CHANGE MASTER BOOK nr = mb_active.at[i, 'nreinv'] if nr == MAX_ELEVATION: self.trtrade_list.loc[len(self.trtrade_list)] = [ self.master_book.at[i, 'code'], int(self.master_book.at[i, 'nshares']), 'sell', 'yet' ] tl_print("Situation 2 - more than MAX_ELEVATION: ", self.master_book.at[i, 'code'], " sell") ########################## cash = cash + updated_value else: # check cash, # if cash > MIN_CASH_FOR_PURCHASE and no_repurchase < MAX_REINVESTMENT: add this item to trade_list (buy), DO NOT CHANGE MASTER BOOK if cash > MIN_CASH_FOR_PURCHASE and nr < MAX_REINVESTMENT: self.trtrade_list.loc[len( self.trtrade_list)] = [ self.master_book.at[i, 'code'], int(round(TICKET_SIZE / updated_price)), 'buy', 'yet' ] tl_print("Situation 3 - higher than UB: ", self.master_book.at[i, 'code'], " buy") ########################## cash = cash - TICKET_SIZE # else elevate bounds 1 steps, and update no_repurchase, dec_made = "bd_elev" and dec_time else: mb_active.at[i, 'nreinv'] = nr + 1 [LLB, LB, UB] = self.bounds(nr + 1) mb_active.at[i, 'LLB'] = LLB mb_active.at[i, 'LB'] = LB mb_active.at[i, 'UB'] = UB mb_active.at[i, 'dec_made'] = 'bd_elev' mb_active.at[i, 'dec_time'] = tr_time self.master_book.loc[i, 'active'] = False new_line = mb_active.loc[mb_active.index == i] new_line.at[i, 'cash'] = book_cash new_line.index = [len(self.master_book)] self.master_book = self.master_book.append( new_line) return cash def master_book_integrity_checker(self): bk = self.km.get_account_stock_list(ACCOUNT_NO) for exception_code in TRENDTRADE_EXCEPT_LIST: bk = bk[bk['code'] != exception_code] bk = bk.reset_index(drop=True) ch = int(self.km.get_cash(ACCOUNT_NO)) tl_print('Cash in Kiwoom Account is: ', format(ch, ',')) if self.prev_mbf_exists == False or CREATE_NEW_MASTER_BOOK == True: if ch < START_CASH - bk['invtotal'].sum( ) * self.tax_fee_adjustment('buy'): tl_print('Exception: INSUFFICIENT CASH TO START TREND TRADING') raise Exception() entries = pd.DataFrame(columns=self.master_book.columns) entries[[ 'code', 'name', 'cprice', 'nshares', 'invtotal', 'cvalue', 'retrate' ]] = bk[[ 'code', 'name', 'cprice', 'nshares', 'invtotal', 'cvalue', 'retrate' ]] entries['invtotal'] = round(entries['invtotal'] * self.tax_fee_adjustment('buy')) entries['cvalue'] = round(entries['cvalue'] * self.tax_fee_adjustment('sell')) entries = entries.astype({'invtotal': 'int', 'cvalue': 'int'}) entries['ret'] = 0 entries['retrate'] = round( (entries['cvalue'] - entries['invtotal']) / entries['invtotal'], 4) entries['init_invtime'] = entries['dec_time'] = time.ctime() entries['dec_made'] = 'loaded' entries['active'] = True for i in entries.index: res = self.nreinv_find(entries.at[i, 'retrate']) if res[0] == -1: entries.at[i, 'dec_made'] = 'EXCEPT' tl_print(' - ', entries.at[i, 'code'], entries.at[i, 'name'], ' > EXCEPT') entries.at[i, 'nreinv'] = nr = res[1] [LLB, LB, UB] = self.bounds(nr) entries.at[i, 'LLB'] = LLB entries.at[i, 'LB'] = LB entries.at[i, 'UB'] = UB if i == 0: entries.at[i, 'cash'] = int(START_CASH - entries.at[i, 'invtotal']) else: entries.at[i, 'cash'] = int(entries.at[i - 1, 'cash'] - entries.at[i, 'invtotal']) self.master_book = self.master_book.append(entries) self.master_book = self.master_book.reset_index(drop=True) tl_print( '[Initiation success]: Existing stock list from Kiwoom API loaded into master_book' ) else: ############################################# # Loading existing book # master_book active items should match bk items mb_cash = self.master_book.at[len(self.master_book) - 1, 'cash'] if mb_cash > ch: tl_print( "Exception: Master_book loading error - cash balance insufficient" ) raise Exception() mb_active = self.master_book.loc[self.master_book[ 'active']] # selected subset of DataFrame is already a deep copy of original DataFrame if len(mb_active) != len(bk): tl_print("Exception: Master_Book integrity check: error (1)") raise Exception( ) # this error could occur when releasing from and adding to TRENDTRADE_EXCEPT_LIST for i in bk.index: mt = mb_active[mb_active['code'] == bk.at[i, 'code']] if len(mt) != 1: tl_print( "Exception: Master_Book integrity check: error (2)") raise Exception() l = list(mt.index)[0] if mt.at[l, 'nshares'] != bk.at[i, 'nshares']: tl_print( "Exception: Master_Book integrity check: error (3)") raise Exception() if (mt.at[l, 'invtotal'] - bk.at[i, 'invtotal'] * self.tax_fee_adjustment('buy') ) / mt.at[l, 'invtotal'] > 0.01: tl_print( "Exception: Master_Book integrity check: error (4)") raise Exception() tl_print( '[Initiation success]: Existing stock list from Kiwoom API matches with master_book' ) def master_book_initiator(self, initial_cash_amount, replace=False): if self.prev_mbf_exists and not replace: # tl_print("Using existing master book - master book file exists") pass else: if self.prev_mbf_exists and replace: t = time.strftime("_%Y%m%d_%H%M%S") n = MASTER_BOOK_BACKUP_FILE[:-5] os.rename(MASTER_BOOK_FILE, n + t + '.xlsx') self.prev_mbf_exists = False mb = xlsxwriter.Workbook(MASTER_BOOK_FILE) mbws = mb.add_worksheet() mbws.write('A1', 'code') mbws.write('B1', 'name') mbws.write( 'C1', 'cprice') # price at the time of the decision, current_price mbws.write('D1', 'nshares') # number of shares mbws.write('E1', 'nreinv') # number of reinvestements mbws.write('F1', 'LLB') # Limit Lower Bound mbws.write('G1', 'LB') mbws.write('H1', 'UB') mbws.write('I1', 'invtotal') # invested total amount after entry fee mbws.write( 'J1', 'cvalue' ) # value at the time of the decision (after tax and exit fee) current_value mbws.write('K1', 'retrate') # return_rate mbws.write( 'L1', 'ret' ) # return resulted due to the decision in the current line mbws.write('M1', 'init_invtime') mbws.write( 'N1', 'dec_made') # decision that resulted in the current line mbws.write('O1', 'dec_time') mbws.write( 'P1', 'active' ) # True: for currently holding stocks, False: for record mbws.write('Q1', 'cash') # d+2 cash after all tax and fee mbws.write('A2', '-') mbws.write('B2', 'init') mbws.write('C2', 0) mbws.write('D2', 0) mbws.write('E2', 0) mbws.write('F2', 0) mbws.write('G2', 0) mbws.write('H2', 0) mbws.write('I2', 0) mbws.write('J2', 0) mbws.write('K2', 0) mbws.write('L2', 0) mbws.write('M2', time.ctime()) mbws.write('N2', '-') mbws.write('O2', time.ctime()) mbws.write('P2', False) mbws.write('Q2', initial_cash_amount) mb.close() self.master_book = self.read_master_book_from_Excel() def read_master_book_from_Excel(self): mb_converters = { 'code': str, 'name': str, 'cprice': int, 'nshares': int, 'nreinv': int, 'LLB': float, 'LB': float, 'UB': float, 'invtotal': int, 'cvalue': int, 'retrate': float, 'ret': int, 'init_invtime': str, 'dec_made': str, 'dec_time': str, 'active': bool, 'cash': int } master_book = pd.read_excel(MASTER_BOOK_FILE, index_col=None, converters=mb_converters) master_book['init_invtime'] = pd.to_datetime( master_book['init_invtime']) master_book['dec_time'] = pd.to_datetime(master_book['dec_time']) return master_book @staticmethod def read_external_buysell_list(): el_converters = { 'code': str, 'amount': int, 'buy_sell': str, 'note': str } el = pd.read_excel(EXTERNAL_LIST_FILE, index_col=None, converters=el_converters) t = time.strftime("_%Y%m%d_%H%M%S") n = EXTERNAL_LIST_BACKUP_FILE[:-5] os.rename(EXTERNAL_LIST_FILE, n + t + '.xlsx') return el def write_master_book_to_Excel(self, master_book): master_book.to_excel(MASTER_BOOK_FILE, index=False) def _write_transaction_to_master_book(self, code, name, buy_sell, price, quantity, tr_time): # this function is to be used only after SendOrder success mb_active = self.master_book.loc[self.master_book["active"]] active_line = mb_active[mb_active['code'] == code] if buy_sell == 'buy': if len(active_line) == 0: new_line = pd.DataFrame(columns=self.master_book.columns) new_line.at[0, 'code'] = code new_line.at[0, 'name'] = name new_line.at[0, 'cprice'] = price new_line.at[0, 'nshares'] = quantity new_line.at[0, 'nreinv'] = nr = 0 [LLB, LB, UB] = self.bounds(nr) new_line.at[0, 'LLB'] = LLB new_line.at[0, 'LB'] = LB new_line.at[0, 'UB'] = UB new_line.at[0, 'invtotal'] = v1 = int( round(price * quantity * self.tax_fee_adjustment('buy'))) new_line.at[0, 'cvalue'] = v2 = int( round(price * quantity * self.tax_fee_adjustment('sell'))) new_line.at[0, 'retrate'] = round((v2 - v1) / v1, 4) new_line.at[0, 'ret'] = 0 new_line.at[0, 'init_invtime'] = tr_time new_line.at[0, 'dec_made'] = 'new_ent' new_line.at[0, 'dec_time'] = tr_time new_line.at[0, 'active'] = True new_line.at[0, 'cash'] = ch = self.master_book.at[ len(self.master_book) - 1, 'cash'] - v1 elif len(active_line) == 1: idx = list(active_line.index)[0] self.master_book.at[idx, 'active'] = False new_line = active_line new_line.at[idx, 'cprice'] = price # price update new_line.at[idx, 'nshares'] = ns = new_line.at[ idx, 'nshares'] + quantity # repurchase new_line.at[idx, 'nreinv'] = nr = new_line.at[idx, 'nreinv'] + 1 if nr > MAX_REINVESTMENT: tl_print( "Exception: Do not attmpt to purchase over MAX_ELEVATION" ) raise Exception() [LLB, LB, UB] = self.bounds(nr) new_line.at[idx, 'LLB'] = LLB new_line.at[idx, 'LB'] = LB new_line.at[idx, 'UB'] = UB repv = int( round(price * quantity * self.tax_fee_adjustment('buy'))) new_line.at[idx, 'invtotal'] = v1 = new_line.at[idx, 'invtotal'] + repv new_line.at[idx, 'cvalue'] = v2 = int( round((price * ns) * self.tax_fee_adjustment('sell'))) new_line.at[idx, 'retrate'] = round((v2 - v1) / v1, 4) new_line.at[idx, 'ret'] = 0 # new_line.at[0, 'init_invtime'] = tr_time # does not change new_line.at[idx, 'dec_made'] = 'reinv' new_line.at[idx, 'dec_time'] = tr_time # update time new_line.at[idx, 'active'] = True new_line.at[idx, 'cash'] = ch = self.master_book.at[ len(self.master_book) - 1, 'cash'] - repv else: tl_print("Exception: ERROR in Master_Book Integrity - buy") raise Exception() else: # buy_sell == 'sell': if len(active_line) == 1: idx = list(active_line.index)[0] self.master_book.at[idx, 'active'] = False new_line = active_line new_line.at[idx, 'cprice'] = price # price update original_quantity = new_line.at[idx, 'nshares'] new_line.at[ idx, 'nshares'] = remained_quantity = original_quantity - quantity avg_price = new_line.at[idx, 'invtotal'] / original_quantity new_line.at[idx, 'invtotal'] = v1 = avg_price * remained_quantity new_line.at[idx, 'cvalue'] = v2 = int( round(price * remained_quantity * self.tax_fee_adjustment('sell'))) if v1 != 0: # remained_quantity is not zero new_line.at[idx, 'retrate'] = round((v2 - v1) / v1, 4) else: new_line.at[idx, 'retrate'] = 0 v3 = int( round(price * quantity * self.tax_fee_adjustment('sell'))) new_line.at[idx, 'ret'] = v3 - avg_price * quantity if remained_quantity == 0: new_line.at[idx, 'dec_made'] = 'a_sold' new_line.at[idx, 'active'] = False ################################################################# # tr_data saves results only when a_sold self.tr_data_res_ = [ self.master_book.at[idx, 'invtotal'], new_line.at[idx, 'ret'] ] else: new_line.at[idx, 'dec_made'] = 'p_sold' new_line.at[idx, 'active'] = True new_line.at[idx, 'dec_time'] = tr_time new_line.at[idx, 'cash'] = ch = self.master_book.at[ len(self.master_book) - 1, 'cash'] + v3 else: tl_print("Exception: ERROR in Master_Book Integrity - sell") raise Exception() new_line.index = [len(self.master_book)] self.master_book = self.master_book.append(new_line) def bounds(self, nr): # nr = number of repurchase UB = round(self.bounds_table.at['UB', nr], 4) LB = round(self.bounds_table.at['LB', nr], 4) LLB = round(self.bounds_table.at['LLB', nr], 4) return [LLB, LB, UB] def nreinv_find(self, rr): res = [0, 0] if rr <= self.bounds_table.at['LLB', 0]: # raise Exception("Current return rate is even lower than LLB for initial investment") # print("Return rate is even lower than LLB for initial investment") res[0] = -1 elif rr <= self.bounds_table.at['LB', 0]: # raise Exception("Current return rate is even lower than LB for initial investment") # print("Return rate is even lower than LB for initial investment") res[0] = -1 else: pass for i in self.bounds_table.columns: if rr <= self.bounds_table.at['LB', i]: res[1] = max(i - 1, 0) return res res[1] = MAX_ELEVATION return res def tax_fee_adjustment(self, buy_sell): if buy_sell == 'buy': return 1 + FEE_RATE # when buying, you pay additional cash for fee else: # buy_sell == 'sell': return 1 - (FEE_RATE + TAX_RATE ) # when selling, your cash is dedcuted by tax and fee def execute_external_control_command(self): [command_time, ext_command] = self.read_external_command() if ext_command != '': tl_print('External command [' + ext_command + '] recognized at time: ' + datetime.now().strftime("%Y%m%d %H:%M:%S") + ' (command created at: ' + command_time + ')') if ext_command == 'suspend': tl_print( "*****************************************************") tl_print( "PROCESS SUSPENDED PER THE EXTERNAL COMMAND: [suspend]") tl_print( "*****************************************************") while 1: # tl_print("System suspended - waiting for", EXT_COMM_SUSPEND_SLEEPING_TIME, "seconds until recheck") time.sleep(EXT_COMM_SUSPEND_SLEEPING_TIME) [command_time, ext_command] = self.read_external_command() if ext_command == 'resume': tl_print('External command [' + ext_command + '] recognized at time: ' + self.ext_command_last_excution_time_.strftime( "%Y%m%d %H:%M:%S") + ' (command created at: ' + command_time + ')') tl_print( "*****************************************************" ) tl_print( "PROCESS RESUMED PER THE EXTERNAL COMMAND: [resume]" ) tl_print( "*****************************************************" ) break elif ext_command == 'stop': tl_print('External command [' + ext_command + '] recognized at time: ' + self.ext_command_last_excution_time_.strftime( "%Y%m%d %H:%M:%S") + ' (command created at: ' + command_time + ')') break elif ext_command == 'ping': tl_print("ping > trtrader is suspended") elif ext_command == 'resume': tl_print( "[resume] command not executed in suspend status is ignored" ) elif ext_command == 'ping': tl_print("ping > trtrader is running") if ext_command == 'stop': tl_print( "*****************************************************") tl_print("PROCESS EXITS PER THE EXTERNAL COMMAND: [stop]") tl_print( "*****************************************************") tl_print("System exits") sys.exit() def read_external_command(self): try: html = urllib.request.urlopen(EXTERNAL_COMMAND_URL).read() soup = BeautifulSoup(html, features='lxml') text = soup.get_text() lines = [line.strip() for line in text.splitlines() ] # strips spaces before and after each word command_time = datetime.strptime(lines[0], "%Y%m%d %H:%M:%S") ext_command = lines[1] if command_time > self.ext_command_last_excution_time_: # only if command time is later than init time or last execution time, the command will be executed if ext_command in EXTERNAL_COMMAND_LIST: self.ext_command_last_excution_time_ = command_time return [lines[0], ext_command] return ['', ''] except Exception as e: # tl_print("Excpetion: Error in read_external_command - ignored: " + str(e)) return ['', ''] # Any kinds of errors are ignored def status_print(self, to_file=False): mb_print = self.master_book.copy() mb_print = mb_print.astype(str) for i in mb_print.index: mb_print.at[i, 'name'] = mb_print.at[i, 'name'][:6] mb_print.at[i, 'cprice'] = format(int(mb_print.at[i, 'cprice']), ',') mb_print.at[i, 'nshare'] = format(int(mb_print.at[i, 'nshares']), ',') mb_print.at[i, 'LLB'] = format( float(mb_print.at[i, 'LLB']) * 100, '.1f') mb_print.at[i, 'LB'] = format( float(mb_print.at[i, 'LB']) * 100, '.1f') mb_print.at[i, 'UB'] = format( float(mb_print.at[i, 'UB']) * 100, '.1f') mb_print.at[i, 'invtotal'] = format( int(round(float(mb_print.at[i, 'invtotal']) / 1000)), ',') mb_print.at[i, 'cvalue'] = format( int(round(float(mb_print.at[i, 'cvalue']) / 1000)), ',') mb_print.at[i, 'ret'] = format( int(round(float(mb_print.at[i, 'ret']) / 1000)), ',') mb_print.at[i, 'cash'] = format( int(round(float(mb_print.at[i, 'cash']) / 1000)), ',') mb_print.at[i, 'retrate'] = format( float(mb_print.at[i, 'retrate']) * 100, '.1f') mb_print = mb_print.rename( columns={ 'cprice': 'cpr', 'nshares': 'vol', 'nreinv': 'nr', 'LLB': 'LL(%)', 'LB': 'L(%)', 'UB': 'U(%)', 'invtotal': 'inv(k)', 'cvalue': 'cval(k)', 'retrate': 'rt(%)', 'ret': 'rt(k)', 'dec_made': 'dec', 'active': 'act', 'cash': 'cash(k)' }) mb_print.drop([0], inplace=True) l = [ 'code', 'cpr', 'vol', 'nr', 'LL(%)', 'L(%)', 'U(%)', 'inv(k)', 'cval(k)', 'rt(%)', 'rt(k)', 'dec', 'act', 'cash(k)', 'name' ] mb_mobile = mb_print.copy() mb_mobile['dec'] = mb_mobile['dec'].map(ABRIDGED_DICT) mb_mobile['act'] = mb_mobile['act'].map({'True': 'A', 'False': 'F'}) mb_mobile['DA'] = mb_mobile['dec'] + mb_mobile['act'] lm = ['code', 'inv(k)', 'nr', 'rt(%)', 'DA', 'name'] if to_file == True: f = open(STATUS_REPORT_FILE, 'w') f.write('master_book (up to last 75 items): \n') f.write( tabulate(mb_print.loc[-75:, l], headers='keys', showindex=False, tablefmt='simple')) f.write('\n') f.close() m = open(STATUS_REPORT_MOBILE, 'w') m.write('master_book (last 75 items): \n') m.write( tabulate(mb_mobile.loc[-75:, lm], headers='keys', showindex=False, tablefmt='simple')) m.write('\n') m.close() else: tl_print( 'MASTER_BOOK (up to last 75 items): \n', tabulate(mb_print.loc[-75:, l], headers='keys', showindex=False, tablefmt='psql')) if len(self.trtrade_list) > 0: trtrade_list_print = self.trtrade_list.copy() for i in trtrade_list_print.index: trtrade_list_print.at[i, 'name'] = self.km.get_master_code_name( trtrade_list_print.at[i, 'code']) if to_file == True: f = open(STATUS_REPORT_FILE, 'a') f.write('trtrade_list (up to last 75 items): \n') f.write( tabulate(trtrade_list_print.loc[-75:, :], headers='keys', showindex=False, tablefmt='simple')) f.write('\n') f.close() m = open(STATUS_REPORT_MOBILE, 'a') m.write('trtrade_list (last 75 items): \n') m.write( tabulate(trtrade_list_print.loc[-75:, :], headers='keys', showindex=False, tablefmt='simple')) m.write('\n') m.close() else: tl_print( 'trtrade_list (up to last 75 items): \n', tabulate(trtrade_list_print.loc[-75:, :], headers='keys', showindex=False, tablefmt='psql')) else: if to_file == True: f = open(STATUS_REPORT_FILE, 'a') f.write('trtrade_list empty \n') f.close() m = open(STATUS_REPORT_MOBILE, 'a') m.write('trtrade_list empty \n') m.close() else: tl_print('trtrade_list empty') self.status_summary_report(to_file) def status_summary_report(self, to_file=False): # Cash at ACCOUNT # Cash at TrTrading # Total invested amount accross all items # Current value total across all items # Return rate of TrTrading # Realized return total # Number of active items cash_account = format( int(round(int(self.km.get_cash(ACCOUNT_NO)) / 1000)), ',') mb_active = self.master_book.loc[self.master_book['active']] cash_trtrading = format( int( round(self.master_book.at[self.master_book.index[-1], 'cash'] / 1000)), ',') # there might not be any active item. tr_invested_total = mb_active['invtotal'].sum() tr_cvalue_total = mb_active['cvalue'].sum() if tr_invested_total > 0: tr_return_rate = tr_cvalue_total / tr_invested_total - 1 else: tr_return_rate = 0 tr_invested_total = format(int(round(tr_invested_total / 1000)), ',') tr_cvalue_total = format(int(round(tr_cvalue_total / 1000)), ',') tr_return_rate = format(tr_return_rate * 100, '.2f') tr_realized_return_total = format( int(round(self.master_book['ret'].sum() / 1000)), ',') no_active = len(mb_active) t = time.strftime("%Y%m%d %H:%M:%S") if to_file == True: f = open(STATUS_REPORT_FILE, 'a') f.write("[TrTrade Summary - " + t + "]" + "\n") f.write("- Kiwoom Cash(k): " + cash_account + "\n") f.write("- TrTrade Cash(k): " + cash_trtrading + "\n") f.write('- Return(%): ' + tr_return_rate + "\n") f.write('- #items: ' + str(no_active) + "\n") f.write("- Total invested(k): " + tr_invested_total + "\n") f.write("- Current Value(k): " + tr_cvalue_total + "\n") f.write('- Realized Return Total(k): ' + tr_realized_return_total + "\n") f.write('- Exception List: ' + str(TRENDTRADE_EXCEPT_LIST) + "\n") f.close() m = open(STATUS_REPORT_MOBILE, 'a') m.write("[TrTrade Summary - " + t + "]" + "\n") m.write("- Kiwoom Cash(k): " + cash_account + "\n") m.write("- TrTrade Cash(k): " + cash_trtrading + "\n") m.write('- Return(%): ' + tr_return_rate + "\n") m.write('- #items: ' + str(no_active) + "\n") m.write("- Total invested(k): " + tr_invested_total + "\n") m.write("- Current Value(k): " + tr_cvalue_total + "\n") m.write('- Realized Return Total(k): ' + tr_realized_return_total + "\n") m.write('- Exception List: ' + str(TRENDTRADE_EXCEPT_LIST) + "\n") m.close() else: tl_print("[TrTrade Summary - " + t + ']') tl_print("- Kiwoom Cash(k): " + cash_account) tl_print("- TrTrade Cash(k): " + cash_trtrading) tl_print('- Return(%): ' + tr_return_rate) tl_print('- #items: ' + str(no_active)) tl_print("- Total invested(k): " + tr_invested_total) tl_print("- Current Value(k): " + tr_cvalue_total) tl_print('- Realized Return Total(k): ' + tr_realized_return_total) tl_print('- Exception List: ' + str(TRENDTRADE_EXCEPT_LIST))
def __init__(self): super().__init__() self.setupUi(self) self.tr = 0 #총TR요청횟수 #텔레그램봇 my_token = '692301814:AAEfmddhyZPcO0Uzh8r5ZehfooTPOvKOOqc' self.mybot = telegram.Bot(token=my_token) self.chat_id = 544924927 self.kiwoom = Kiwoom() #키움인스턴스 생성 self.kiwoom.comm_connect() #API로그인 self.ts_1_p = 'False' #거래전략1 초기값 # Timer1 self.timer = QTimer(self) self.timer.start(1000) #1초 상태바 self.timer.timeout.connect(self.timeout) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 25) #25초 잔고조회 self.timer2.timeout.connect(self.timeout2) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 30) #30초 매수전략1 self.timer3.timeout.connect(self.timeout3) # Timer4 self.timer4 = QTimer(self) self.timer4.start(1000 * 33) # 33초 매도전략 self.timer4.timeout.connect(self.timeout4) # Timer5 self.volume_start = 'false' self.timer5 = QTimer(self) #self.timer5.start(1000 * 60) # 60초 9시에 급등주알고리즘 시작하기 #self.timer5.timeout.connect(self.timeout5) # Timer7 self.timer7 = QTimer(self) self.timer7.start(1000 * 1800) # 30분 중간보고 self.timer7.timeout.connect(self.timeout7) self.list700 = [] self.list600 = [] self.buy_list = [] #버튼, 이벤트발생 self.lineEdit.textChanged.connect(self.code_changed) #종목코드 입력시 self.pushButton.clicked.connect(self.send_order) #현금주문 버튼 클릭시 self.pushButton_2.clicked.connect(self.check_balance) #계좌정보 조회 self.pushButton_3.clicked.connect(self.trading_strategy_1) #거래전략1호 self.pushButton_4.clicked.connect(self.quit_app) #앱종료 self.pushButton_4.clicked.connect( QCoreApplication.instance().quit) # 앱종료 self.pushButton_5.clicked.connect(self.test_button) # 테스트버튼 #계좌정보 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) #프로그램시작알림 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "\n프로그램이 시작되었습니다.")
class Bring_stock_data(): def __init__(self): super().__init__() self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.kiwoom.ohlcv = { 'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': [] } self.kiwoom.df_10001 = { 'code': [], 'name': [], 'month': [], 'face_value': [], 'capital': [] } self.kiwoom.df_10002 = { 'code': [], 'name': [], '매도거래원명1': [], '매도거래원1': [], '매도거래량1': [], '매수거래원명1': [], '매수거래원1': [], '매수거래량1': [] } self.kiwoom.df_10003 = {'시간': [], '현재가': [], '누적거래량': []} self.kiwoom.df_10004 = { '총매도잔량': [], '총매수잔량': [], '시간외매도잔량': [], '시간외매수잔량': [] } self.kiwoom.df_10005 = { '날짜': [], '시가': [], '고가': [], '저가': [], '종가': [] } self.kiwoom.df_10006 = { '날짜': [], '시가': [], '고가': [], '저가': [], '종가': [] } self.kiwoom.df_20006 = {'일자': [], '시가': [], '고가': [], '저가': []} # 주식 기본정보를 df로 받는다. def load_item_basic_info(self): stock_code = input("stock_code: ") start_date = input("start_date: ") stock_code = str(stock_code) start_date = str(start_date) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.set_input_value("조회일자", start_date) self.kiwoom.comm_rq_data("opt10086_req", "opt10086", 0, "0124") while self.kiwoom.remained_data == True: time.sleep(TR_REQ_TIME_INTERVAL) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.set_input_value("조회일자", start_date) self.kiwoom.comm_rq_data("opt10086_req", "opt10086", 2, "0124") df = pd.DataFrame(self.kiwoom.ohlcv, columns=['open', 'high', 'low', 'close', 'volume'], index=self.kiwoom.ohlcv['date']) print(df) print("save_to_csv") df.to_csv( "C:\\workplace\\atm_project\\atm_ver_0.1_jh\\item_basic_info.csv", mode='w') return df def get_tr10001_data(self): stock_code = input("stock_code: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0286") print(self.kiwoom.df_10001) df = pd.DataFrame(self.kiwoom.df_10001, columns=['name', 'month', 'face_value', 'capital'], index=self.kiwoom.df_10001['code']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10001.csv", mode='w') def get_tr10002_data(self): stock_code = input("stock_code: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10002_req", "opt10002", 0, "0129") print(self.kiwoom.df_10002) df = pd.DataFrame(self.kiwoom.df_10002, columns=[ 'name', '매도거래원명1', '매도거래원1', '매도거래량1', '매수거래원명1', '매수거래원1', '매수거래량1' ], index=self.kiwoom.df_10002['code']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10002.csv", mode='w') def get_tr10003_data(self): stock_code = input("stock_code: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10003_req", "opt10003", 0, "0120") while self.kiwoom.remained_data == True: time.sleep(TR_REQ_TIME_INTERVAL) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10003_req", "opt10003", 2, "0120") print(self.kiwoom.df_10003) df = pd.DataFrame(self.kiwoom.df_10003, columns=['현재가', '누적거래량'], index=self.kiwoom.df_10003['시간']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10003.csv", mode='w') def get_tr10004_data(self): stock_code = input("종목코드: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10004_req", "opt10004", 0, "0119") df = pd.DataFrame(self.kiwoom.df_10004, columns=['총매도잔량', '총매수잔량', '시간외매도잔량', '시간외매수잔량']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10004.csv", mode='w') def get_tr10005_data(self): stock_code = input("종목코드: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10005_req", "opt10005", 0, "0124") while self.kiwoom.remained_data == True: time.sleep(TR_REQ_TIME_INTERVAL) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10005_req", "opt10005", 2, "0124") df = pd.DataFrame(self.kiwoom.df_10005, columns=['시가', '고가', '저가', '종가'], index=self.kiwoom.df_10005['날짜']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10005.csv", mode='w') def get_tr10006_data(self): stock_code = input("종목코드: ") stock_code = str(stock_code) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10006_req", "opt10006", 0, "0124") while self.kiwoom.remained_data == True: time.sleep(TR_REQ_TIME_INTERVAL) self.kiwoom.set_input_value("종목코드", stock_code) self.kiwoom.comm_rq_data("opt10006_req", "opt10006", 2, "0124") df = pd.DataFrame(self.kiwoom.df_10006, columns=['시가', '고가', '저가', '종가'], index=self.kiwoom.df_10006['날짜']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr10006.csv", mode='w') def get_tr20006_data(self): market_code = input("업종코드: ") start_date = input("기준일자: ") market_code = str(market_code) start_date = str(start_date) self.kiwoom.set_input_value("업종코드", market_code) self.kiwoom.set_input_value("기준일자", start_date) self.kiwoom.comm_rq_data("opt20006_req", "opt20006", 0, "0602") while self.kiwoom.remained_data == True: time.sleep(TR_REQ_TIME_INTERVAL) self.kiwoom.set_input_value("업종코드", market_code) self.kiwoom.set_input_value("기준일자", start_date) self.kiwoom.comm_rq_data("opt20006_req", "opt20006", 2, "0602") df = pd.DataFrame(self.kiwoom.df_20006, columns=['시가', '고가', '저가'], index=self.kiwoom.df_20006['일자']) print(df) print("save_to_csv") df.to_csv("C:\\workplace\\atm_project\\atm_ver_0.1_jh\\tr20006.csv", mode='w') # df를 csv파일로 저장 def save_df_to_csv(self, df): print("stock_save_to_csv") df.to_csv( "C:\\workplace\\atm_project\\atm_ver_0.1_jh\\item_basic_info.csv", mode='w')
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.CommConnect() # Timer self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 10) self.timer2.timeout.connect(self.timeout2) # Get Account Number accouns_num = int(self.kiwoom.GetLoginInfo("ACCOUNT_CNT")) accounts = self.kiwoom.GetLoginInfo("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] 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) def timeout2(self): if self.checkBox.isChecked() == True: self.check_balance() 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 = "서버 연결 중" else: state_msg = "서버 미 연결 중" self.statusbar.showMessage(state_msg + " | " + time_msg) def code_changed(self): code = self.lineEdit.text() code_name = self.kiwoom.GetMasterCodeName(code) self.lineEdit_2.setText(code_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.SendOrder("SendOrder_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "") def check_balance(self): self.kiwoom.init_opw00018_data() # Request opw00018 self.kiwoom.SetInputValue("계좌번호", "8080996211") self.kiwoom.SetInputValue("비밀번호", "0000") self.kiwoom.CommRqData("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.prev_next == '2': time.sleep(0.2) self.kiwoom.SetInputValue("계좌번호", "8080996211") self.kiwoom.SetInputValue("비밀번호", "0000") self.kiwoom.CommRqData("opw00018_req", "opw00018", 2, "2000") # Request opw00001 self.kiwoom.SetInputValue("계좌번호", "8080996211") self.kiwoom.SetInputValue("비밀번호", "0000") self.kiwoom.CommRqData("opw00001_req", "opw00001", 0, "2000") # balance item = QTableWidgetItem(self.kiwoom.data_opw00001) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, 0, item) for i in range(1, 6): item = QTableWidgetItem(self.kiwoom.data_opw00018['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.data_opw00018['multi']) self.tableWidget_2.setRowCount(item_count) for j in range(item_count): row = self.kiwoom.data_opw00018['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()
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.run() self.currentTime = datetime.datetime.now() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) # Timer2 실시간 조회 체크박스 체크하면 10초에 한 번씩 데이터 자동 갱신 self.timer2 = QTimer(self) self.timer2.start(1000 * 10) self.timer2.timeout.connect(self.timeout2) # 선정 종목 리스트 self.load_buy_sell_list() accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) #self.pushButton_2.clicked.connect(self.check_balance) self.check_balance() self.save_final_stock() def is_trading_time(self): vals = [] current_time = self.currentTime.time() for start, end in TRADING_TIME: start_time = datetime.time(hour=start[0], minute=start[1]) end_time = datetime.time(hour=end[0], minute=end[1]) if (current_time >= start_time and current_time <= end_time): vals.append(True) else: vals.append(False) pass if vals.count(True): return True else: return False """def stock_name(self): f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() account = self.comboBox.currentText() for row_data in buy_list: split_row_data = row_data.split(';') code = split_row_data[1] """ #주문을 들어가기 전에 파일에서 불러와서 종목을 확인, 종목의 전일 종가 확인 - 첫 번째 주문 시 #두 번째 주문부터는 이미 주문 들어간 파일에서 확인 # 자동 주문 def trade_stocks(self): #self.check_balance() auto_buy = [] hoga_lookup = {'지정가': "00", '시장가': "03"} f = open("buy_list.txt", 'rt') buy_list = f.readlines() auto_buy += buy_list f.close() f = open("sell_list.txt", 'rt') sell_list = f.readlines() f.close() account = self.comboBox.currentText() close_rate, current_rate = self.run() #print("rate: ", rate[2][0]) print(current_rate) # buy list for i in range(len(auto_buy)): split_row_data = auto_buy[i].split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] bdr = split_row_data[5] pr = split_row_data[6] lr = split_row_data[7] #temp = self.kiwoom.opw00018_output['multi'][0][3] """for i in range(len(new)): price = bdr * new[i] price = int(price) temp = price % 10 new_price = price - temp""" #print(self.final_stock[0]) #price = bdr * self.final_stock[cnt] """price = int(price) temp = price % 10 new_price = price - """ print("bdr:", float(bdr)) # 전날 종가 new_price = close_rate[i][0] * float(bdr) print("cnt:", i) print("rate[cnt]", close_rate[i][0]) print("new_price:", new_price) #temp = new_price % 10 #new_price = new_price - temp hoga = "지정가" if split_row_data[-1].rstrip( ) == '매수전' and new_price <= current_rate[i][ 0] and self.is_trading_time() == True: self.kiwoom.send_order("send_order_req", "0101", account, 1, code, 1, int(new_price), hoga_lookup[hoga], "") if self.kiwoom.orderNum: for i, row_data in enumerate(buy_list): buy_list[i] = buy_list[i].replace("매수전", "주문완료") elif split_row_data[-1].rstrip() == '매수전' and self.is_trading_time( ) == False: self.kiwoom.send_order("send_order_req", "0101", account, 1, code, 1, price, hoga_lookup[hoga], "") if self.kiwoom.orderNum: for i, row_data in enumerate(buy_list): buy_list[i] = buy_list[i].replace("매수전", "주문완료") # sell list for row_data in sell_list: split_row_data = row_data.split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] if split_row_data[-1].rstrip() == '매도전': self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "") #파일 정보 변경 # buy list """for i, row_data in enumerate(buy_list): buy_list[i] = buy_list[i].replace("매수전", "주문완료")""" # file update f = open("buy_list.txt", 'wt') for row_data in buy_list: f.write(row_data) f.close() # sell list for i, row_data in enumerate(sell_list): sell_list[i] = sell_list[i].replace("매도전", "주문완료") # file update f = open("sell_list.txt", 'wt') for row_data in sell_list: f.write(row_data) f.close() def load_buy_sell_list(self): f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() f = open("sell_list.txt", 'rt') sell_list = f.readlines() f.close() row_count = len(buy_list) + len(sell_list) self.tableWidget_3.setRowCount(row_count) # buy list # j:행, i:열 for j in range(len(buy_list)): row_data = buy_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name( split_row_data[1].rstrip()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_3.setItem(j, i, item) # sell list for j in range(len(sell_list)): row_data = sell_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name( split_row_data[1].rstrip()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_3.setItem(len(buy_list) + j, i, item) self.tableWidget_3.resizeRowsToContents() def save_final_stock(self): item_count = len(self.kiwoom.opw00018_output['multi']) if (self.is_trading_time() == False): self.final_stock = [] for i in range(item_count): row = self.kiwoom.opw00018_output['multi'][i][3] self.final_stock.append(row) print(self.final_stock) #if(self.is_trading_time() == True): #종가 파일로 저장. def timeout(self): market_start_time = QTime(9, 0, 0) current_time = QTime.currentTime() if current_time > market_start_time and self.trade_stocks_done is False: self.trade_stocks() self.trade_stocks_done = True 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() 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") # opw0001TR (예수금 데이터) 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) # 나머지 칼럼 (table1) 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 get_ohlcv(self, code, start): #self.get_ohlcv("035720", "20190604") self.kiwoom.ohlcv = {'date': [], 'close': []} self.kiwoom.final = {'close': []} self.kiwoom.current = {'current': []} 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) #df = DataFrame(self.kiwoom.ohlcv, columns=['close'], # index=self.kiwoom.ohlcv['date']) #return self.kiwoom.ohlcv def run(self): true_close = [] true_current = [] code = [] today = datetime.datetime.today().strftime("%Y%m%d") f = open("buy_list.txt", 'rt') buy_list = f.readlines() for row_data in buy_list: split_row_data = row_data.split(';') code.append(split_row_data[1]) for i in range(len(code)): print("code: ", code[i]) self.get_ohlcv(code[i], today) true_close.append(self.kiwoom.final['close']) true_current.append(self.kiwoom.current['current']) print(true_close) f.close() return (true_close, true_current)
def __init__(self): self.kiwoom = Kiwoom.Kiwoom() self.kiwoom.comm_connect() self.get_code_list() #StockM이 실행되면 한 번만 수행하면 되기 때문에
class MyWindow(QMainWindow, form_class): # QMainWindow: QWidget 상속하는 클래스(위젯 사용할 수 있도록), form_class: pytrader.ui def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() # Kiwoom 인스턴스 생성 self.kiwoom.comm_connect() # 로그인 self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.timer2 = QTimer(self) self.timer2.start(1000 * 10) self.timer2.timeout.connect(self.timeout2) accouns_num = int( self.kiwoom.get_login_info("ACCOUNT_CNT")) # 보유계좌 갯수 (ex. 2) accounts = self.kiwoom.get_login_info( "ACCNO") # 구분자 ';'로 연결된 보유계좌 목록을 반환 (ex. 8165088111;8753740831;) accounts_list = accounts.split(';')[0:accouns_num] # 계좌번호를 리스트로 저장 self.comboBox.addItems(accounts_list) # 계좌번호를 comboBox에 넣음 self.lineEdit.textChanged.connect(self.code_changed) # 종목코드 입력시 self.pushButton.clicked.connect(self.send_order) # [현금주문] 버튼 누를시 self.pushButton_2.clicked.connect(self.check_balance) # [조회] 버튼 누를시 def code_changed(self): code = self.lineEdit.text() # 변경된 종목코드 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 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() 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()
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.lineEdit.textChanged.connect(self.code_changed) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) self.pushButton.clicked.connect(self.send_order) self.pushButton_2.clicked.connect(self.check_balance) 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 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 = "서버 연결 중" else: state_msg = "서버 미 연결 중" self.statusbar.showMessage(state_msg + " | " + time_msg) 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")
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.kiwoom.excelfile_initiator() self.kospi_codes = self.kiwoom.get_code_list_by_market(MARKET_KOSPI) self.kosdaq_codes = self.kiwoom.get_code_list_by_market(MARKET_KOSDAQ) self.candidate_codes = [ '005930', '252670', '122630', '000660', '207940', '035420', '006400', '035720', '005380', '034730', '036570', '017670', '105560', '096770', '090430', '097950', '018260', '003550', '006800', '078930' ] # There can be limits in the number of timers self.timer = QTimer(self) self.timer.start( 1000 * 10) # Timer for time update: refresh at every 10*1000ms self.timer.timeout.connect(self.timeout) # self.timer_balance_check = QTimer(self) # self.timer_balance_check.start(1000*10) # self.timer_balance_check.timeout.connect(self.check_balance) self.timer_autotrade_run = QTimer(self) self.timer_autotrade_run.start(1000 * AUTOTRADE_INTERVAL) self.timer_autotrade_run.timeout.connect(self.timeout_autotrade_run) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton.clicked.connect(self.send_order_ui) self.pushButton_2.clicked.connect(self.check_balance) self.pushButton_3.clicked.connect(self.timeout_autotrade_run) self.check_balance() def timeout(self): current_time = QTime.currentTime() text_time = current_time.toString("hh:mm") time_msg = "Time: " + text_time state = self.kiwoom.get_connect_state() if state == 1: state_msg = "Server Connected" else: state_msg = "Server Not Connected" self.statusbar.showMessage(state_msg + " | " + time_msg) def timeout_autotrade_run(self): current_time = QTime.currentTime() if RUN_AUTOTRADE and not RUN_ANYWAY_OUT_OF_MARKET_OPEN_TIME: if datetime.datetime.today().weekday() in range( 0, 5 ) and current_time > MARKET_START_TIME and current_time < MARKET_FINISH_TIME: self.autotrade_list_gen() self.trade_stocks() self.label_8.setText("Autotrade executed") else: self.label_8.setText("Market not open") elif RUN_AUTOTRADE: self.label_8.setText("Autotrade / market may not open") self.autotrade_list_gen() self.trade_stocks() else: self.label_8.setText("Autotrade disabled") def code_changed(self): code = self.lineEdit.text() if len(code) >= CODE_MIN_LENGTH: name = self.kiwoom.get_master_code_name(code) if name != "": self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "1001") self.lineEdit_2.setText(name) self.spinBox_2.setValue(self.kiwoom.cur_price) else: self.lineEdit_2.setText("") self.spinBox_2.setValue(0) else: self.lineEdit_2.setText("") self.spinBox_2.setValue(0) def send_order_ui(self): order_type_lookup = {'Buy': 1, 'Sell': 2} account = self.comboBox.currentText() order_type = self.comboBox_2.currentText() code = self.lineEdit.text() hoga = HOGA_LOOKUP[self.comboBox_3.currentText()] num = self.spinBox.value() if hoga == "00": price = self.spinBox_2.value() elif hoga == "03": price = 0 res = self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga, "") if res[0] == 0 and res[1] != "": self.label_8.setText("Order sent") ################################### if self.kiwoom.order_chejan_finished == True: self.label_8.setText("Order completed") else: self.label_8.setText("Errer in order processing") def check_balance(self): 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: 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 load_buy_sell_list(self): try: buy_list = pd.read_excel(EXCEL_BUY_LIST, index_col=None, converters={'Code': str}) except Exception as e: print(e) buy_list = pd.DataFrame() try: sell_list = pd.read_excel(EXCEL_SELL_LIST, index_col=None, converters={'Code': str}) except Exception as e: print(e) sell_list = pd.DataFrame() return [buy_list, sell_list] ########################################################################### ##### EXECUTION ########################################################################### def trade_stocks(self): [buy_list, sell_list] = self.load_buy_sell_list() # account account = self.comboBox.currentText() buy_order = 1 sell_order = 2 # buy_list for i in buy_list.index: if buy_list["Tr"][i] == 'yet' or buy_list["Tr"][i] == 'failed': hoga = HOGA_LOOKUP[buy_list["Order_type"][i]] if hoga == "00": price = buy_list["Price"][i] elif hoga == "03": price = 0 res = self.kiwoom.send_order("send_order_req", "0101", account, buy_order, buy_list["Code"][i], int(buy_list["Amount"][i]), price, hoga, "") if res[0] == 0 and res[1] != "": self.label_8.setText("Order sent: " + str(res[1])) buy_list.at[i, "Tr"] = 'ordered' ################################### if self.kiwoom.order_chejan_finished == True: buy_list.at[i, "Tr"] = 'done' else: self.label_8.setText("Errer in order processing") buy_list.at[i, "Tr"] = 'failed' buy_list.to_excel(EXCEL_BUY_LIST, index=False) # sell_list for i in sell_list.index: if sell_list["Tr"][i] == 'yet' or sell_list["Tr"][i] == 'failed': hoga = HOGA_LOOKUP[sell_list["Order_type"][i]] if hoga == "00": price = sell_list["Price"][i] elif hoga == "03": price = 0 res = self.kiwoom.send_order("send_order_req", "0101", account, sell_order, sell_list["Code"][i], int(sell_list["Amount"][i]), price, hoga, "") if res[0] == 0 and res[1] != "": self.label_8.setText("Order sent: " + str(res[1])) sell_list.at[i, "Tr"] = 'ordered' ################################### if self.kiwoom.order_chejan_finished == True: buy_list.at[i, "Tr"] = 'done' else: self.label_8.setText("Errer in order processing") sell_list.at[i, "Tr"] = 'failed' sell_list.to_excel(EXCEL_SELL_LIST, index=False) ########################################################################### ##### ALGORITHMS ########################################################################### def autotrade_list_gen(self): [code, price] = self.algo_random_choose_buy(3) # sell_list = self.algo_random_choose_sell(3) sell_list = self.algo_sell_by_return_range(10, -1) self.kiwoom.update_buy_list(code, price) self.kiwoom.update_sell_list(sell_list) def check_speedy_rising_volume(self, code): today = datetime.datetime.today().strftime("%Y%m%d") df = self.kiwoom.get_ohlcv(code, today) volumes = df['volume'] if len(volumes) < 21: return False sum_vol20 = 0 today_vol = 0 for i, vol in enumerate(volumes): if i == 0: today_vol = vol elif 1 <= i <= 20: sum_vol20 += vol else: break avg_vol20 = sum_vol20 / 20 if today_vol > avg_vol20 * 3: return True return False def algo_speedy_rising_volume(self): buy_list_code = [] for i, code in enumerate(self.kosdaq_codes): if self.check_speedy_rising_volume(code): buy_list_code.append(code) return buy_list_code def algo_random_choose_buy(self, BUY_SELL_SIZE): buy_list_code = [] buy_list_price = [] for i in range(BUY_SELL_SIZE): code = random.choice(self.candidate_codes) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "1001") name = self.kiwoom.get_master_code_name(code) price = self.kiwoom.cur_price if price > MIN_STOCK_PRICE: buy_list_code.append(code) buy_list_price.append(price) return [buy_list_code, buy_list_price] def algo_random_choose_sell(self, BUY_SELL_SIZE): my_stock_list = self.kiwoom.get_my_stock_list() if len(my_stock_list) > BUY_SELL_SIZE: n = list(range(len(my_stock_list))) set_to_sell = random.sample(n, BUY_SELL_SIZE) return my_stock_list.iloc[set_to_sell] else: return my_stock_list def algo_sell_by_return_range( self, upperlimit, lowerlimit): # upperlimit, lowerlimit in percentage my_stocks = self.kiwoom.get_my_stock_list() profit_sell_list = my_stocks[my_stocks['earning_rate'] > upperlimit] loss_sell_list = my_stocks[my_stocks['earning_rate'] < lowerlimit] print('Profit Sell List (up to 50 items): \n', tabulate(profit_sell_list[:50], headers='keys', tablefmt='psql')) print('Loss Sell List (up to 50 items): \n', tabulate(loss_sell_list[:50], headers='keys', tablefmt='psql')) return profit_sell_list.append(loss_sell_list)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.timer2 = QTimer(self) self.timer2.start(1000 *10) self.timer2.timeout.connect(self.timeout2) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] 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) 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 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() 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()
class Pymon: def __init__(self): self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.get_code_list() self.excelfile_initiator() def get_code_list(self): self.kospi_codes = self.kiwoom.get_code_list_by_market(MARKET_KOSPI) self.kosdaq_codes = self.kiwoom.get_code_list_by_market(MARKET_KOSDAQ) def get_ohlcv(self, code, start): 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") df = pd.DataFrame(self.kiwoom.ohlcv, columns=['open', 'high', 'low', 'close', 'volume'], index=self.kiwoom.ohlcv['date']) return df def update_buy_list(self, buy_list_code): buy_list = pd.read_excel(EXCEL_BUY_LIST, index_col=None, converters={'Code': str}) for i, code in enumerate(buy_list_code): name = self.kiwoom.get_master_code_name(code) today = datetime.datetime.today().strftime("%Y%m%d") time_ = datetime.datetime.now().strftime("%H:%M:%S") self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "1001") amount = round(ALLOCATION_SIZE / self.kiwoom.cur_price) buy_list = buy_list.append( { 'Date': today, 'Time': time_, 'Name': name, 'Code': code, 'Order_type': 'mkt', 'Tr': 'yet', 'Price': self.kiwoom.cur_price, 'Amount': amount }, ignore_index=True) print('Buy List: \n', tabulate(buy_list, headers='keys', tablefmt='psql')) buy_list.to_excel(EXCEL_BUY_LIST, index=False) def get_stock_list(self): 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: self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") stock_list = pd.DataFrame(self.kiwoom.opw00018_rawoutput, columns=[ 'name', 'code', 'quantity', 'purchase_price', 'current_price', 'invested_amount', 'current_total', 'eval_profit_loss_price', 'earning_rate' ]) for i in stock_list.index: stock_list.at[i, 'code'] = stock_list['code'][i][ 1:] # taking off "A" in front of returned code return stock_list.set_index('code') def update_sell_list(self, sell_list_code): sell_list = pd.read_excel(EXCEL_SELL_LIST, index_col=None, converters={'Code': str}) stock_list = self.get_stock_list() for i, code in enumerate(sell_list_code): if code in list(stock_list.index): name = self.kiwoom.get_master_code_name(code) today = datetime.datetime.today().strftime("%Y%m%d") time_ = datetime.datetime.now().strftime("%H:%M:%S") self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "1001") # getting current price amount = stock_list['quantity'][code] sell_list = sell_list.append( { 'Date': today, 'Time': time_, 'Name': name, 'Code': code, 'Order_type': 'mkt', 'Tr': 'yet', 'Price': self.kiwoom.cur_price, 'Amount': amount }, ignore_index=True) print('Sell List: \n', tabulate(sell_list, headers='keys', tablefmt='psql')) sell_list.to_excel(EXCEL_SELL_LIST, index=False) def excelfile_initiator(self): if not os.path.exists(EXCEL_BUY_LIST): # create buy list bl = xlsxwriter.Workbook(EXCEL_BUY_LIST) blws = bl.add_worksheet() blws.write('A1', 'Date') # Date / Time when the item is added blws.write('B1', 'Time') blws.write('C1', 'Name') blws.write('D1', 'Code') blws.write('E1', 'Order_type') # 시장가 ('mkt') vs 지정가 ('fixed') blws.write('F1', 'Tr') # yet: not, done: done blws.write('G1', 'Price') # latest price when the list is populated blws.write('H1', 'Amount') # blws.write('I1', 'Invested_total') # Before any fee and tax # blws.write('J1', 'Date_Trans') # Date / Time when the item is purchased # blws.write('K1', 'Time_Trans') bl.close() if not os.path.exists(EXCEL_SELL_LIST): # create sell list sl = xlsxwriter.Workbook(EXCEL_SELL_LIST) slws = sl.add_worksheet() slws.write('A1', 'Date') # Date / Time when the item is added slws.write('B1', 'Time') slws.write('C1', 'Name') slws.write('D1', 'Code') slws.write('E1', 'Order_type') # 시장가 ('mkt') vs 지정가 ('fixed') slws.write('F1', 'Tr') # yet: not, done: done slws.write('G1', 'Price') # latest price when the list is populated slws.write('H1', 'Amount') # Amount to sell # slws.write('I1', 'Fee_Tax') # slws.write('J1', 'Harvested_total') # After fee and tax # slws.write('K1', 'Date_Trans') # Date / Time when the item is purchased # slws.write('L1', 'Time_Trans') sl.close() ########################################################################### ##### ALGORITHMS ########################################################################### def check_speedy_rising_volume(self, code): today = datetime.datetime.today().strftime("%Y%m%d") df = self.get_ohlcv(code, today) volumes = df['volume'] if len(volumes) < 21: return False sum_vol20 = 0 today_vol = 0 for i, vol in enumerate(volumes): if i == 0: today_vol = vol elif 1 <= i <= 20: sum_vol20 += vol else: break avg_vol20 = sum_vol20 / 20 if today_vol > avg_vol20 * 3: return True return False def algo_speedy_rising_volume(self): buy_list_code = [] for i, code in enumerate(self.kosdaq_codes): if self.check_speedy_rising_volume(code): buy_list_code.append(code) return buy_list_code ########################################################################### ##### EXECUTION ########################################################################### def run(self): # has to return True if the list is updated current_time = QTime.currentTime() # Timer while datetime.datetime.today().weekday() in range( 0, 5 ) and current_time > MARKET_START_TIME and current_time < MARKET_FINISH_TIME: # Algo buy_list_code = [] buy_list_code.append(random.choice(self.kospi_codes)) buy_list_code.append(random.choice(self.kospi_codes)) buy_list_code.append(random.choice(self.kospi_codes)) buy_list_code.append(random.choice(self.kospi_codes)) buy_list_code.append(random.choice(self.kospi_codes)) stock_list_codelist = self.get_stock_list().index.tolist() sell_list_code = [] sell_list_code.append(random.choice(stock_list_codelist)) sell_list_code.append(random.choice(stock_list_codelist)) sell_list_code.append(random.choice(stock_list_codelist)) sell_list_code.append(random.choice(stock_list_codelist)) sell_list_code.append(random.choice(stock_list_codelist)) pymon.update_buy_list(buy_list_code) pymon.update_sell_list(sell_list_code) # Checking time.sleep(AUTOTRADE_INTERVAL) current_time = QTime.currentTime() print(current_time.toString("hh:mm:ss"))
def __init__(self): super().__init__() self.kiwoom = Kiwoom() self.kiwoom.comm_connect()
class MainWindow(QMainWindow, gui): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.commConnect() # get user account ID/PW self.account = [] with open("account.txt", 'r') as f: self.account = f.readlines() # get account info account_cnt = int(self.kiwoom.getLoginInfo("ACCOUNT_CNT")) account_no = self.kiwoom.getLoginInfo("ACCNO") account_list = account_no.split(';')[0:account_cnt] # timer in status bar self.timer_status_bar = QTimer(self) self.timer_status_bar.start(1000) self.timer_status_bar.timeout.connect(self.timeoutStatusBar) # timer in table widgets self.timer_table = QTimer(self) self.timer_table.start(10000) self.timer_table.timeout.connect(self.timeoutBalanceTable) # Window forms self.qtOrder_comboBox_account.addItems(account_list) self.qtOrder_lineEdit_item.textChanged.connect(self.itemCodeChanged) self.qtOrder_pushButton_sendOrder.clicked.connect(self.sendOrder) self.qtTrade_pushButton_check.clicked.connect(self.checkBalance) # execute methods # self.conductBuySell() # 현재 '주문완료' 전 일 경우 shutdown 오류 발생 self.loadBuySellList() self.saveDayData() # DB df = pd.DataFrame(self.kiwoom.ohlcv, self.kiwoom.ohlcv['date'], ['open', 'high', 'low', 'close']) con = sqlite3.connect("stock.db") df.to_sql('039490', con, if_exists='replace') def timeoutStatusBar(self): current_time = QTime.currentTime() text_time = current_time.toString("ap h시 m분 s초") time_msg = "현재시간 : " + text_time if self.kiwoom.getConnectState() == 1: state_msg = "서버 접속 중" else: state_msg = "서버 끊김" self.statusBar = QStatusBar(self) self.setStatusBar(self.statusBar) self.statusBar.showMessage(state_msg + " | " + time_msg) def timeoutBalanceTable(self): if self.qtTrade_checkBox_realtime.isChecked() == True: self.checkBalance() else: pass def itemCodeChanged(self): """ print item code by hangul """ code = self.qtOrder_lineEdit_item.text() name = self.kiwoom.getMasterCodeName(code) self.qtOrder_lineEdit_code.setText(name) def sendOrder(self): order_type_lookup = {"신규매수": 1, "신규매도": 2, "매수취소": 3, "매도취소": 4} bid_lookup = {"지정가": "00", "시장가": "03"} account = self.qtOrder_comboBox_account.currentText() order_type = self.qtOrder_comboBox_order.currentText() code = self.qtOrder_lineEdit_item.text() bid = self.qtOrder_comboBox_type.currentText() num = self.qtOrder_spinBox_qty.value() price = self.qtOrder_spinBox_price.value() self.kiwoom.sendOrder("sendOrder_req", "0101", account, order_type_lookup[order_type], code, num, price, bid_lookup[bid], "") def checkBalance(self): current_account = self.qtOrder_comboBox_account.currentText() # request opw00001 : 예수금상세현황요청 self.kiwoom.setInputValue("계좌번호", current_account) self.kiwoom.setInputValue("비밀번호", self.account[1]) self.kiwoom.commRqData("opw00001_req", "opw00001", 0, "2000") # request opw00018 : 계좌평가잔고내역요청 self.kiwoom.setInputValue("계좌번호", current_account) self.kiwoom.setInputValue("비밀번호", self.account[1]) self.kiwoom.commRqData("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.prev_next == '2': time.sleep(0.2) self.kiwoom.setInputValue("계좌번호", current_account) self.kiwoom.setInputValue("비밀번호", self.account[1]) self.kiwoom.commRqData("opw00018_req", "opw00018", 2, "2000") # print balance at table item = QTableWidgetItem(self.kiwoom.opw00001_data) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.qtTrade_tableWidget.setItem(0, 0, item) for i in range(len(self.kiwoom.opw00018_data['single'])): item = QTableWidgetItem(self.kiwoom.opw00018_data['single'][i]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.qtTrade_tableWidget.setItem(0, i + 1, item) self.qtTrade_tableWidget.resizeRowsToContents() # print own stock items at table item_cnt = len(self.kiwoom.opw00018_data['multi']) self.qtTrade_tableWidget2.setRowCount(item_cnt) for i in range(item_cnt): row = self.kiwoom.opw00018_data['multi'][i] for j in range(len(row)): item = QTableWidgetItem(row[j]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.qtTrade_tableWidget2.setItem(i, j, item) self.kiwoom.opw00018_data['multi'] = [] self.qtTrade_tableWidget2.resizeRowsToContents() def saveDayData(self): self.kiwoom.setInputValue("종목코드", "039490") self.kiwoom.setInputValue("기준일자", "20170123") self.kiwoom.setInputValue("수정주가구분", 1) self.kiwoom.commRqData("opt10081_req", "opt10081", 0, "0001") while self.kiwoom.prev_next == '2': self.kiwoom.setInputValue("종목코드", "039490") self.kiwoom.setInputValue("기준일자", "20170123") self.kiwoom.setInputValue("수정주가구분", 1) self.kiwoom.commRqData("opt10081_req", "opt10081", 2, "0001") def loadBuySellList(self): # read list from files f = open("buy_list.txt", "rt") buy_list = f.readlines() f.close() f = open("sell_list.txt", "rt") sell_list = f.readlines() f.close() # set table row row_count = len(buy_list) + len(sell_list) self.qtAutoList_tableWidget.setRowCount(row_count) # buy list for i in range(len(buy_list)): data = buy_list[i] split_data = data.split(';') for j in range(len(split_data)): if j == 1: name = self.kiwoom.getMasterCodeName( split_data[j].rstrip()) item = QTableWidgetItem(name) else: item = QTableWidgetItem(split_data[j].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.qtAutoList_tableWidget.setItem(i, j, item) # sell list for i in range(len(sell_list)): data = sell_list[i] split_data = data.split(';') for j in range(len(split_data)): if j == 1: name = self.kiwoom.getMasterCodeName( split_data[j].rstrip()) item = QTableWidgetItem(name) else: item = QTableWidgetItem(split_data[j].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.qtAutoList_tableWidget.setItem(len(buy_list) + i, j, item) self.qtAutoList_tableWidget.resizeRowsToContents() def conductBuySell(self): bid_lookup = {'지정가': "00", '시장가': "03"} # read list from files f = open("buy_list.txt", "rt") buy_list = f.readlines() f.close() f = open("sell_list.txt", "rt") sell_list = f.readlines() f.close() # get current account account = self.qtOrder_comboBox_account.currentText() # buy for data in buy_list: split_data = data.split(';') code = split_data[1] bid = split_data[2] num = split_data[3] price = split_data[4] if split_data[-1].rstrip() == '매수전': self.kiwoom.sendOrder('sendOrder_req', '0101', account, 1, code, num, price, bid_lookup[bid], '') # update buy list file for i, data in enumerate(buy_list): buy_list[i] = buy_list[i].replace('매수전', '주문완료') f = open('buy_list.txt', 'wt') for data in buy_list: f.write(data) f.close() # sell for data in sell_list: split_data = data.split(';') code = split_data[1] bid = split_data[2] num = split_data[3] price = split_data[4] if split_data[-1].rstrip() == '매도전': self.kiwoom.sendOrder('sendOrder_req', '0101', account, 2, code, num, price, bid_lookup[bid], '') # update sell list file for i, data in enumerate(sell_list): sell_list[i] = sell_list[i].replace('매도전', '주문완료') f = open('sell_list.txt', 'wt') for data in buy_list: f.write(data) f.close()
def __init__(self): self.ki = kw.Kiwoom() self.dB = db.StockDB() self.date = date.today() - timedelta(1)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False self.bucket = list() self.item_list = list() self.code_list = list() self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer2 = QTimer(self) self.timer2.start(1000 * 10) 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] self.comboBox.addItems(accounts_list) self.comboBox_2.addItems(accounts_list) self.codeLineEdit.textChanged.connect(self.code_changed) self.codeLineEdit_2.textChanged.connect(self.code_changed_2) self.viewButton.clicked.connect(self.check_balance) self.resetButton.clicked.connect(self.reset_bucket) self.addButton.clicked.connect(self.add_to_bucket) self.showButton.clicked.connect(self.show_bucket) self.downButton.clicked.connect(self.download_data) self.optButton.clicked.connect(self.optimize_weights) self.sendButton.clicked.connect(self.send_initial_order) self.spinBox.valueChanged.connect(self.asset_num) self.LogDisplay = LogDisplay(self) def send_order(self): order_type_lookup = { 'Buying': 1, 'Selling': 2, 'Cancel Buying': 3, 'Cancel Selling': 4 } hoga_lookup = {'Limit': "00", 'Market': "03"} account = self.comboBox_2.currentText() order_type = self.comboBox_3.currentText() code2 = self.codeLineEdit_2.text() hoga = self.comboBox_4.currentText() num = self.spinBox_2.value() price = self.spinBox_3.value() self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code2, num, price, hoga_lookup[hoga], "") def timeout2(self): if self.checkBox.isChecked(): self.check_balance() 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") # 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() # my portfolio def code_changed(self): code = self.codeLineEdit.text() name = self.kiwoom.get_master_code_name(code) self.nameLineEdit.setText(name) # manual order def code_changed_2(self): code2 = self.codeLineEdit_2.text() name = self.kiwoom.get_master_code_name(code2) self.nameLineEdit_2.setText(name) def asset_num(self): self.num = self.spinBox.value() def reset_bucket(self): self.bucket = list() self.item_list = list() self.code_list = list() def add_to_bucket(self): code = self.codeLineEdit.text() name = self.kiwoom.get_master_code_name(code) self.nameLineEdit.setText(name) self.bucket.append([code, name]) def show_bucket(self): item_count = len(self.bucket) print(self.num) if self.num != item_count: QMessageBox.about( self, "Warning!", "Item # is different from the number of assets added to your bucket!" ) return account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] self.kiwoom.set_input_value("계좌번호", account_number) # Item list self.bucketTable.setRowCount(item_count) for j in range(item_count): row = self.bucket[j] self.code_list.append(row[0]) self.item_list.append(row[1]) for i in range(len(row)): item = QTableWidgetItem(row[i]) self.bucketTable.setItem(j, i, item) self.bucketTable.resizeRowsToContents() def download_data(self): account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] self.kiwoom.set_input_value("계좌번호", account_number) for code in self.code_list: self.kiwoom.get_ohlcv(code) QMessageBox.about(self, "Notification", "Download Completed") def optimize_weights(self): self.po = PortfolioOptimizer(self.code_list) QMessageBox.about(self, "Notification", "Calculation Completed") def send_initial_order(self): df = self.po.init_buy_list.reset_index() print("****** Proceeding my initial order ******") account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] self.kiwoom.set_input_value("계좌번호", account_number) for i in range(len(df)): print( "{name}({code}) buy {quantity}".format(name=df.iloc[i][1], code=df.iloc[i][0], quantity=df.iloc[i][5])) self.kiwoom.send_order('order_req', '0101', account_number, 1, df.iloc[i][0], df.iloc[i][5], 0, '03', '') print("succeeded") QMessageBox.about(self, "Notification", "Order Completed") def display_log(self): self.LogDisplay()
def __init__(self): self.kiwoom = Kiwoom.Kiwoom() self.kiwoom.comm_connect() self.get_code_list()
def __init__(self): self.kiwoom = Kiwoom.Kiwoom() self.kiwoom.comm_connect() self.get_code_list() self.my = Mysql() self.my.connect(MYSQL)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.tr = 0 #총TR요청횟수 #텔레그램봇 my_token = '692301814:AAEfmddhyZPcO0Uzh8r5ZehfooTPOvKOOqc' self.mybot = telegram.Bot(token=my_token) self.chat_id = 544924927 self.kiwoom = Kiwoom() #키움인스턴스 생성 self.kiwoom.comm_connect() #API로그인 self.ts_1_p = 'False' #거래전략1 초기값 # Timer1 self.timer = QTimer(self) self.timer.start(1000) #1초 상태바 self.timer.timeout.connect(self.timeout) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 25) #25초 잔고조회 self.timer2.timeout.connect(self.timeout2) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 30) #30초 매수전략1 self.timer3.timeout.connect(self.timeout3) # Timer4 self.timer4 = QTimer(self) self.timer4.start(1000 * 33) # 33초 매도전략 self.timer4.timeout.connect(self.timeout4) # Timer5 self.volume_start = 'false' self.timer5 = QTimer(self) #self.timer5.start(1000 * 60) # 60초 9시에 급등주알고리즘 시작하기 #self.timer5.timeout.connect(self.timeout5) # Timer7 self.timer7 = QTimer(self) self.timer7.start(1000 * 1800) # 30분 중간보고 self.timer7.timeout.connect(self.timeout7) self.list700 = [] self.list600 = [] self.buy_list = [] #버튼, 이벤트발생 self.lineEdit.textChanged.connect(self.code_changed) #종목코드 입력시 self.pushButton.clicked.connect(self.send_order) #현금주문 버튼 클릭시 self.pushButton_2.clicked.connect(self.check_balance) #계좌정보 조회 self.pushButton_3.clicked.connect(self.trading_strategy_1) #거래전략1호 self.pushButton_4.clicked.connect(self.quit_app) #앱종료 self.pushButton_4.clicked.connect( QCoreApplication.instance().quit) # 앱종료 self.pushButton_5.clicked.connect(self.test_button) # 테스트버튼 #계좌정보 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) #프로그램시작알림 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "\n프로그램이 시작되었습니다.") def test_button(self): self.timeout7() #종료 def quit_app(self): #계좌정보요청 self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 bb = self.kiwoom.opw00018_output['single'] myaccount = '총매입금액: %s원\n총평가금액: %s원\n총평가손익금액: %s원\n총수익률(%%): %s\n추정예탁자산: %s원' % ( bb[0], bb[1], bb[2], bb[3], bb[4]) a = len(self.kiwoom.opw00018_output['multi']) if a != 0: name = [] num = [] buy = [] price = [] earn = [] ret = [] for i in range(a): name.append(self.kiwoom.opw00018_output['multi'][i][0]) num.append(self.kiwoom.opw00018_output['multi'][i][1]) buy.append(self.kiwoom.opw00018_output['multi'][i][2]) price.append(self.kiwoom.opw00018_output['multi'][i][3]) earn.append(self.kiwoom.opw00018_output['multi'][i][4]) ret.append(self.kiwoom.opw00018_output['multi'][i][5]) mystocks = { '종목': name, '수량': num, '매입가': buy, '현재가': price, '평가손익': earn, '수익률(%)': ret } mystocks = DataFrame(mystocks) mystocks = mystocks.set_index(['종목']) #last 보고 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 프로그램이 종료되었습니다.") self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "\n프로그램이 종료되었습니다.\n총 TR 요청 횟수 : %d회\n -----계좌현황-----\n%s\n -----보유종목-----\n%s" % (self.tr, myaccount, mystocks)) time.sleep(3) #상태표시줄(현재시간, 서버연결상태) 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 = "서버가 연결되었습니다." else: state_msg = "서버가 연결되지 않았습니다." self.statusbar.showMessage(state_msg + " | " + time_msg) def timeout2(self): if self.checkBox.isChecked(): self.check_balance() #계좌정보 실시간 조회 def timeout3(self): if self.ts_1_p == 'True': #매수전략1 진행시 30초마다 조회 self.volume_check() def timeout4(self): self.sell_stocks() #매도전략 def timeout5(self): #9시 이후에 급등주알고리즘 시작 market_start_time = QTime(9, 5, 0) current_time = QTime.currentTime() if current_time > market_start_time and self.volume_start == 'false': self.volume_start = 'true' self.trading_strategy_1() def timeout7(self): #중간보고 self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 bb = self.kiwoom.opw00018_output['single'] myaccount = '총매입금액: %s원\n총평가금액: %s원\n총평가손익금액: %s원\n총수익률(%%): %s\n추정예탁자산: %s원' % ( bb[0], bb[1], bb[2], bb[3], bb[4]) print(myaccount) a = len(self.kiwoom.opw00018_output['multi']) if a != 0: name = [] num = [] buy = [] price = [] earn = [] ret = [] for i in range(a): name.append(self.kiwoom.opw00018_output['multi'][i][0]) num.append(self.kiwoom.opw00018_output['multi'][i][1]) buy.append(self.kiwoom.opw00018_output['multi'][i][2]) price.append(self.kiwoom.opw00018_output['multi'][i][3]) earn.append(self.kiwoom.opw00018_output['multi'][i][4]) ret.append(self.kiwoom.opw00018_output['multi'][i][5]) mystocks = { '종목': name, '수량': num, '매입가': buy, '현재가': price, '평가손익': earn, '수익률(%)': ret } mystocks = DataFrame(mystocks) mystocks = mystocks.set_index(['종목']) print(mystocks) # 중간보고 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 중간보고 완료.") print('hi') self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "\n--------중간보고--------\n총 TR 요청 횟수 : %d회\n --------계좌현황--------\n%s\n --------보유종목--------\n%s" % (self.tr, myaccount, mystocks)) #종목명 나타내기 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], "") self.tr += 1 #계좌정보 def check_balance(self): self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() 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.tr += 1 # opw00001 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") self.tr += 1 # 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() print('잔고조회완료') #거래량급증 거래전략1 def trading_strategy_1(self): if self.ts_1_p == 'False': print('ts_1_p = true, 매수전략1 실행중입니다.') self.ts_1_p = 'True' self.label_7.setText("진행중...") self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 시작되었습니다.") self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 시작되었습니다.") self.volume_check() elif self.ts_1_p == 'True': print('ts_1_p = False, 매수전략1 중지되었습니다.') self.label_7.setText("") self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 중지되었습니다.") self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 중지되었습니다.") self.ts_1_p = 'False' #매수,매도주문 def order_stocks(self, bs, code, num, price, set_price): ''' :param bs: 매수=1 매도=2 :param code: 종목코드 :param num: 수량 :param price: 가격 (시장가이면 0) :param set_price: 지정가=00 시장가=03 :return: ''' account = self.comboBox.currentText() # order self.kiwoom.send_order("send_order_req", "0101", account, bs, code, num, price, set_price, "") self.tr += 1 #거래량급증 조회 def volume_check(self): market_list = ['kospi', 'kosdaq'] print('조회수급등조회시작') for market in market_list: if market == 'kospi': url = 'https://finance.naver.com/sise/sise_quant_high.nhn' elif market == 'kosdaq': url = 'https://finance.naver.com/sise/sise_quant_high.nhn?sosok=1' html = requests.get(url).text df = pd.DataFrame() df = df.append(pd.read_html(html, header=0)[1]) df = df.dropna() df = df.rename( columns={ 'N': 'num', '증가율': 'rate', '종목명': 'name', '현재가': 'price', '전일비': 'diff', '등락률': 'updown', '매수호가': 'buy_hoga', '매도호가': 'sell_hoga', '거래량': 'volume', '전일거래량': 'yes_volume', 'PER': 'PER' }) df = df.set_index(['num']) #크롤링완료 #700이상 df700 = df[[a > 700 for a in df.rate]] a700 = list(df700['name']) if len(df700) != 0: for i in range(len(df700)): a = html.find(a700[i]) code = html[a - 22:a - 16] self.list700.append(code) #교집합 구하기 aa = set(self.list700) bb = set(self.list600) buy_set = aa & bb buy_set = list(buy_set) if len(buy_set) != 0: for i in range(len(buy_set)): self.buy_list.append(buy_set[i]) #600~700 self.list600 = [] df600 = df[[a > 400 and a < 700 for a in df.rate]] a600 = list(df600['name']) if len(df600) != 0: for i in range(len(df600)): a = html.find(a600[i]) code = html[a - 22:a - 16] self.list600.append(code) print('매수리스트: %s' % self.buy_list) #order if len(self.buy_list) == 0: pass else: account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") buy_q = int(self.kiwoom.d2_deposit[:-3].replace(',', '')) buy_q = (buy_q // len(self.buy_list)) // 5 #예수금/선정종목갯수/5 self.tr += 1 for code in self.buy_list: time.sleep(0.5) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") self.tr += 1 self.order_stocks(1, code, buy_q, 0, '03') self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매수주문\n종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, buy_q)) self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString('hh:mm:ss') + 'ㅣ매수주문\n 종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, buy_q)) self.buy_list = [] self.list700 = [] print("거래량급증조회완료") #목표수익률 도달시 팔기 def sell_stocks(self): self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 list_1 = list(self.kiwoom.opw00018_output['multi']) a = len(list_1) if a != 0: print('보유종목현황: %s' % list_1) for i in range(a): if float(list_1[i][5]) > 5: code = list_1[i][6] num = int(list_1[i][1].replace('.00', '').replace(',', '')) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") self.tr += 1 self.order_stocks(2, code, num, 0, '03') print('매도종목: %s' % code) self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n 종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, num)) self.textEdit.append( QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n 종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, num)) elif float(list_1[i][5]) < -3: code = list_1[i][6] num = int(list_1[i][1].replace('.00', '').replace(',', '')) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") self.tr += 1 print('매도종목: %s' % code) self.order_stocks(2, code, num, 0, '03') self.mybot.sendMessage( self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n 종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, num)) self.textEdit.append( QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n 종목: %s\n수량: %d\n가격: 시장가' % (self.kiwoom.stock_name, num))
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False # 자동 trading False이면 작동 self.kiwoom = Kiwoom() self.kiwoom.comm_connect() # 전략 self.stratagy = SysStratagy() # Timer1 self.timer = QTimer(self) self.timer.start(1000 * 5) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 10) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 10) # Timer4 손절처리를 위한 Timer 설정 self.timer4 = QTimer(self) self.timer4.start(1000 * 60) # Naver에서 현재가 가져오기 self.timer_naver = QTimer(self) self.timer_naver.start(1000 * 4) # Naver에서 현재가 가져오기 self.timer_rate = QTimer(self) self.timer_rate.start(1000 * 3) # 계좌정보 넣어줌 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) # 보유 종목정보 self.boyou_stock_list = [] self.check_balance() self.init_boyou_stock_list = self.kiwoom.opw00018_output['multi'] self.boyou_stock_list = self.init_boyou_stock_list # self.boyou_stock_list.append(['삼성전자', '100', '40000', '42000', '200000', '5', '005930']) # 아침에 보유주식 매도기능 주석처리함.. 보유주식 정보에서 처리하면 되므로 2019.05.19 # 보유 주식 매도 주문 아침9시전에 구동시에 보유주식에 대한 매도주문처리 # self.init_boyou_mado() # 매도/매수 리스트 조회 self.load_buy_sell_list() # 보유주식정보 json으로 저장 self.boyoustock = BoyouStock() self.boyou_stock_save_json() # 이벤트 정보 연결 self.timer.timeout.connect(self.timeout) self.timer2.timeout.connect(self.timeout2) self.timer3.timeout.connect(self.timeout3) self.timer4.timeout.connect( self.timeout4) # stop loss 처리 # 보유주식정보 가져오는 것으로 수정함.2019.05.19 self.timer_naver.timeout.connect(self.timeout_naver) self.timer_rate.timeout.connect(self.timeout_rate) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton.clicked.connect(self.send_order) self.pushButton_2.clicked.connect( self.check_balance_Widget ) # pushButton_2 라는 객체가 클릭될 때 check_balance라는 메서드가 호출 # 손절,익절률 설정 값 읽어오기 config = self.boyoustock.readConfig() if len(config) > 0: self.stop_profit_rate = (config["stop_profit_rate"] / 100) + 1 self.stop_loss_rate = 1 - (config["stop_loss_rate"] / 100) self.spinBox_6.setValue(config["stop_profit_rate"]) self.spinBox_7.setValue(config["stop_loss_rate"]) else: self.stop_profit_rate = (self.spinBox_6.value() / 100) + 1 self.stop_loss_rate = 1 - (self.spinBox_7.value() / 100) print("초기 설정 익절률: " + str(self.stop_profit_rate)) print("초기 설정 손절률: " + str(self.stop_loss_rate)) def init_boyou_mado(self): market_start_time = QTime(9, 0, 0) current_time = QTime.currentTime() # self.init_maedo_proc() if current_time < market_start_time: # 보유종목 매도 처리.. self.init_maedo_proc() else: print("보유주식에 대한 매도주문은 9시전에만 가능함.") def timeout(self): # market_start_time = QTime(8, 0, 0) # market_end_time = QTime(19, 0, 0) current_time = QTime.currentTime() if self.stratagy.isTimeAvalable(self.kiwoom.maesu_start_time, self.kiwoom.maesu_end_time ) and self.trade_stocks_done is False: self.trade_stocks() # self.trade_stocks_done = True else: print("지금은 거래 가능한 시간이 아닙니다.") self.kiwoom.comm_terminate() sys.exit(1) 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_Widget() def timeout3(self): if self.checkBox_2.isChecked(): self.load_buy_sell_list() def timeout4(self): self.boyoustock.readBoyouStockInfo() # if self.checkBox_3.isChecked(): # 일단주석처리. # self.stock_stop_loss() def timeout_naver(self): self.cur_stock_price_naver() def timeout_rate(self): config = {} profit = (self.spinBox_6.value() / 100) + 1 loss = 1 - (self.spinBox_7.value() / 100) if self.stop_profit_rate != profit: self.stop_profit_rate = profit self.spinBox_6.setValue(self.spinBox_6.value()) config["stop_profit_rate"] = self.spinBox_6.value() config["stop_loss_rate"] = self.spinBox_7.value() self.boyoustock.updateConfig(config) print("익절률이 변경되었습니다. TO " + str(profit)) if self.stop_loss_rate != loss: self.stop_loss_rate = loss self.spinBox_7.setValue(self.spinBox_7.value()) config["stop_profit_rate"] = self.spinBox_6.value() config["stop_loss_rate"] = self.spinBox_7.value() self.boyoustock.updateConfig(config) print("손절률이 변경되었습니다. TO " + str(loss)) def boyou_stock_save_json(self): if len(self.init_boyou_stock_list) > 0: init_stock_list = [] self.boyoustock.updateBoyouStockInfo(init_stock_list) for key in range(len(self.init_boyou_stock_list)): row = self.boyou_stock_list[key] boyou_cnt = int(row[1].replace(',', '')) maeip_price = int(row[2].replace(',', '')) # cur_price = int(row[3].replace(',', '')) stock_code = row[6] stock_name = row[0] mado_price = self.stratagy.get_maedo_price( maeip_price, self.stop_loss_rate) # 5% 손절가처리 sell_price = self.stratagy.get_maedo_price( maeip_price, self.stop_profit_rate) # 목표가 처리 self.boyoustock.stock_buy([ stock_code, stock_name, maeip_price, boyou_cnt, sell_price, mado_price ]) else: init_stock_list = [] self.boyoustock.updateBoyouStockInfo(init_stock_list) def cur_stock_price_naver(self): # self.chg_boyou_stock_list = self.kiwoom.opw00018_output['multi'] # # 초기에 보유주식과 매수/매도가 발생시 보유 주식이 다를 수 있으므로 # # 이렇게 처리함.. # logger.debug("== cur_stock_price_naver ==") # logger.debug((self.init_boyou_stock_list, self.chg_boyou_stock_list)) # if util.list_diff(self.init_boyou_stock_list, self.chg_boyou_stock_list): # self.boyou_stock_list = self.chg_boyou_stock_list self.boyou_stock_list = self.boyoustock.readBoyouStockInfo() for key in range(len(self.boyou_stock_list)): bstock = self.boyou_stock_list[key] stock_cd = bstock[0] # 주식코드 stock_nm = bstock[1] # 주식명 maeip_price = bstock[2] # 매입단가 maeip_qtr = bstock[3] # 매입수 stop_price = self.stratagy.get_maedo_price( maeip_price, self.stop_loss_rate) # -5% 손절가 dest_price = self.stratagy.get_maedo_price( maeip_price, self.stop_profit_rate) # 목표가 도달시 cur_price = util.get_naver_cur_stock_price( stock_cd) # 네이버에서 가져온 현재가 logger.debug(util.cur_date_time() + '보유주식명:' + stock_nm + ',주식코드:' + stock_cd + ',현재가:' + str(cur_price) + ',예상 손절가:' + str(stop_price)) if cur_price <= stop_price: logger.debug(util.cur_date_time() + '손절 프로세스 진행 ===> 보유주식명:' + stock_nm + ',주식코드:' + stock_cd + ',현재가:' + str(cur_price) + ',예상 손절가:' + str(stop_price)) # self.stock_stop_loss(stock_cd, maeip_qtr, stop_price) self.add_init_stock_sell_info(stock_cd, dest_price, maeip_qtr, 'S') elif cur_price >= dest_price: logger.debug(util.cur_date_time() + '이익 매도 프로세스 진행 ===> 보유주식명:' + stock_nm + ',주식코드:' + stock_cd + ',현재가:' + str(cur_price) + ',예상 손절가:' + str(stop_price)) self.add_init_stock_sell_info(stock_cd, dest_price, maeip_qtr, 'I') # 이익을 위한 매도주문(즉시 매도처리 이므로)을 취소하고 손실을 중지하기 위한 주문처리를 함. def stock_stop_loss(self, t_stock_code, num, price): is_existed_stock = False self.check_balance() item_count = len(self.kiwoom.opw00018_output['multi']) logger.debug("itemCount ==> " + str(item_count)) if item_count == 0: logger.debug("보유종목이 없습니다.") # 한 종목에 대한 종목명, 보유량, 매입가, 현재가, 평가손익, 수익률(%)은 출력 for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] stock_code = row[6] if t_stock_code == stock_code: is_existed_stock = True if is_existed_stock: order_type_lookup = {'신규매수': 1, '신규매도': 2, '매수취소': 3, '매도취소': 4} hoga_lookup = {'지정가': "00", '시장가': "03"} account = self.comboBox.currentText() self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup['신규매도'], t_stock_code, num, price, hoga_lookup['시장가'], "") else: print("이미 매도 되었거나 매수되지 않은 주식입니다.") # logger.debug("=== stock_stop_loss ===") # logger.debug("손실에 대한 loss 처리 설정했습니다.") # self.check_balance() # # Item list # item_count = len(self.kiwoom.opw00018_output['multi']) # logger.debug("itemCount ==> " + str(item_count)) # if item_count == 0: # logger.debug("보유종목이 없습니다.") # # # 한 종목에 대한 종목명, 보유량, 매입가, 현재가, 평가손익, 수익률(%)은 출력 # for j in range(item_count): # row = self.kiwoom.opw00018_output['multi'][j] # boyou_cnt = int(row[1].replace(',', '')) # maeip_price = int(row[2].replace(',', '')) # cur_price = int(row[3].replace(',', '')) # stock_code = row[6] # logger.debug(util.cur_date_time() + "현재보유주식코드=>" + stock_code + ",손절주식코드=>" + t_stock_code) # if stock_code == t_stock_code: # # 보유종목의 이익매도 주문이 있는 경우 이익매도주문 취소후 익절처리 # self.check_michegyoel_joomoon(stock_code) # row2 = self.kiwoom.opw00007_output[j] # if len(row2) > 0: # if row2[5] != '': # orgJoomoonNo = int(row2[5]) # 원주문번호 정보를 가져온다. # self._file_line_delete(self.kiwoom.sell_loc, stock_code) # stor파일에 해당 종목을 삭제한다. # else: # orgJoomoonNo = '' # else: # orgJoomoonNo = "" # logger.debug(util.cur_date_time() + ":보유주식수/ 매입가/주식코드/원주문번호: %s %s %s %s" % (boyou_cnt, maeip_price, stock_code, orgJoomoonNo)) # if orgJoomoonNo != "": # self.kiwoom.add_stock_sell_info_loss(stock_code, 0, boyou_cnt, orgJoomoonNo) # else: # self.add_init_stock_sell_info(stock_code, 0, boyou_cnt, 'S') # print("종목코드 :", stock_code, " 원주문번호 : ", orgJoomoonNo) # logger.debug(util.cur_date_time() + ":보유주식수/ 매입가/주식코드/원주문번호: %s %s %s %s" % ( # boyou_cnt, maeip_price, stock_code, orgJoomoonNo)) # mado_price = self.stratagy.get_maedo_price(maeip_price, 0.95) # 4% 익절가처리 # 해당주식의 (이익을 얻기 위한)매도 주문 취소 처리 # 아침에 자동 매도주문 처리가 됐을것이고 그것에 대해 취소처리를 하는 것.. # if not self._item_stock_exist(stock_code): # logger.debug(util.cur_date_time() + " : 현재가 / 손절가: %s %s " % (cur_price, mado_price)) # 일단 주석처리 2019.05.02 # if cur_price < mado_price: # 익절가보다 작으면 매도처리 # if orgJoomoonNo != "": # self.kiwoom.add_stock_sell_info_loss(stock_code, mado_price, boyou_cnt, orgJoomoonNo) # else: # self.add_init_stock_sell_info(stock_code, mado_price, boyou_cnt, 'S') def code_changed(self): code = self.lineEdit.text() name = self.kiwoom.get_master_code_name(code) self.lineEdit_2.setText(name) def get_boyou_cnt(self): self.check_balance() # Item list item_count = len(self.kiwoom.opw00018_output['multi']) if item_count == 0: print("보유종목이 없습니다.") return item_count 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(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") def check_michegyoel_joomoon(self, code): self.kiwoom.reset_opw00007_output() account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] # 첫번째 계좌번호 호출 joomoondate = util.cur_date('%y%m%d') self.kiwoom.set_input_value("주문일자", joomoondate) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.set_input_value("비밀번호", "3051") self.kiwoom.set_input_value("비밀번호매체구분", "00") self.kiwoom.set_input_value("조회구분", "3") self.kiwoom.set_input_value("주식채권구분", "1") self.kiwoom.set_input_value("매도매수구분", "1") self.kiwoom.set_input_value("종목코드", code) self.kiwoom.set_input_value("시작주문번호", "") self.kiwoom.comm_rq_data("opw00007_req", "opw00007", 0, "2000") def check_balance_Widget(self): self.check_balance() # balance item = QTableWidgetItem(self.kiwoom.d2_deposit) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, 0, item) # 총매입, 총평가, 총손익, 총수익률(%), 추정자산을 QTableWidget의 칼럼에 추가하는 코드. # 데이터는 self.kiwoom.opw00018_output['single']을 통해 얻어올 수 있음. for i in range(1, 6): print('Debug', self.kiwoom.opw00018_output['single'][i - 1]) item = QTableWidgetItem(self.kiwoom.opw00018_output['single'][i - 1]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, i, item) # resizeRowsToContents 메서드를 호출해서 아이템의 크기에 맞춰 행의 높이를 조절 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) # resizeRowsToContents 메서드를 호출해서 아이템의 크기에 맞춰 행의 높이를 조절 self.tableWidget.resizeRowsToContents() def load_buy_sell_list(self): f = open(self.kiwoom.buy_loc, 'rt', encoding='UTF-8') buy_list = f.readlines() f.close() f = open(self.kiwoom.sell_loc, 'rt', encoding='UTF-8') sell_list = f.readlines() f.close() row_count = len(buy_list) + len(sell_list) self.tableWidget_3.setRowCount(row_count) # buy list for j in range(len(buy_list)): row_data = buy_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name( split_row_data[1].rsplit()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_3.setItem(j, i, item) # sell list for j in range(len(sell_list)): row_data = sell_list[j] split_row_data = row_data.split(';') split_row_data[1] = self.kiwoom.get_master_code_name( split_row_data[1].rstrip()) for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_3.setItem(len(buy_list) + j, i, item) self.tableWidget_3.resizeRowsToContents() # 프로그램 시작시, 보유종목에 대한 매도처리 def init_maedo_proc(self): self.check_balance() # Item list item_count = len(self.kiwoom.opw00018_output['multi']) if item_count == 0: print("보유종목이 없습니다. [", item_count, "]") pass # 한 종목에 대한 종목명, 보유량, 매입가, 현재가, 평가손익, 수익률(%)은 출력 stratagy = SysStratagy() for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] boyou_cnt = int(row[1].replace(',', '')) maeip_price = int(row[2].replace(',', '')) stock_code = row[6] mado_price = stratagy.get_maedo_price(maeip_price, self.stop_profit_rate) self.add_init_stock_sell_info(stock_code, mado_price, boyou_cnt, 'I') # 매도 Stor에 매도 종목 추가 def add_init_stock_sell_info(self, code, sell_price, sell_qty, status): dm = ';' b_gubun = "매도" b_status = "매도전" b_price = sell_price if status == 'I': b_method = "지정가" else: b_method = "시장가" b_qty = sell_qty included = False code_info = self.kiwoom.get_master_code_name(code) mste_info = self.kiwoom.get_master_construction(code) stock_state = self.kiwoom.get_master_stock_state(code) print(code_info, mste_info, stock_state) f = open(self.kiwoom.sell_loc, 'rt', encoding='UTF-8') sell_list = f.readlines() f.close() if self.stratagy.isTimeAvalable(self.kiwoom.maesu_start_time, self.kiwoom.maesu_end_time): if len(sell_list) > 0: write_mode = 'a' # 추가 else: write_mode = 'wt' for stock in sell_list: if code in stock: included = True else: included = False if not included: f = open(self.kiwoom.sell_loc, write_mode, encoding='UTF-8') stock_info = b_gubun + dm + code + dm + b_method + dm + str( b_qty) + dm + str(b_price) + dm + b_status + dm f.write(stock_info + '\n') f.close() else: f = open(self.kiwoom.sell_loc, 'wt', encoding='UTF-8') stock_info = b_gubun + dm + code + dm + b_method + dm + str( b_qty) + dm + str(b_price) + dm + b_status + dm f.write(stock_info + '\n') f.close() # buy_list는 애초에 모니터링시 기본정보 목록에서 추출 # 매매전략에 해당하는 종목을 buy_list_txt에 저장 def trade_buy_stratagic(self, code): stockInfo = {} stockInfo = self.get_current_info(code) if stockInfo is not None and len(stockInfo) > 0: print('종목정보 : ', stockInfo) name = self.kiwoom.get_master_code_name(code) cur_price = stockInfo.get('현재가') open_price = stockInfo.get('시가') print('현재가 :', cur_price, ' 시가:', open_price) if open_price == '' or cur_price == '': return False else: if cur_price[0] == '-' or cur_price[0] == '+': cur_price = cur_price[1:] if open_price[0] == '-' or open_price[0] == '+': open_price = open_price[1:] result = self.stratagy.isBuyStockAvailable( code, name, cur_price, open_price, s_year_date) else: self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "2000") name = self.kiwoom.get_master_code_name(code) # cur_price = self.kiwoom.jangoInfo[code]['현재가'] # if cur_price[0] == '-' or cur_price[0] == '+': # cur_price = cur_price[1:] # open_price = self.kiwoom.jangoInfo[code]['시가'] # if cur_price[0] == '-' or cur_price[0] == '+': # open_price = open_price[1:] # print(name, ",현재가 : ", self.kiwoom.cur_price) result = self.stratagy.isBuyStockAvailable(code, name, self.kiwoom.cur_price, self.kiwoom.open_price, s_year_date) # 주식 정상상태 로직 추가 2019.04.20 start mste_info = self.kiwoom.get_master_construction(code) if mste_info == '정상' and result is True: result = True else: result = False # End return result # return True def _file_update(self, fileName, code, pre_status, chg_status): stock_list = [] f = open(fileName, 'rt', encoding='UTF-8') stock_list = f.readlines() f.close() for i, row_data in enumerate(stock_list): if code in stock_list[i]: stock_list[i] = stock_list[i].replace(pre_status, chg_status) # file update f = open(fileName, 'wt', encoding='UTF-8') for row_data in stock_list: f.write(row_data) f.close() def _file_line_delete(self, fileName, code): stock_list = [] f = open(fileName, 'rt', encoding='UTF-8') stock_list = f.readlines() f.close() for i, row_data in enumerate(stock_list): if code in stock_list[i]: stock_list[i + 1].remove() # file update f = open(fileName, 'wt', encoding='UTF-8') for row_data in stock_list: f.write(row_data) f.close() def _item_stock_exist(self, fileName, code): stock_list = [] f = open(fileName, 'rt', encoding='UTF-8') stock_list = f.readlines() f.close() b_exist = False for i, row_data in enumerate(stock_list): if code in stock_list[i]: b_exist = True return b_exist def get_current_info(self, code): return self.kiwoom.jongmokInfo.get(code) def get_current_info_tr(self, code): self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "2000") def trade_stocks(self): if self.stratagy.isTimeAvalable(self.kiwoom.maesu_start_time, self.kiwoom.maesu_end_time): logger.debug("trade_stocks_1") hoga_lookup = {'지정가': "00", '시장가': "03"} f = open(self.kiwoom.buy_loc, 'rt', encoding='UTF-8') buy_list = f.readlines() logger.debug("trade_stocks_2") f.close() code = '' for stock in buy_list: code = code + stock.split(";")[1] + ";" if code != '': fidList = str(jk_util.name_fid["현재가"]) + ";" + str( jk_util.name_fid["종목명"]) + ";" + str( jk_util.name_fid["종목코드"]) self.kiwoom.setRealReg("0101", code[:-1], fidList, "0") logger.debug("trade_stocks_3") f = open(self.kiwoom.sell_loc, 'rt', encoding='UTF-8') sell_list = f.readlines() f.close() account = self.comboBox.currentText() logger.debug("trade_stocks_4") if len(buy_list) == 0: print("매수 대상 종목이 존재하지 않습니다.") logger.debug("trade_stocks_5") # buy list for row_data in buy_list: split_row_data = row_data.split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] if split_row_data[-1].rstrip() == '매수전': logger.debug("trade_stocks_6") if self.trade_buy_stratagic(code): # * 매수전략 적용 * logger.debug("trade_stocks_7") # 다시 해당 주식의 TR정보를 가져옮.. 상한가 오류로 인하여.. self.get_current_info_tr(code) if self.get_boyou_cnt() >= total_boyou_cnt: print("보유 종목이 3개 이상 입니다.") else: buy_num_info = self.stratagy.get_buy_num_price( total_buy_money, self.kiwoom.high_price, self.kiwoom.cur_price) num = buy_num_info[0] price = buy_num_info[1] print("매수수량 : ", num, " 매수상한가 : ", price) logger.debug("trade_stocks_8") self.kiwoom.send_order("send_order_req", "0101", account, 1, code, num, price, hoga_lookup[hoga], "") # 1: 매수, 2: 매도 logger.debug("trade_stocks_9") if self.kiwoom.order_result == 0: self._file_update(self.kiwoom.buy_loc, code, '매수전', '주문완료') else: print(self.kiwoom.order_result, ': 매수 처리 못했습니다.') # time.sleep(5) logger.debug("trade_stocks_10") if len(sell_list) == 0: print("매도 대상 종목이 존재하지 않습니다.") logger.debug("trade_stocks_11") # sell list for row_data in sell_list: split_row_data = row_data.split(';') hoga = split_row_data[2] code = split_row_data[1] num = split_row_data[3] price = split_row_data[4] logger.debug("trade_stocks_12") if split_row_data[-2].rstrip() == '매도전': logger.debug("trade_stocks_13") self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "") # 1: 매수, 2: 매도 print('결과 : ', self.kiwoom.order_result) if self.kiwoom.order_result == 0: self._file_update(self.kiwoom.sell_loc, code, '매도전', '주문완료') else: print(self.kiwoom.order_result, ': 매도 처리 못했습니다.')
def __init__(self): super().__init__() self.setupUi(self) t = check_logger.check_server() #0.4.5 self.tr = 0 #총TR요청횟수 #텔레그램봇 my_token = '692301814:AAEfmddhyZPcO0Uzh8r5ZehfooTPOvKOOqc' self.mybot = telegram.Bot(token=my_token) self.chat_id = 544924927 self.kiwoom = Kiwoom() #키움인스턴스 생성 self.kiwoom.comm_connect() #API로그인 self.ts_1_p = 'False' #거래전략1 초기값 self.market_start = 'false' #마켓 초기값 self.market_close = 'false' self.shutdown_0900 = 'false' self.shutdown_1530 = 'false' # Timer1 self.timer = QTimer(self) self.timer.start(1000) #1초 상태바 self.timer.timeout.connect(self.timeout) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 25) #25초 잔고조회 self.timer2.timeout.connect(self.timeout2) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 30) #30초 매수전략1 self.timer3.timeout.connect(self.timeout3) # Timer4 self.timer4 = QTimer(self) self.timer4.start(1000 * 33) # 33초 매도전략 self.timer4.timeout.connect(self.timeout4) # Timer5 self.timer5 = QTimer(self) self.timer5.start(1000 * 15) # 60초 09:00~15:30 장중모드 self.timer5.timeout.connect(self.timeout5) # Timer7 self.timer7 = QTimer(self) self.timer7.start(1000 * 1800) # 30분 중간보고, 장마감후 어플 및 컴퓨터 종료 self.timer7.timeout.connect(self.timeout7) self.list700 = [] self.list600 = [] self.buy_list = [] self.sell_list = [] #버튼, 이벤트발생 self.lineEdit.textChanged.connect(self.code_changed) #종목코드 입력시 self.pushButton.clicked.connect(self.send_order) #현금주문 버튼 클릭시 self.pushButton_2.clicked.connect(self.check_balance) #계좌정보 조회 self.pushButton_3.clicked.connect(self.trading_strategy_1) #거래전략1호 self.pushButton_4.clicked.connect(self.quit_app) #앱종료 self.pushButton_4.clicked.connect( QCoreApplication.instance().quit) # 앱종료 self.pushButton_5.clicked.connect(self.timeout7) # 테스트버튼 #계좌정보 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) #프로그램시작알림 log.info('프로그램이 시작되었습니다.') self.textEdit.append( '\n' + QDateTime.currentDateTime().toString("yyyy/MM/dd\nhh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.mybot.sendMessage( self.chat_id, text='\n' + QDateTime.currentDateTime().toString("yyyy/MM/dd\n hh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.get_etf_etn_list() # ETN, ETF 종목 리스트 저장
def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False # 자동 trading False이면 작동 self.kiwoom = Kiwoom() self.kiwoom.comm_connect() # 전략 self.stratagy = SysStratagy() # Timer1 self.timer = QTimer(self) self.timer.start(1000 * 5) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 10) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 10) # Timer4 손절처리를 위한 Timer 설정 self.timer4 = QTimer(self) self.timer4.start(1000 * 60) # Naver에서 현재가 가져오기 self.timer_naver = QTimer(self) self.timer_naver.start(1000 * 4) # Naver에서 현재가 가져오기 self.timer_rate = QTimer(self) self.timer_rate.start(1000 * 3) # 계좌정보 넣어줌 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) # 보유 종목정보 self.boyou_stock_list = [] self.check_balance() self.init_boyou_stock_list = self.kiwoom.opw00018_output['multi'] self.boyou_stock_list = self.init_boyou_stock_list # self.boyou_stock_list.append(['삼성전자', '100', '40000', '42000', '200000', '5', '005930']) # 아침에 보유주식 매도기능 주석처리함.. 보유주식 정보에서 처리하면 되므로 2019.05.19 # 보유 주식 매도 주문 아침9시전에 구동시에 보유주식에 대한 매도주문처리 # self.init_boyou_mado() # 매도/매수 리스트 조회 self.load_buy_sell_list() # 보유주식정보 json으로 저장 self.boyoustock = BoyouStock() self.boyou_stock_save_json() # 이벤트 정보 연결 self.timer.timeout.connect(self.timeout) self.timer2.timeout.connect(self.timeout2) self.timer3.timeout.connect(self.timeout3) self.timer4.timeout.connect( self.timeout4) # stop loss 처리 # 보유주식정보 가져오는 것으로 수정함.2019.05.19 self.timer_naver.timeout.connect(self.timeout_naver) self.timer_rate.timeout.connect(self.timeout_rate) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton.clicked.connect(self.send_order) self.pushButton_2.clicked.connect( self.check_balance_Widget ) # pushButton_2 라는 객체가 클릭될 때 check_balance라는 메서드가 호출 # 손절,익절률 설정 값 읽어오기 config = self.boyoustock.readConfig() if len(config) > 0: self.stop_profit_rate = (config["stop_profit_rate"] / 100) + 1 self.stop_loss_rate = 1 - (config["stop_loss_rate"] / 100) self.spinBox_6.setValue(config["stop_profit_rate"]) self.spinBox_7.setValue(config["stop_loss_rate"]) else: self.stop_profit_rate = (self.spinBox_6.value() / 100) + 1 self.stop_loss_rate = 1 - (self.spinBox_7.value() / 100) print("초기 설정 익절률: " + str(self.stop_profit_rate)) print("초기 설정 손절률: " + str(self.stop_loss_rate))
import sys from PyQt5.QtWidgets import * import Kiwoom # 자동로그인 및 종목 데이터 호출 세팅 app = QApplication(sys.argv) kiwoom = Kiwoom.Kiwoom() kiwoom.comm_connect() account_number = kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] # 공시에서 받아올 종목 코드 stockcode = '006360' quantity = 10 signal = "HOLD" kiwoom.signal(signal, stockcode, account_number, quantity)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.trade_stocks_done = False self.kiwoom = Kiwoom() self.kiwoom.comm_connect() # Database 연결 self.con = sqlite3.connect("HBase.db") self.cursor = self.con.cursor() #보유종목현황 / 선정 종목 버튼 리스트 self.btn_list1 = [] self.btn1_num = 0 self.btn_list2 = [] self.btn2_num = 0 #현재 시간을 알려주기 위한 Timer self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) #실시간 잔고 및 보유종목 현황을 보여주기 위한 Timer self.timer2 = QTimer(self) self.timer.start(5000) self.timer.timeout.connect(self.timeout2) #종목코드 입력 self.lineEdit.textChanged.connect(self.code_change) #계좌번호 출력 accounts_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accounts_num] self.comboBox.addItems(accounts_list) #주문버튼 / 잔고 조회 버튼 self.pushButton.clicked.connect(self.send_order) self.pushButton_2.clicked.connect(self.check_balance) #선정 종목 정보 출력 self.load_buy_sell_list() #self.kiwoom._set_real_reg("6000", "8121773611", "8019", "0") //실시간 정보 확인 #프로그램 상에서 수동 주문하는 함수 -> 주문 정보를 DB에 저장 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() name = self.kiwoom.get_master_code_name(code) hoga = self.comboBox_3.currentText() num = self.spinBox.value() price = self.spinBox_2.value() current_time = QTime.currentTime().toString() now = datetime.now() current_date = str(now.year) + '-' + str(now.month) + '-' + str( now.day) #구매 정보 DB에 저장 if order_type == '신규매수': sql = "INSERT INTO buy_inform VALUES(" sql = sql + "'" + current_date + "'" + "," + "'" + current_time + "'" + "," + "'" + name + "'" + "," + "'" + code + "'" + "," + "'수동주문'" + ")" self.cursor.execute(sql) self.con.commit() elif order_type == '신규매도': sql = "INSERT INTO sell_inform VALUES(" #buy_inform 에서 데이터가져오기 // 매수 정보에서 불러온 정보와 더불어 매도 정보에 저장 df = pd.read_sql("SELECT * FROM buy_inform", self.con, index_col=None) df_num = len(df) for i in range(df_num - 1, -1, -1): if df.loc[i, "종목명"] == name: buy_date = df.loc[i, "매수날짜"] buy_time = df.loc[i, "매수시각"] buy_reason = df.loc[i, "매수근거"] break #보유종목현황에서 데이터가져오기 item_count = len(self.kiwoom.opw00018_output['multi']) for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] if row[0] == name: sql = sql + "'" + buy_date + "','" + buy_time + "','" + current_date + "','" + current_time + "','" + row[ 0] + "','" + row[1] + "','" + row[2] + "','" + row[ 3] + "','" + row[4] + "','" + row[5] + "','" + row[ 6] + "','" + row[ 7] + "','" + buy_reason + "'," + "'수동주문'" + ")" #delete_sql = "DELETE FROM buy_inform WHERE 종목명 = " #delete_sql = delete_sql + "'" + name + "'" self.cursor.execute(sql) #self.cursor.execute(delete_sql) self.con.commit() break self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "") def code_change(self): code = self.lineEdit.text() name = self.kiwoom.get_master_code_name(code) self.lineEdit_2.setText(name) def timeout(self): market_start_time = QTime(9, 0, 0) current_time = QTime.currentTime() if current_time > market_start_time and self.trade_stocks_done is False: self.trade_stocks() self.trade_stocks_done = True 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 link_btn(self): naver_url = "https://finance.naver.com/item/fchart.nhn?code=" daum_url = "https://finance.daum.net/quotes/" sender = self.sender() code = sender.text() daum_url = daum_url + "A" + code + "#chart" webbrowser.open_new(daum_url) code = re.findall('\d+', code)[0] naver_url = naver_url + code webbrowser.open_new(naver_url) #현재 보유하고 있는 주식과 잔고를 보여주는 함수 def check_balance(self): self.kiwoom.reset_opw00018_output() account_number = self.kiwoom.get_login_info("ACCNO") account_number = account_number.split(';')[0] #opw00018 - 각 종목에 대한 비중, 매입가, 평가액 등을 요청 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.AlignHCenter) 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.AlignHCenter) 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)): if i == 1: self.btn_list1.append(QPushButton(self.tableWidget_2)) self.btn_list1[self.btn1_num].setText(row[i]) self.btn_list1[self.btn1_num].clicked.connect( self.link_btn) self.tableWidget_2.setCellWidget( j, i, self.btn_list1[self.btn1_num]) self.btn1_num += 1 else: item = QTableWidgetItem(row[i]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.tableWidget_2.setItem(j, i, item) self.tableWidget_2.resizeRowsToContents() def timeout2(self): if self.checkBox.isChecked(): self.check_balance() #매수해야 하는 목록, 매도해야 하는 목록을 불러와 표로 보여주는 함수 def load_buy_sell_list(self): f = open("buy_list.txt", 'rt', encoding='UTF8') buy_list = f.readlines() f.close() f = open("sell_list.txt", 'rt', encoding='UTF8') sell_list = f.readlines() f.close() row_count = len(buy_list) + len(sell_list) self.tableWidget_3.setRowCount(row_count) #buy list for j in range(len(buy_list)): row_data = buy_list[j] split_row_data = row_data.split(';') for i in range(len(split_row_data)): if i == 1: self.btn_list2.append(QPushButton(self.tableWidget_2)) self.btn_list2[self.btn2_num].setText( split_row_data[i].rstrip()) self.btn_list2[self.btn2_num].clicked.connect( self.link_btn) self.tableWidget_3.setCellWidget( j, i, self.btn_list2[self.btn2_num]) self.btn2_num += 1 else: item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.tableWidget_3.setItem(j, i, item) #sell list for j in range(len(sell_list)): row_data = sell_list[j] split_row_data = row_data.split(';') for i in range(len(split_row_data)): if i == 1: self.btn_list2.append(QPushButton(self.tableWidget_2)) self.btn_list2[self.btn2_num].setText( split_row_data[i].rstrip()) self.btn_list2[self.btn2_num].clicked.connect( self.link_btn) self.tableWidget_3.setCellWidget( len(buy_list) + j, i, self.btn_list2[self.btn2_num]) self.btn2_num += 1 else: item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignHCenter) self.tableWidget_3.setItem(len(buy_list) + j, i, item) self.tableWidget_3.resizeRowsToContents() #현재 작성되어 있는 매수해야하는 목록과 매도해야 하는 목록을 바탕으로 매수,매도 진행 def trade_stocks(self): hoga_lookup = {'지정가': "00", '시장가': "03"} f = open("buy_list.txt", 'rt', encoding='UTF8') buy_list = f.readlines() f.close() f = open("sell_list.txt", 'rt', encoding='UTF8') sell_list = f.readlines() f.close() #acoount account = self.comboBox.currentText() #Current Time and Date Check current_time = QTime.currentTime().toString() now = datetime.now() current_date = str(now.year) + '-' + str(now.month) + '-' + str( now.day) #buy list for row_data in buy_list: split_row_data = row_data.split(';') hoga = split_row_data[3] code = split_row_data[1] name = split_row_data[2] num = split_row_data[4] price = split_row_data[5] buy_reason = split_row_data[7] if split_row_data[6].rstrip() == '매수전': sql = "INSERT INTO buy_inform VALUES(" sql = sql + "'" + current_date + "'" + "," + "'" + current_time + "'" + "," + "'" + name + "'" + "," + "'" + code + "','" + buy_reason + "')" self.cursor.execute(sql) self.con.commit() self.kiwoom.send_order("send_order_req", "0101", account, 1, code, num, price, hoga_lookup[hoga], "") #sell list for row_data in sell_list: split_row_data = row_data.split(';') hoga = split_row_data[3] code = split_row_data[1] name = split_row_data[2] num = split_row_data[4] price = split_row_data[5] sell_reason = split_row_data[7] if split_row_data[6].rstrip() == '매도전': sql = "INSERT INTO sell_inform VALUES(" # buy_inform 에서 데이터가져오기 df = pd.read_sql("SELECT * FROM buy_inform", self.con, index_col=None) df_num = len(df) for i in range(df_num - 1, -1, -1): if df.loc[i, "종목명"] == name: buy_date = df.loc[i, "매수날짜"] buy_time = df.loc[i, "매수시각"] buy_reason = df.loc[i, "매수근거"] break # 보유종목현황에서 데이터가져오기 item_count = len(self.kiwoom.opw00018_output['multi']) for j in range(item_count): row = self.kiwoom.opw00018_output['multi'][j] if row[0] == name: sql = sql + "'" + buy_date + "','" + buy_time + "','" + current_date + "','" + current_time + "','" + \ row[0] + "','" + row[1] + "','" + row[2] + "','" + row[3] + "','" + row[4] + "','" + row[ 5] + "','" + row[6] + "','" + row[7] + "','" + buy_reason + "','" + sell_reason + "')" # delete_sql = "DELETE FROM buy_inform WHERE 종목명 = " # delete_sql = delete_sql + "'" + name + "'" self.cursor.execute(sql) # self.cursor.execute(delete_sql) self.con.commit() break self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "") #buy / sell list replace for i, row_data in enumerate(buy_list): buy_list[i] = buy_list[i].replace("매수전", "주문완료") for i, row_data in enumerate(sell_list): sell_list[i] = sell_list[i].replace("매도전", "주문완료") #file update f = open("buy_list.txt", 'wt', encoding='UTF8') for row_data in buy_list: f.write(row_data) f.close() f = open("sell_list.txt", 'wt', encoding='UTF8') for row_data in sell_list: f.write(row_data) f.close()
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) self.timer2 = QTimer(self) self.timer2.start(1000 * 10) self.timer2.timeout.connect(self.timeout2) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.cmbAccountList.addItems(accounts_list) self.lineEdit.textChanged.connect(self.code_changed) self.btnSendOrder.clicked.connect(self.send_order) self.btnCheckBalance.clicked.connect(self.check_balance) 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 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.chkRealTime.isChecked(): self.check_balance() 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()
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.token = "" self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.code = '093320' self.name = self.kiwoom.get_master_code_name(self.code) self.kiwoom.current = {} self.past_price = 0 self.past_ratio = 0 self.past_amount = 0 # Timer1 - 1초에 한 번씩 이벤트가 발생한다. self.timer = QTimer(self) self.timer.start(1000 * 15) self.timer.timeout.connect(self.timeout_visualize) self.timer = QTimer(self) self.timer.start(1000 * 30) self.timer.timeout.connect(self.timeout_message) def request_data(self, code): """ 데이터 요청 :param code: :return: """ self.kiwoom.current = {} self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", 'opt10001', 0, '2000') def timeout_visualize(self): """ 30초마다 서버로부터 가격, 상승률, 양을 가져온다. :return: """ 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) self.request_data(self.code) self.lineEdit.setText(self.kiwoom.get_master_code_name(self.code)) self.lineEdit_2.setText(self.kiwoom.current['price']) self.lineEdit_3.setText(self.kiwoom.current['ratio']) self.lineEdit_4.setText(self.kiwoom.current['amount']) def timeout_message(self): """ 60초마다 변경 사항이 있을 시 텔레그램 메세지를 보낸다. :return: """ bot = telegram.Bot(token=self.token) chat_id = bot.getUpdates()[-1].message.chat.id price = self.kiwoom.current['price'] ratio = self.kiwoom.current['ratio'] amount = self.kiwoom.current['amount'] if self.past_price != price: message = self.name + "\n" + \ "현재 가격: " + price + "\n" + \ "등락율: " + ratio + "%\n" + \ "거래량: " + amount + "\n" bot.sendMessage(chat_id=chat_id, text=message) self.past_price = price self.past_ratio = ratio self.past_amount = amount
"""try: print("window check") print(self.activeModalWidget()) dialog = self.activeModalWidget() if dialog is not None: self.kiwoom.comm_terminate() self.kiwoom = None except Exception as e: print(e)""" if __name__ == "__main__": app = StockApplication(sys.argv) app.setupSignals() StockApplication.kiwoom = Kiwoom.Kiwoom() StockApplication.kiwoom.comm_connect() kospi_codes = StockApplication.kiwoom.get_code_list_by_market(0) start = 0 num = len(kospi_codes) bound = range(start, num) print(bound) for i in bound: code = kospi_codes[i] StockApplication.kiwoom.reset_opt10001_output() StockApplication.kiwoom.set_input_value("종목코드", code) StockApplication.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0,
def __init__(self): self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.get_code_list() self.excelfile_initiator()
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.kiwoom = Kiwoom() self.kiwoom.comm_connect() self.timer = QTimer(self) self.timer.start(500) self.timer.timeout.connect(self.timeout) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) self.lineEdit.textChanged.connect(self.code_changed) self.pushButton.clicked.connect(self.send_order) ## 조건검색식 관련 추가 self.load_condition_list() self.checkBox_cond.setChecked(True) self.pushButton_cond.clicked.connect(self.start_cond) 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 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) if self.kiwoom.msg: # 텔레그램 if self.checkBox_cond.isChecked(): self.kiwoom.bot.sendMessage(chat_id=self.kiwoom.chat_id, text=self.kiwoom.msg) self.textEdit_cond.append(self.kiwoom.msg) self.kiwoom.msg = "" ## 조건검색식 관련 추가 def load_condition_list(self): print("pytrader.py [load_condition_list]") """ condiComboBox에 condition List를 설정한다. """ cond_list = [] try: # 조건식 실행 self.kiwoom.getConditionLoad() # getConditionLoad 가 정상 실행되면 kiwoom.condition에 조건식 목록이 들어간다. dic = self.kiwoom.condition for key in dic.keys(): cond_list.append("{};{}".format(key, dic[key])) # 콤보박스에 조건식 목록 추가 self.comboBox_cond.addItems(cond_list) except Exception as e: print(e) def start_cond(self): conditionIndex = self.comboBox_cond.currentText().split(';')[0] conditionName = self.comboBox_cond.currentText().split(';')[1] if self.pushButton_cond.text() == "적용": try: self.kiwoom.sendCondition("0",conditionName,int(conditionIndex),1) self.pushButton_cond.setText("해제") self.comboBox_cond.setEnabled(False) self.checkBox_cond.setEnabled(False) print("{} activated".format(conditionName)) except Exception as e: print(e) else: self.kiwoom.sendConditionStop("0",conditionName,conditionIndex) self.pushButton_cond.setText("적용") self.comboBox_cond.setEnabled(True) self.checkBox_cond.setEnabled(True)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.tr = 0 # 총TR요청횟수 # 텔레그램봇 my_token = '692301814:AAEfmddhyZPcO0Uzh8r5ZehfooTPOvKOOqc' self.mybot = telegram.Bot(token=my_token) self.chat_id = 544924927 self.kiwoom = Kiwoom() # 키움인스턴스 생성 self.kiwoom.comm_connect() # API로그인 self.ts_1_p = 'False' # 거래전략1 초기값 self.market_start = 'false' # 마켓 초기값 self.market_close = 'false' self.shutdown_0900 = 'false' self.shutdown_1530 = 'false' # 0.4.6 t = time.gmtime() self.file_today = '{}-{}-{}'.format(t.tm_year, t.tm_mon, t.tm_mday) # Timer1 self.timer = QTimer(self) self.timer.start(1000) # 1초 상태바 self.timer.timeout.connect(self.timeout) # Timer2 self.timer2 = QTimer(self) self.timer2.start(1000 * 25) # 25초 잔고조회 self.timer2.timeout.connect(self.timeout2) # Timer3 self.timer3 = QTimer(self) self.timer3.start(1000 * 30) # 30초 매수전략1 self.timer3.timeout.connect(self.timeout3) # Timer4 self.timer4 = QTimer(self) self.timer4.start(1000 * 33) # 33초 매도전략 self.timer4.timeout.connect(self.timeout4) # Timer5 self.timer5 = QTimer(self) self.timer5.start(1000 * 15) # 60초 09:00~15:30 장중모드 self.timer5.timeout.connect(self.timeout5) # Timer7 self.timer7 = QTimer(self) self.timer7.start(1000 * 1800) # 30분 중간보고, 장마감후 어플 및 컴퓨터 종료 self.timer7.timeout.connect(self.timeout7) self.list700 = [] self.list600 = [] self.buy_list = [] self.sell_list = [] # 버튼, 이벤트발생 self.lineEdit.textChanged.connect(self.code_changed) # 종목코드 입력시 self.pushButton.clicked.connect(self.send_order) # 현금주문 버튼 클릭시 self.pushButton_2.clicked.connect(self.check_balance) # 계좌정보 조회 self.pushButton_3.clicked.connect(self.trading_strategy_1) # 거래전략1호 self.pushButton_4.clicked.connect(self.quit_app) # 앱종료 self.pushButton_4.clicked.connect(QCoreApplication.instance().quit) # 앱종료 self.pushButton_5.clicked.connect(self.timeout7) # 테스트버튼 # 계좌정보 accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) # 프로그램시작알림 log.info('프로그램이 시작되었습니다.') self.textEdit.append('\n' + QDateTime.currentDateTime().toString("yyyy/MM/dd\nhh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.mybot.sendMessage(self.chat_id, text='\n' + QDateTime.currentDateTime().toString( "yyyy/MM/dd\n hh:mm:ss") + "ㅣ 프로그램이 시작되었습니다.") self.get_etf_etn_list() # ETN, ETF 종목 리스트 저장 # 종료 def quit_app(self): log.info('프로그램이 종료되었습니다.') if self.ts_1_p == 'True': self.trading_strategy_1() self.timer.stop() self.timer2.stop() self.timer3.stop() self.timer4.stop() self.timer5.stop() self.timer7.stop() time.sleep(1) # 계좌정보요청 self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") mystocks = '' while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 bb = self.kiwoom.opw00018_output['single'] myaccount = '총매입금액: %s원\n총평가금액: %s원\n총평가손익금액: %s원\n총수익률(%%): %s\n추정예탁자산: %s원' % ( bb[0], bb[1], bb[2], bb[3], bb[4]) a = len(self.kiwoom.opw00018_output['multi']) if a != 0: name = [] num = [] buy = [] price = [] earn = [] ret = [] for i in range(a): name.append(self.kiwoom.opw00018_output['multi'][i][0]) num.append(self.kiwoom.opw00018_output['multi'][i][1]) buy.append(self.kiwoom.opw00018_output['multi'][i][2]) price.append(self.kiwoom.opw00018_output['multi'][i][3]) earn.append(self.kiwoom.opw00018_output['multi'][i][4]) ret.append(self.kiwoom.opw00018_output['multi'][i][5]) mystocks = {'종목': name, '수량': num, '매입가': buy, '현재가': price, '평가손익': earn, '수익률(%)': ret} mystocks = DataFrame(mystocks) mystocks = mystocks.set_index(['종목']) # last 보고 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 프로그램이 종료되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString( "hh:mm:ss") + "ㅣ 프로그램이 종료되었습니다.\n총 TR 요청 횟수 : %d회\n --------계좌현황--------\n계좌번호: %s\n%s\n --------보유종목--------\n%s" % (self.tr, account_number, myaccount, mystocks)) with open('log.txt', 'a') as f: f.writelines(self.textEdit.toPlainText()) time.sleep(3) # 상태표시줄(현재시간, 서버연결상태) def timeout(self): market_start_time = QTime(9, 00, 00) market_close_time = QTime(15, 30, 00) market_start_time2 = QTime(9, 00, 2) market_close_time2 = QTime(15, 30, 2) current_time = QTime.currentTime() # 9시 이후에 급등주알고리즘 시작 if current_time > market_start_time and current_time < market_start_time2 and self.market_start == 'false': log.info('장 시작 알림') self.market_start = 'true' self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장이 시장되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장이 시작되었습니다.") elif current_time > market_close_time and current_time < market_close_time2 and self.market_close == 'false': log.info('장 종료알림') self.market_close = 'true' self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장이 종료되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장이 종료되었습니다.") text_time = current_time.toString("hh:mm:ss") time_msg = "현재시간: " + text_time state = self.kiwoom.GetConnectState() if state == 1: state_msg = "서버가 연결되었습니다." else: state_msg = "서버가 연결되지 않았습니다." log.fatal('서버 미연결') self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ서버가 연결되지 않았습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 서버가 연결되지 않았습니다.") self.statusbar.showMessage(state_msg + " | " + time_msg) def timeout2(self): if self.checkBox.isChecked(): self.check_balance() # 계좌정보 실시간 조회 def timeout3(self): if self.ts_1_p == 'True': # 매수전략1 진행시 30초마다 조회 log.debug('거래량조회 알고리즘 실행') self.volume_check() def timeout4(self): log.debug('매도 알고리즘 실행') self.sell_stocks() # 매도전략 def timeout5(self): #체크시 9시~15:30까지 작동 if self.checkBox_2.isChecked(): market_start_time = QTime(9, 1, 30) market_close_time = QTime(15, 40, 00) current_time = QTime.currentTime() # 9시 이후에 급등주알고리즘 시작 if current_time > market_start_time and self.shutdown_0900 == 'false' and self.ts_1_p == 'False': log.info('장이 시작되어 매수알고리즘 실행') self.shutdown_0900 = 'true' self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장 시작, 매수전략1 시작하겠습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 장 시작, 매수전략1 시작하겠습니다.") self.trading_strategy_1() # 15시 40 분 이후 알고리즘 중지 및 10분 뒤 컴퓨터 종료 elif current_time > market_close_time and self.shutdown_1530 == 'false': log.info('장이 종료되어 알고리즘 중지') self.shutdown_1530 = 'true' self.trading_strategy_1() time.sleep(1) self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 10분 후 컴퓨터를 종료합니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 10분 후 컴퓨터를 종료합니다.") log.fatal('컴퓨터 종료 카운트 시작') self.quit_app() time.sleep(10) os.system("shutdown -s -t 600") print('10분 후 컴퓨터를 종료합니다...') def timeout7(self): # 중간보고 log.debug('중간보고') self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 mystocks = '' bb = self.kiwoom.opw00018_output['single'] myaccount = '총매입금액: %s원\n총평가금액: %s원\n총평가손익금액: %s원\n총수익률(%%): %s\n추정예탁자산: %s원' % ( bb[0], bb[1], bb[2], bb[3], bb[4]) print(myaccount) a = len(self.kiwoom.opw00018_output['multi']) if a != 0: name = [] num = [] buy = [] price = [] earn = [] ret = [] for i in range(a): name.append(self.kiwoom.opw00018_output['multi'][i][0]) num.append(self.kiwoom.opw00018_output['multi'][i][1]) buy.append(self.kiwoom.opw00018_output['multi'][i][2]) price.append(self.kiwoom.opw00018_output['multi'][i][3]) earn.append(self.kiwoom.opw00018_output['multi'][i][4]) ret.append(self.kiwoom.opw00018_output['multi'][i][5]) mystocks = {'종목': name, '수량': num, '매입가': buy, '현재가': price, '평가손익': earn, '수익률(%)': ret} mystocks = DataFrame(mystocks) mystocks = mystocks.set_index(['종목']) print(mystocks) time.sleep(1) # 중간보고 self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 중간보고 완료.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "\n--------중간보고--------\n총 TR 요청 횟수 : %d회\n --------계좌현황--------\n계좌번호: %s\n%s\n --------보유종목--------\n%s" % (self.tr, account_number, myaccount, mystocks)) # 종목명 나타내기 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], "") self.tr += 1 # 계좌정보 def check_balance(self): log.debug('잔고조회') self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 # opw00001 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") self.tr += 1 # 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() # 거래량급증 거래전략1 def trading_strategy_1(self): log.info('매수전략1 실행/중지') if self.ts_1_p == 'False': log.debug('매수전략1 실행중') print('ts_1_p = true, 매수전략1 실행중입니다.') self.ts_1_p = 'True' self.label_7.setText("진행중...") self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 시작되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 시작되었습니다.") self.volume_check() elif self.ts_1_p == 'True': log.debug('매수전략1 중지') print('ts_1_p = False, 매수전략1 중지되었습니다.') self.label_7.setText("") self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 중지되었습니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 매수전략1 중지되었습니다.") self.ts_1_p = 'False' # 매수,매도주문 def order_stocks(self, bs, code, num, price, set_price): ''' :param bs: 매수=1 매도=2 :param code: 종목코드 :param num: 수량 :param price: 가격 (시장가이면 0) :param set_price: 지정가=00 시장가=03 :return: ''' # 0.4.7 수정 장중에만 주문넣기 market_start_time = QTime(9, 00, 00) market_close_time = QTime(15, 30, 00) current_time = QTime.currentTime() if current_time > market_start_time and current_time < market_close_time: account = self.comboBox.currentText() log.critical('order_stocks 주문실행') # order self.kiwoom.send_order("send_order_req", "0101", account, bs, code, num, price, set_price, "") self.tr += 1 # 0.4.6 리스트 작성 if bs == 1: # 매수 f = open(sys.path[0] + '\\backup\\' + self.file_today + '_buy.txt', 'a') f.write(code + '\n') f.close() log.debug('buy_list.txt 기록') elif bs == 2: # 매도 f = open(sys.path[0] + '\\backup\\' + self.file_today + '_sell.txt', 'a') f.write(code + '\n') f.close() log.debug('sell_list.txt 기록') else: log.debug('장이 닫혀있어 주문하지 않았습니다.') print('장이 닫혀있어 주문하지 않았습니다.') # 거래량급증 조회 def volume_check(self): print('조회수급등조회시작') kospi_url = 'https://finance.naver.com/sise/sise_quant_high.nhn' kosdaq_url = 'https://finance.naver.com/sise/sise_quant_high.nhn?sosok=1' df = pd.DataFrame() html_1 = requests.get(kospi_url).text df = df.append(pd.read_html(html_1, header=0)[1]) html_2 = requests.get(kosdaq_url).text df = df.append(pd.read_html(html_2, header=0)[1]) del df['PER'] df = df.dropna() df = df.rename( columns={'N': 'num', '증가율': 'rate', '종목명': 'name', '현재가': 'price', '전일비': 'diff', '등락률': 'updown', '매수호가': 'buy_hoga', '매도호가': 'sell_hoga', '거래량': 'volume', '전일거래량': 'yes_volume'}) df = df.set_index(['num']) # 크롤링완료 html = html_1 + html_2 if df.empty is True: log.debug('네이버금융 데이터가 없음') self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 네이버금융 데이터가 없습니다.') self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString( 'hh:mm:ss') + 'ㅣ 네이버금융 데이터가 없습니다.') print('네이버금융 데이터가 없습니다.') else: # 0.4.6 장 종료시 데이터프레임 저장 if self.market_close == 'true': df.to_csv(sys.path[0] + '\\backup\\' + self.file_today + '_volume.csv', encoding='cp949') # 0.4.1 수정 # 700이상 df700 = df[[a > 700 for a in df.rate]] a700 = list(df700['name']) if len(df700) != 0: for i in range(len(df700)): # 0.4.3 수정(종목이름 앞글자 같을 때 보완) a = html.find(a700[i]) b = len(a700[i]) if html[a + b] == '<': code = html[a - 22:a - 16] self.list700.append(code) else: html = html[a + b:] a = html.find(a700[i]) code = html[a - 22:a - 16] self.list700.append(code) print(self.list700) print(self.list600) # 교집합 구하기 aa = set(self.list700) bb = set(self.list600) buy_set = aa & bb buy_set = list(buy_set) if len(buy_set) != 0: for code in buy_set: if code in self.etn_etf_list: pass else: for i in range(len(buy_set)): self.buy_list.append(buy_set[i]) # 600~700 self.list600 = [] df600 = df[[a < 700 for a in df.rate]] a600 = list(df600['name']) if len(df600) != 0: for i in range(len(df600)): a = html.find(a600[i]) b = len(a600[i]) if html[a + b] == '<': code = html[a - 22:a - 16] self.list600.append(code) else: html = html[a + b:] a = html.find(a600[i]) code = html[a - 22:a - 16] self.list600.append(code) print('매수리스트: %s' % self.buy_list) log.debug('buy_list 저장완료') # order # 0.4.3 자산5% if len(self.buy_list) == 0: pass else: log.debug('바이리스트 주문을 시작함') self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") buy_q = int(self.kiwoom.opw00018_output['single'][4].replace(',', '')) // 20 # 추정예탁자산의 5% self.tr += 1 self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") d2_deposit = int(self.kiwoom.d2_deposit.replace(',', '')) # d2 예수금 self.tr += 1 if buy_q <= d2_deposit: log.critical('주문실행') for code in self.buy_list: # 주문하기 # 0.4.3 매수비중 5%제한 time.sleep(0.5) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") buy_q = buy_q // self.kiwoom.stock_pv # 매수금액/현재가 : 수량 self.tr += 1 time.sleep(1) self.order_stocks(1, code, buy_q, 0, '03') self.textEdit.append( QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매수주문\n종목: %s\n수량: %d\n가격: 시장가\n현재가:%s' % ( self.kiwoom.stock_name, buy_q, self.kiwoom.stock_pv)) self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString( 'hh:mm:ss') + 'ㅣ매수주문\n 종목: %s\n수량: %d\n가격: 시장가\n현재가:%s' % ( self.kiwoom.stock_name, buy_q, self.kiwoom.stock_pv)) else: # 주문x log.critical('예수금이 부족해 주문하지 못함') self.textEdit.append(QTime.currentTime().toString("hh:mm:ss") + "ㅣ 예수금이 부족합니다.") self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString("hh:mm:ss") + "ㅣ 예수금이 부족합니다.") print('예수금이 부족합니다.') self.buy_list = [] self.list700 = [] print("거래량급증조회완료") log.debug('거래량급증조회완료') # 목표수익률 도달시 팔기 def sell_stocks(self): self.kiwoom.reset_opw00018_output() account_number = self.comboBox.currentText() self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000") while self.kiwoom.remained_data: time.sleep(1) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000") self.tr += 1 list_1 = list(self.kiwoom.opw00018_output['multi']) a = len(list_1) if a != 0: log.debug('보유종목현황') print('보유종목현황: %s' % list_1) # 0.4.3 3%, -2.5% 수정 for i in range(a): if float(list_1[i][5]) > 3: code = list_1[i][6] num = int(list_1[i][1].replace('.00', '').replace(',', '')) # 0.4.4 매도주문 1회만 실행 if code not in self.sell_list: log.debug('이익실현매도') self.sell_list.append(code) self.order_stocks(2, code, num, 0, '03') print('매도종목: %s' % code) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") self.tr += 1 time.sleep(1) self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString( "hh:mm:ss") + 'ㅣ 이익실현\n매도주문\n 종목: %s\n수량: %d\n가격: 시장가\n현재가: %s' % ( self.kiwoom.stock_name, num, self.kiwoom.stock_pv)) self.textEdit.append( QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n종목: %s\n수량: %d\n가격: 시장가\n현재가: %s' % ( self.kiwoom.stock_name, num, self.kiwoom.stock_pv)) else: log.debug('이미 접수된 주문') elif float(list_1[i][5]) < -2.5: code = list_1[i][6] num = int(list_1[i][1].replace('.00', '').replace(',', '')) if code not in self.sell_list: log.debug('손절매도') self.sell_list.append(code) self.order_stocks(2, code, num, 0, '03') print('매도종목: %s' % code) self.kiwoom.set_input_value("종목코드", code) self.kiwoom.comm_rq_data("opt10001_req", "opt10001", 0, "0101") self.tr += 1 time.sleep(1) self.mybot.sendMessage(self.chat_id, text=QTime.currentTime().toString( "hh:mm:ss") + 'ㅣ 손절\n매도주문\n 종목: %s\n수량: %d\n가격: 시장가\n현재가: %s' % ( self.kiwoom.stock_name, num, self.kiwoom.stock_pv)) self.textEdit.append( QTime.currentTime().toString("hh:mm:ss") + 'ㅣ 매도주문\n종목: %s\n수량: %d\n가격: 시장가\n현재가: %s' % ( self.kiwoom.stock_name, num, self.kiwoom.stock_pv)) else: log.debug('이미 접수된 주문') # ETF, ETN 종목 리스트 저장 def get_etf_etn_list(self): log.debug('etf,etn리스트 저장') time.sleep(2) market_list = ['etn', 'etf'] self.etn_etf_list = [] for market in market_list: if market == 'etn': url = 'https://finance.naver.com/api/sise/etnItemList.nhn?' elif market == 'etf': url = 'https://finance.naver.com/api/sise/etfItemList.nhn?' html = requests.get(url).text aa = html.split('},') for stock in aa: code_start = stock.find('itemcode') code = stock[code_start + 11:code_start + 17] self.etn_etf_list.append(code)
class MyWindow(QMainWindow, form_class): def __init__(self): super().__init__() self.setupUi(self) self.saveditem = Saveditem() self.kiwoom = Kiwoom() self.kiwoom.comm_connect() fname = "ongoing_list.txt" if not os.path.isfile(fname): f = open(fname, 'wt') f.close() # 선정 종목 리스트 self.load_buy_sell_list() self.file_upload() self.timer = QTimer(self) self.timer.start(1000) self.timer.timeout.connect(self.timeout) #실시간 현재가 self.scrnum = 5000 self.set_current() self.kiwoom.OnReceiveRealData.connect(self.kiwoom._receive_real_data) self.kiwoom.sig_cl.sig_.connect(self.stockgridview) accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT")) accounts = self.kiwoom.get_login_info("ACCNO") accounts_list = accounts.split(';')[0:accouns_num] self.comboBox.addItems(accounts_list) self.exe_save = 0 self.pushButton.clicked.connect(self.save_ongoing) #self.check_chejan_balance() self.check_balance() # 주문 들어가는 부분 self.timer3 = QTimer(self) self.timer3.start(1000 * 10) self.timer3.timeout.connect(self.timeout3) # 화면번호 def getnum(self): if self.scrnum < 9999: self.scrnum += 1 else: self.scrnum = 5000 return int(self.scrnum) #실시간 현재가 불러오기 위한 종목코드 수집 def file_upload(self): # 오늘의 추천 파일만 확인 f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() self.ncode = [] #self.check_price = [] for i in range(len(buy_list)): split_row_data = buy_list[i].split(' ') self.ncode.append(split_row_data[8]) #self.check_price.append(split_row_data[14]) #실시간 설정 def set_current(self): print(self.ncode) for i in range(0, len(self.ncode)): self.kiwoom._set_real_reg(self.getnum(), self.ncode[i], "9001;10", "0") def stockgridview(self): item_cnt = len(self.saveditem.item_view) self.scode_list = list(self.saveditem.item_view.keys()) self.tableWidget_5.setRowCount(item_cnt) for i in range(item_cnt): for j in range(3): #print(self.savedstockitem.item_view[self.scode_list[i]][j]) item = QTableWidgetItem( self.saveditem.item_view[self.scode_list[i]][j]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_5.setItem(i, j, item) # 버튼으로 파일 저장 def save_ongoing(self): self.exe_save = 1 self.check_chejan_balance() # 거래시간 확인 def is_trading_time(self): global special vals = [] current_time = datetime.datetime.now().time() #print(current_time) for start, end in TRADING_TIME: # 수능날 now = datetime.datetime.now() soo_day = datetime.datetime.today().weekday() soo = now.isocalendar() # 수능날 if soo_day == 3 and soo[1] == 46: start_time = datetime.time(hour=9, minute=start[1]) end_time = datetime.time(hour=16, minute=end[1]) # 새해 다음날 elif now.month == 1 and now.day == 2: start_time = datetime.time(hour=9, minute=start[1]) end_time = datetime.time(hour=end[0], minute=end[1]) else: start_time = datetime.time(hour=start[0], minute=start[1]) end_time = datetime.time(hour=end[0], minute=end[1]) if (current_time >= start_time and current_time <= end_time): vals.append(True) else: vals.append(False) pass if vals.count(True): return True else: return False def is_end_time(self): vals = [] current_time = datetime.datetime.now().time() for start, end in TRADING_TIME: now = datetime.datetime.now() soo_day = datetime.datetime.today().weekday() soo = now.isocalendar() # 수능날 if now.month == 11 and soo_day == 3: if soo[1] == 46: start_time = datetime.time(hour=16, minute=20) # 새해 다음날 elif now.month == 1 and now.day == 2: start_time = datetime.time(hour=15, minute=20) # 동시 호가 시간 포함한 3시 30분 else: end_che = datetime.time(hour=4, minute=15) start_time = datetime.time(hour=end[0], minute=end[1] + 10) if (current_time >= start_time): vals.append(True) elif (current_time >= end_che and current_time <= start_time): vals.append(False) else: vals.append(False) pass if vals.count(True): return True else: return False # 자동 주문 def trade_stocks(self): self.is_order_correct() hoga_lookup = {'지정가': "00", '시장가': "03"} global lr_list global pr_list current_time = datetime.datetime.now() f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() account = self.comboBox.currentText() now = datetime.datetime.now() soo_day = datetime.datetime.today().weekday() soo = now.isocalendar() today_hd = datetime.datetime.today().strftime("%Y%m%d") order_check1 = ["주문완료", "매도완료"] # 매수 for i in range(len(buy_list)): split_row_data = buy_list[i].split(' ') machine = split_row_data[0] code = split_row_data[8] num = split_row_data[13] price = split_row_data[14] hoga = "지정가" #print("first_order", self.first_order) if self.is_trading_time() == True: if code in self.scode_list: if not machine in order_check1: if int(price) <= int( self.saveditem.item_view[code][1]): print("{0}: 코드, {1}: 주문가격 {2}: 현재가".format( code, int(price), int(self.saveditem.item_view[code][1]))) self.kiwoom.send_order("send_order_req", "0101", account, 1, code, int(num), int(price), hoga_lookup[hoga], "") buy_list[i] = buy_list[i].replace( machine, order_check1[0]) f = open("buy_list.txt", 'wt') for row_data in buy_list: f.write(row_data) # 매도 num_data = len(self.kiwoom.opw00018_output['multi']) for i in range(num_data): code_name = self.kiwoom.opw00018_output['compare'][i][0] quantity = self.kiwoom.opw00018_output['compare'][i][1] current_price = self.kiwoom.opw00018_output['compare'][i][2] purchase_price = self.kiwoom.opw00018_output['compare'][i][3] print("종목이름: %s, 현재가격: %s, 구입가격: %s" % (code_name, current_price, purchase_price)) location = 0 while (location < len(current_price)): if current_price[location] == ',': current_price = current_price[:location] + current_price[ location + 1::] location += 1 current_price = int(current_price) location2 = 0 while (location2 < len(purchase_price)): if purchase_price[location2] == ',': purchase_price = purchase_price[: location2] + purchase_price[ location2 + 1::] location2 += 1 for j in range(len(buy_list)): split_row_data = buy_list[j].split(' ') machine = split_row_data[0] hd = split_row_data[7] code = split_row_data[8] num = split_row_data[13] price = split_row_data[14] pr = split_row_data[15] lr = split_row_data[16].replace("\n", "") hoga = "지정가" code_new = self.kiwoom.get_master_code_name(code) due_time = current_time.replace(hour=15, minute=15, second=0, microsecond=0) if soo_day == 3 and soo[1] == 46: due_time = current_time.replace(hour=16, minute=15, second=0, microsecond=0) if due_time < current_time and machine == "주문완료": print(hd, today_hd) if hd == today_hd: self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, current_price, hoga_lookup[hoga], "") print("hd 만료, 시장가 판매") buy_list[j] = buy_list[j].replace(machine, "매도완료") #if code_name == code_new and int(quantity) >= int(num): << 에러남 확인 바람 if code_name == code_new: print("code name: %s, lr: %f, pr: %f" % (code, float(lr), float(pr))) pr_price = float(pr) * int(purchase_price) print("pr_price: %f * %d = %d" % (float(pr), int(purchase_price), int(pr_price))) lr_price = float(lr) * float(purchase_price) pr_price = int(pr_price) lr_price = int(lr_price) lr_list[code_name] = lr_price pr_list[code_name] = pr_price print("profit rate price: ", pr_price) print("loss rate price: ", lr_price) print("current price: ", current_price) if machine == "주문완료" and self.is_trading_time() == True: if (current_price >= pr_price): self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, current_price, hoga_lookup[hoga], "") print("pr 주문완료") print(account, code, num, current_price, hoga_lookup[hoga]) buy_list[j] = buy_list[j].replace(machine, "매도완료") break elif current_price <= lr_price: self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, current_price, hoga_lookup[hoga], "") print(account, code, num, current_price, hoga_lookup[hoga]) buy_list[j] = buy_list[j].replace(machine, "매도완료") print(lr_list) print(pr_list) # file update f = open("buy_list.txt", 'wt') for row_data in buy_list: f.write(row_data) f.close() def load_buy_sell_list(self): global file_changed current_time = datetime.datetime.now() today_file = datetime.datetime.today().strftime("%Y%m%d") file_name = today_file + "추천.txt" print(file_name) if os.path.isfile(file_name) == False: print("오늘의 추천 파일을 찾을 수 없습니다.") elif file_changed == False and current_time < current_time.replace( hour=15, minute=16): print(file_name, " buy_list로 변환") f = open(file_name, 'rt') temp_list = f.readlines() f.close() frow_data = [] for row_data in temp_list: frow_data.append(' '.join(row_data.split())) frow_data = filter(str.strip, frow_data) temp = [] for x in frow_data: temp.append(x) bl = [] for j in range(2, len(temp) - 1): x = [] split_row_data = temp[j].split(' ') split_row_data[7] = ( split_row_data[7][split_row_data[7].find("(") + 1:split_row_data[7].find(")")]) split_row_data[8] = re.sub(r'\([^)]*\)', '', split_row_data[8]) split_row_data[9] = split_row_data[9].replace("원", "") split_row_data[9] = split_row_data[9].replace(",", "") split_row_data[13] = split_row_data[13].replace("주", "") split_row_data[13] = split_row_data[13].replace(",", "") split_row_data[14] = split_row_data[14].replace("원", "") split_row_data[14] = int(split_row_data[14].replace(",", "")) for i in range(len(split_row_data)): x.append(split_row_data[i]) x = map(str, x) y = " ".join(x) bl.append(y) # 전날 미매도 파일 불러오기 f = open("ongoing_list.txt", 'rt') sell_list = f.readlines() sell_list2 = [s.rstrip() for s in sell_list] bl += sell_list2 f.close() f = open("buy_list.txt", 'wt') for i in range(len(bl)): # print(bl[i]) f.write(bl[i]) f.write("\n") f.close() file_changed = True print("file_changed?? ", file_changed) f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() row_count = len(buy_list) self.tableWidget_3.setRowCount(row_count) self.num_name = {} # buy list # j:행, i:열 for j in range(len(buy_list)): split_row_data = buy_list[j].split(' ') temp_name = split_row_data[8] # 종목명 구하기 code_name = self.kiwoom.get_master_code_name(temp_name) self.num_name[code_name] = temp_name for i in range(len(split_row_data)): item = QTableWidgetItem(split_row_data[i].rstrip()) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter) self.tableWidget_3.setItem(j, i, item) self.tableWidget_3.resizeRowsToContents() print("num_name", self.num_name) def timeout(self): # market_start_time = QTime(9, 0, 0) current_time = QTime.currentTime() """if current_time > market_start_time and self.trade_stocks_done is False: self.trade_stocks() self.trade_stocks_done = True""" now = QDate.currentDate() text_time = now.toString( Qt.DefaultLocaleLongDate) + " " + 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 timeout3(self): print(datetime.datetime.now()) self.check_balance() print("check_balance 완료") self.check_chejan_balance() print("check_chejan_balance 완료") self.trade_stocks() print("trade_stocks 완료") self.load_buy_sell_list() print("load_buy_sell_list 완료") def check_chejan_balance(self): f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() name = [] num_order = [] file_price = [] buy_list2 = [] check_order = [] self.first_order = {} for i in range(len(buy_list)): split_row_data = buy_list[i].split(' ') machine = split_row_data[0] code = split_row_data[8] num = split_row_data[13] price = int(split_row_data[14]) name.append(code) num_order.append(num) file_price.append(price) check_order.append(machine) # SetInputValue(입력 데이터 설정)과 CommRqData(TR 요청) # 최대 20개의 보유 종목 데이터 리턴 반복 self.kiwoom.reset_opt10075_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("opt10075_req", "opt10075", 0, "2000") while self.kiwoom.remained_data: time.sleep(0.2) self.kiwoom.set_input_value("계좌번호", account_number) self.kiwoom.comm_rq_data("opt10075_req", "opt10075", 0, "2000") # if self.is_trading_time() == False: # break item_count = len(self.kiwoom.opt10075_output['no_che']) self.tableWidget_4.setRowCount(item_count) for j in range(item_count): row = self.kiwoom.opt10075_output['no_che'][j] for i in range(len(row)): item = QTableWidgetItem(row[i]) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget_4.setItem(j, i, item) # 매수만 된 종목 확인 if row[0] == '접수': if row[1] == '+매수': self.first_order[int(self.num_name[self.kiwoom.opt10075_output['no_che'][j][3]])] = \ int(self.kiwoom.opt10075_output['no_che'][j][7]) # ongoin_list 저장 if self.is_end_time() == True or self.exe_save == 1: if row[0] == '체결': # 오늘자 파일의 매수 확인 후 ongoing_list에 저장 if row[1] == '+매수': # if row[1] == '-매도': for l in range(0, j + 1): if self.kiwoom.opt10075_output['no_che'][l][3] == \ self.kiwoom.opt10075_output['no_che'][j][3]: # print("l-{0} {1}".format(l, self.kiwoom.opt10075_output['no_che'][l])) # print("j-{0} {1}".format(j, self.kiwoom.opt10075_output['no_che'][j])) # 후에 매도가 됐는지 확인 if not self.kiwoom.opt10075_output[ 'no_che'][l][1] == '-매도': for k in range(len(buy_list)): if int(self.num_name[self.kiwoom.opt10075_output['no_che'][j][3]]) == int(name[k]) \ and int(self.kiwoom.opt10075_output['no_che'][j][4]) == int(num_order[k])\ and int(self.kiwoom.opt10075_output['no_che'][j][7]) == int(file_price[k]): #print(buy_list[k]) #buy_list[k].replace(self.check_price[k], '-1') buy_list2.append(buy_list[k]) # 계속 감시 중인 종목이 매도되지 않을 시 ongoing_list에 추가 elif row[1] == '-매도': for s in range(len(buy_list)): if check_order[s] == "주문완료": if not int(self.num_name[self.kiwoom.opt10075_output['no_che'][j][3]]) == int(name[s]) \ and int(self.kiwoom.opt10075_output['no_che'][j][4]) == int(num_order[s]): buy_list2.append(buy_list[s]) # print(self.kiwoom.opt10075_output['no_che'][j][3]) # print("l - %d, j - %d" %(l, j)) # print("확인용", self.kiwoom.opt10075_output['no_che'][l]) """for k in range(len(buy_list)): if int(self.num_name[row[3]]) == int(name[k]): #print(k) #print(buy_list[k]) buy_list2.append(buy_list[k])""" buy_list2 = list(set(buy_list2)) if self.is_end_time() == True or self.exe_save == 1: f = open("ongoing_list.txt", 'wt') for row_data in buy_list2: row_data = row_data f.write(row_data) f.close() self.exe_save = 0 self.tableWidget_4.resizeRowsToContents() # 잔고 및 보유 계좌 정보 확인 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") #모의투자 시 밑의 세줄 주석 처리 #self.kiwoom.set_input_value("비밀번호", "0000") #self.kiwoom.set_input_value("비밀번호입력매체구분", "00") #self.kiwoom.set_input_value("조회구분", 1) #self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000") # balance # 예수금 데이터 tableWidget에 출력 item = QTableWidgetItem(self.kiwoom.d2_deposit) item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight) self.tableWidget.setItem(0, 0, item) # 해당 칼럼에 값 추가 for i in range(1, 6): print(self.kiwoom.opw00018_output['single'][i - 1]) 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] if row[0] in lr_list and pr_list: str_lr = str(lr_list[row[0]]) row[4] = str_lr print(row[4]) str_pr = str(pr_list[row[0]]) row[5] = str_pr print(row[5]) print(row) 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 is_order_correct(self): f = open("buy_list.txt", 'rt') buy_list = f.readlines() f.close() order_check1 = ["주문완료", "매도완료"] # 매수 for i in range(len(buy_list)): split_row_data = buy_list[i].split(' ') machine = split_row_data[0] code = split_row_data[8] num = split_row_data[13] price = split_row_data[14] hoga = "지정가" if machine == order_check1[0]: if not int(code) in self.first_order: buy_list[i] = buy_list[i].replace(machine, "미매수") f = open("buy_list.txt", 'wt') for row_data in buy_list: f.write(row_data)