You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

380 lines
13 KiB

5 years ago
  1. import sys
  2. from PyQt5.QtCore import *
  3. from Kiwoom import *
  4. from PyQt5.QtWidgets import *
  5. from PyQt5.QtGui import *
  6. from PyQt5 import uic
  7. from widgetfile import *
  8. from PyQt5 import QtCore, QtGui, QtWidgets
  9. import time
  10. from pandas_datareader import data
  11. import matplotlib.pyplot as plt
  12. from matplotlib.figure import Figure
  13. from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
  14. from mplfinance.original_flavor import candlestick2_ohlc
  15. from datetime import datetime
  16. import matplotlib.ticker as ticker
  17. import os
  18. import plotly.graph_objects as go
  19. import tkinter as tk
  20. from tkinter import ttk
  21. from IPython.display import display
  22. form_class = uic.loadUiType("pytrader.ui")[0]
  23. start_date = datetime(2020,5,8)
  24. end_date = datetime(2020,10,8)
  25. dialog = tk.Tk()
  26. dialog1 = tk.Tk()
  27. dialog2 = tk.Tk()
  28. class MyWindow(QMainWindow, form_class):
  29. def __init__(self):
  30. super().__init__()
  31. self.setupUi(self)
  32. self.trade_stocks_done = False
  33. self.kiwoom = Kiwoom()
  34. self.kiwoom.comm_connect()
  35. self.timer = QTimer(self)
  36. self.timer.start(1000)
  37. self.timer.timeout.connect(self.timeout)
  38. self.timer2 = QTimer(self)
  39. self.timer2.start(1000 *10)
  40. self.timer2.timeout.connect(self.timeout2)
  41. accouns_num = int(self.kiwoom.get_login_info("ACCOUNT_CNT"))
  42. accounts = self.kiwoom.get_login_info("ACCNO")
  43. accounts_list = accounts.split(';')[0:accouns_num]
  44. self.comboBox.addItems(accounts_list)
  45. self.lineEdit.textChanged.connect(self.code_changed)
  46. self.pushButton.clicked.connect(self.send_order)
  47. self.pushButton_2.clicked.connect(self.check_balance)
  48. self.pushButton_4.clicked.connect(self.show_graph)
  49. self.pushButton_5.clicked.connect(self.dialog_open)
  50. self.pushButton_6.clicked.connect(self.dialog_open1)
  51. self.pushButton_7.clicked.connect(self.dialog_open2)
  52. # 차트확인하기 버튼
  53. self.button = QPushButton('차트 확인',self)
  54. self.button.clicked.connect(self.chart)
  55. #self.button.clicked.connect(self.show_graph)
  56. self.button.setGeometry(105,239,75,23)
  57. self.chart = QDialog()
  58. self.canvas = FigureCanvas(Figure())
  59. self.load_buy_sell_list()
  60. def dialog_open(self):
  61. label = ttk.Label(dialog, text="현재 날짜를 기준으로 과거 거래 일 별로 시가, 고가, 저가, 종가, 거래량을 가져와 특정 거래일의 거래량이 평균 거래량보다 25% 초과시 매매하는 알고리즘")
  62. label.pack()
  63. dialog.title("급등주")
  64. #self.dialog.geometry("300x300")
  65. label.mainloop()
  66. # def change_test(self):
  67. # change_label.configure(text="text change")
  68. # change_button
  69. def dialog_open1(self):
  70. label1 = ttk.Label(dialog1,
  71. text="상위 20개의 종목을 추천하여 매수할 수 있도록 하는 알고리즘")
  72. label1.pack()
  73. dialog.title("신마법공식")
  74. # self.dialog.geometry("300x300")
  75. label1.mainloop()
  76. def dialog_open2(self):
  77. label2 = ttk.Label(dialog2,
  78. text="과거의 데이터를 가지고 와 알고리즘 스스로 반복해 공부하여 향후 해당 주가에 대한 예측을 하는 알고리즘")
  79. label2.pack()
  80. dialog.title("주가예측")
  81. # self.dialog.geometry("300x300")
  82. label2.mainloop()
  83. def show_graph(self):
  84. code = self.lineEdit.text()
  85. self.fig = plt.figure(figsize=(20, 10))
  86. df1 = data.DataReader(code + ".ks", "yahoo")
  87. ax = self.fig.add_subplot(111)
  88. df1['MA20'] = df1['Adj Close'].rolling(window=20).mean()
  89. df1['MA60'] = df1['Adj Close'].rolling(window=60).mean()
  90. self.graph_viewer.canvas.axes.plot(df1.index, df1['Adj Close'], label='Adj Close')
  91. self.graph_viewer.canvas.axes.plot(df1.index, df1['MA20'], label='MA20')
  92. self.graph_viewer.canvas.axes.plot(df1.index, df1['MA60'], label='MA60')
  93. data_name = '이동평균선'
  94. #self.graph_viewer.canvas.axes.plot(x_list, y_list, label=data_name)
  95. self.graph_viewer.canvas.axes.legend()
  96. self.graph_viewer.canvas.axes.set_xlabel('Date')
  97. self.graph_viewer.canvas.axes.set_ylabel('주가')
  98. self.graph_viewer.canvas.draw()
  99. def chart(self):
  100. self.chart.setGeometry(600, 200, 1200, 600)
  101. self.chart.setWindowTitle("PyChart Viewer v0.1")
  102. self.chart.setWindowIcon(QIcon('icon.png'))
  103. self.chart.lineEdit = QLineEdit()
  104. self.chart.button1 = QPushButton("차트그리기")
  105. self.chart.button1.clicked.connect(self.ButtonClicked)
  106. self.chart.button2 = QPushButton("유동성차트 확인")
  107. self.chart.button2.clicked.connect(self.ButtonClicked1)
  108. self.fig = plt.Figure()
  109. self.canvas = FigureCanvas(self.fig)
  110. leftLayout = QVBoxLayout()
  111. leftLayout.addWidget(self.canvas)
  112. # Right Layout
  113. rightLayout = QVBoxLayout()
  114. rightLayout.addWidget(self.lineEdit)
  115. rightLayout.addWidget(self.chart.button1)
  116. rightLayout.addWidget(self.chart.button2)
  117. rightLayout.addStretch(1)
  118. layout = QHBoxLayout()
  119. layout.addLayout(leftLayout)
  120. layout.addLayout(rightLayout)
  121. layout.setStretchFactor(leftLayout, 1)
  122. layout.setStretchFactor(rightLayout, 0)
  123. self.chart.setLayout(layout)
  124. self.chart.show()
  125. def ButtonClicked1(self):
  126. code = self.lineEdit.text()
  127. df = data.DataReader(code + ".ks", "yahoo")
  128. candle = go.Candlestick(x=df.index,
  129. open=df['Open'],
  130. high=df['High'],
  131. low=df['Low'],
  132. close=df['Close'])
  133. fig = go.Figure(data=candle)
  134. fig.show()
  135. def ButtonClicked(self):
  136. code = self.lineEdit.text()
  137. df = data.DataReader(code + ".ks", "yahoo")
  138. df['MA20'] = df['Adj Close'].rolling(window=20).mean()
  139. df['MA60'] = df['Adj Close'].rolling(window=60).mean()
  140. ax = self.fig.add_subplot(111)
  141. """ax.plot(df.index, df['Adj Close'], label='Adj Close')
  142. ax.plot(df.index, df['MA20'], label='MA20')
  143. ax.plot(df.index, df['MA60'], label='MA60')"""
  144. ax.legend(loc='upper right')
  145. candlestick2_ohlc(ax, df['Open'], df['High'],
  146. df['Low'], df['Close'],
  147. width=0.5, colorup='r', colordown='b')
  148. ax.set_title('KOSPI INDEX', fontsize=22)
  149. ax.set_xlabel('Date')
  150. ax.grid()
  151. plt.pause(0.001)
  152. self.canvas.draw()
  153. def closeEvent(self, event):
  154. self.deleteLater()
  155. def trade_stocks(self):
  156. hoga_lookup = {'지정가': "00", '시장가': "03"}
  157. f = open("buy_list.txt", 'rt', encoding='utf-8')
  158. buy_list = f.readlines()
  159. f.close()
  160. f = open("sell_list.txt", 'rt', encoding='utf-8')
  161. sell_list = f.readlines()
  162. f.close()
  163. # account
  164. account = self.comboBox.currentText()
  165. # buy list
  166. for row_data in buy_list:
  167. split_row_data = row_data.split(';')
  168. hoga = split_row_data[2]
  169. code = split_row_data[1]
  170. num = split_row_data[3]
  171. price = split_row_data[4]
  172. if split_row_data[-1].rstrip() == '매수전':
  173. self.kiwoom.send_order("send_order_req", "0101", account, 1, code, num, price, hoga_lookup[hoga], "")
  174. # sell list
  175. for row_data in sell_list:
  176. split_row_data = row_data.split(';')
  177. hoga = split_row_data[2]
  178. code = split_row_data[1]
  179. num = split_row_data[3]
  180. price = split_row_data[4]
  181. if split_row_data[-1].rstrip() == '매도전':
  182. self.kiwoom.send_order("send_order_req", "0101", account, 2, code, num, price, hoga_lookup[hoga], "")
  183. # buy list
  184. for i, row_data in enumerate(buy_list):
  185. buy_list[i] = buy_list[i].replace("매수전", "주문완료")
  186. # file update
  187. f = open("buy_list.txt", 'w', encoding='utf-8')
  188. for row_data in buy_list:
  189. f.write(row_data)
  190. f.close()
  191. # sell list
  192. for i, row_data in enumerate(sell_list):
  193. sell_list[i] = sell_list[i].replace("매도전", "주문완료")
  194. # file update
  195. f = open("sell_list.txt", 'w', encoding='utf-8')
  196. for row_data in sell_list:
  197. f.write(row_data)
  198. f.close()
  199. def load_buy_sell_list(self):
  200. f = open("buy_list.txt", 'rt', encoding='utf-8')
  201. buy_list = f.readlines()
  202. f.close()
  203. f = open("sell_list.txt", 'rt', encoding='utf-8')
  204. sell_list = f.readlines()
  205. f.close()
  206. row_count = len(buy_list) + len(sell_list)
  207. self.tableWidget_4.setRowCount(row_count)
  208. # buy list
  209. for j in range(len(buy_list)):
  210. row_data = buy_list[j]
  211. split_row_data = row_data.split(';')
  212. split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rsplit())
  213. for i in range(len(split_row_data)):
  214. item = QTableWidgetItem(split_row_data[i].rstrip())
  215. item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter)
  216. self.tableWidget_4.setItem(j, i, item)
  217. # sell list
  218. for j in range(len(sell_list)):
  219. row_data = sell_list[j]
  220. split_row_data = row_data.split(';')
  221. split_row_data[1] = self.kiwoom.get_master_code_name(split_row_data[1].rstrip())
  222. for i in range(len(split_row_data)):
  223. item = QTableWidgetItem(split_row_data[i].rstrip())
  224. item.setTextAlignment(Qt.AlignVCenter | Qt.AlignCenter)
  225. self.tableWidget_4.setItem(len(buy_list) + j, i, item)
  226. self.tableWidget_4.resizeRowsToContents()
  227. def code_changed(self):
  228. code = self.lineEdit.text()
  229. name = self.kiwoom.get_master_code_name(code)
  230. self.lineEdit_2.setText(name)
  231. def send_order(self):
  232. order_type_lookup = {'신규매수': 1, '신규매도': 2, '매수취소': 3, '매도취소': 4}
  233. hoga_lookup = {'지정가': "00", '시장가': "03"}
  234. account = self.comboBox.currentText()
  235. order_type = self.comboBox_2.currentText()
  236. code = self.lineEdit.text()
  237. hoga = self.comboBox_3.currentText()
  238. num = self.spinBox.value()
  239. price = self.spinBox_2.value()
  240. self.kiwoom.send_order("send_order_req", "0101", account, order_type_lookup[order_type], code, num, price, hoga_lookup[hoga], "")
  241. def timeout(self):
  242. market_start_time = QTime(9, 0, 0)
  243. current_time = QTime.currentTime()
  244. if current_time > market_start_time and self.trade_stocks_done is False:
  245. self.trade_stocks()
  246. self.trade_stocks_done = True
  247. text_time = current_time.toString("hh:mm:ss")
  248. time_msg = "현재시간: " + text_time
  249. state = self.kiwoom.get_connect_state()
  250. if state == 1:
  251. state_msg = "서버 연결 중"
  252. else:
  253. state_msg = "서버 미 연결 중"
  254. self.statusbar.showMessage(state_msg + " | " + time_msg)
  255. def timeout2(self):
  256. if self.checkBox.isChecked():
  257. self.check_balance()
  258. def check_balance(self):
  259. self.kiwoom.reset_opw00018_output()
  260. account_number = self.kiwoom.get_login_info("ACCNO")
  261. account_number = account_number.split(';')[0]
  262. self.kiwoom.set_input_value("계좌번호", account_number)
  263. self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000")
  264. while self.kiwoom.remained_data:
  265. time.sleep(0.05)
  266. self.kiwoom.set_input_value("계좌번호", account_number)
  267. self.kiwoom.comm_rq_data("opw00018_req", "opw00018", 2, "2000")
  268. # opw00001
  269. self.kiwoom.set_input_value("계좌번호", account_number)
  270. self.kiwoom.comm_rq_data("opw00001_req", "opw00001", 0, "2000")
  271. # balance
  272. item = QTableWidgetItem(self.kiwoom.d2_deposit)
  273. item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
  274. self.tableWidget.setItem(0, 0, item)
  275. for i in range(1, 6):
  276. item = QTableWidgetItem(self.kiwoom.opw00018_output['single'][i - 1])
  277. item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
  278. self.tableWidget.setItem(0, i, item)
  279. self.tableWidget.resizeRowsToContents()
  280. # Item list
  281. item_count = len(self.kiwoom.opw00018_output['multi'])
  282. self.tableWidget_2.setRowCount(item_count)
  283. for j in range(item_count):
  284. row = self.kiwoom.opw00018_output['multi'][j]
  285. for i in range(len(row)):
  286. item = QTableWidgetItem(row[i])
  287. item.setTextAlignment(Qt.AlignVCenter | Qt.AlignRight)
  288. self.tableWidget_2.setItem(j, i, item)
  289. self.tableWidget_2.resizeRowsToContents()
  290. def closeEvent(self, event):
  291. self.deleteLater()
  292. if __name__ == "__main__":
  293. app = QApplication(sys.argv)
  294. myWindow = MyWindow()
  295. myWindow.show()
  296. sys.exit(app.exec())
  297. window = MWindow()