관리자 0 598 0 0

UI 부터가 ver1.0 과 완전히 다르게 개발했습니다.

각각의 정보들을 모두 새창으로 개발했습니다.

Qt Designer 으로 개발하니까 좌표값이랑 크기값을 일일이 세팅하지 않아도 되어서 개발이 너무 편하다.

 


 

 

메인 윈도우 소스공개~

import sys
import requests
import json
import re
import webbrowser

from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QGridLayout, QLabel, QMessageBox, QTableWidget, QTableWidgetItem, QPushButton, QLineEdit
from PyQt5 import uic
from PyQt5.QtCore import QTimer
from functools import partial
from collections import OrderedDict

from kiwoom import kiwoom

ui = uic.loadUiType("auto_pay.ui")[0]
order_ui = uic.loadUiType("order_setup.ui")[0]

class MyWindow(QMainWindow, ui):
def __init__(self):
super().__init__()
self.setupUi(self)
self.show()


'''
# 실사모드
self.ki = kiwoom()
self.ki.commConnect()
# 요기서 loop로 멈춤

self.server = self.ki.get_login_info("GetServerGubun")

if len(self.server) == 0 or self.server != "1":
self.serverGubun = "실제운영서버"
else:
self.serverGubun = "모의투자서버"

self.set_logbox(self.serverGubun + " 접속성공")
'''
# 테스트 모드
self.ki = kiwoom()
self.ki.user_id = "키움아이디"


# 실시간 뉴스 버튼
self.notice_btn.clicked.connect(self.notice_btn_proc)

# 주문설정 버튼
self.order_btn.clicked.connect(self.order_btn_proc)

# 공시뉴스 크롤링 타이머
self.current_timer = None
self.current_timer_interval = 1000
self.current_timer_cnt = 0

# 공시뉴스 데이터
self.news_list = None

# 공시뉴스 긁어오기 시작
# self.start_timer()

# 뉴스 크롤링 및 매칭 서버
self.api_url = "나의API 주소는 비밀"

# 종료버튼
self.btn_exit.clicked.connect(self.news_exit)

def news_exit(self):
# myWindow.close()
self.close()

def order_btn_proc(self):
# 주문설정 팝업
self.osdlg = OrderSetupDialog()
self.osdlg.show()

def notice_btn_proc(self):
# 공시뉴스 팝업
self.dlg = NoticeDialog()
# self.dlg.exec_()
self.dlg.show()

def OnCustomWinClosed(self):
print("OnCustomWinClosed 호출됨")

def start_timer(self):
if self.current_timer:
self.current_timer.stop()
self.current_timer.deleteLater()

self.current_timer = QTimer()
self.current_timer.timeout.connect(self.start_news)
self.current_timer.setSingleShot(True)
self.current_timer.start(self.current_timer_interval)

def start_news(self):
self.current_timer_cnt = self.current_timer_cnt + 1
print("뉴스 타이머 (" + str(self.current_timer_cnt) + ")")
self.get_set_news()
self.start_timer()

# API 서버에서 뉴스크롤링 실행시키고, 바로 가져오기
def get_set_news(self):
# print("get_set_news 호출, stock_id = " + self.ki.user_id)
post_data = {"type": "getset", "stock_id": self.ki.user_id}
r = requests.post(self.api_url, data=post_data)
result_json = r.text # {"result":"OK"}

data = json.loads(result_json)
# print("get_set_news = " + dict['result'])

# 매칭된 키워드가 있으면 로그로 보여주기
'''
뉴스 쓰레드 가동(135)
{'111': ['(주)', '결과']}
'''
if data['log_text']:
self.set_logbox(data['log_text'])
'''
buy_code = re.split(',', data['buy_code'])
for row in buy_code:
if row:
self.ki.call_stock(row)
'''

# 뉴스 갱신
# print("data.list = " + data['list'])
self.news_list = data['list']

def set_logbox(self, msg):
content = self.logbox.toPlainText()
self.logbox.setText(msg + "\n" + content)

class NoticeDialog(QDialog):
def __init__(self):
super().__init__()

print("NoticeDialog 오픈됨.")

self.setGeometry(700, 200, 1000, 650)
self.setWindowTitle("실시간 공시뉴스")

self.notice_table = QTableWidget(self)
self.notice_table.setRowCount(20)
self.notice_table.setColumnCount(3)
self.notice_table.setColumnWidth(0, 720)
self.notice_table.setColumnWidth(1, 140)
self.notice_table.setColumnWidth(2, 90)
self.notice_table.setHorizontalHeaderLabels(['제목', '시간', '상세보기'])

self.layout = QGridLayout()
self.layout.addWidget(self.notice_table, 0, 0)

self.setLayout(self.layout)

self.current_news_timer = None
self.current_news_start = "YES"

# 공시뉴스 마지막 제목
self.last_title = None

self.news_timer()

# self.close()

def closeEvent(self, event):
print("closeEvent 호출됨")
event.ignore()
self.hide()
self.current_news_start = "NO"

def news_loading(self):
print("news_list = " + str(myWindow.news_list))
if myWindow.news_list != None:
cnt = 0
for row in myWindow.news_list:
if cnt == 0:
if self.last_title == row['title']:
break
else:
self.last_title = row['title']

# title = row['title'][0:30]
title = row['title']

self.notice_table.setItem(cnt, 0, QTableWidgetItem(title))
self.notice_table.setItem(cnt, 1, QTableWidgetItem(row['time']))
detailbtn = QPushButton("보기")
detailbtn.clicked.connect(partial(self.detailbtn_clicked, row['idx']))
self.notice_table.setCellWidget(cnt, 2, detailbtn)

# 데이터 갱신을 위해 포커스를 주자
self.notice_table.setCurrentCell(cnt, 0)
self.notice_table.setCurrentCell(cnt, 1)
self.notice_table.setCurrentCell(cnt, 2)
cnt = cnt + 1

if self.current_news_start == "YES":
self.news_timer()

# 기사 상세보기 띄우기
def detailbtn_clicked(self, idx):
url = myWindow.api_url + "?type=news_detail&idx=" + idx + "&stock_id=" + myWindow.ki.user_id
webbrowser.open(url)

def news_timer(self):
# print("news_timer 호출, self.current_news_timer = " + str(self.current_news_timer))
if self.current_news_timer:
self.current_news_timer.stop()
self.current_news_timer.deleteLater()

self.current_news_timer = QTimer()
self.current_news_timer.timeout.connect(self.news_loading)
self.current_news_timer.setSingleShot(True)
self.current_news_timer.start(1000)

class OrderSetupDialog(QDialog, order_ui):
def __init__(self):
super().__init__()

# print("OrderSetupDialog 오픈됨." + str(order_ui))
try:
self.setupUi(self)
except Exception as error:
print(error)

self.btn_order_add.clicked.connect(self.order_table_add)
self.btn_order_save.clicked.connect(self.order_save_proc)
self.vars = locals()

post_data = {"type": "order_get", "stock_id": myWindow.ki.user_id}
# print("post_data = " + str(post_data))

return_data = requests.post(myWindow.api_url, data=post_data)
return_data = return_data.text
# print("return_data = " + str(return_data))
r_data = json.loads(return_data)
order_list_number = 0
if r_data['result'] == "OK":
self.order_money.setText(r_data['buy_money'])
for row in r_data['data']:
# print(row['name'])
self.btn_order_add_proc(order_list_number)
self.vars['edit_name_%d' % order_list_number].setText(row['name'])
self.vars['edit_code_%d' % order_list_number].setText(row['code'])
order_list_number = order_list_number + 1
else:
QMessageBox.information(self, "알림", "주문설정 가져오기에 실패했습니다.")

def order_save_proc(self):
cnt = self.order_table.rowCount()
all_json = OrderedDict()
all_json_cnt = 0
for i in range(cnt):
row_json = OrderedDict()
row_json['name'] = self.vars['edit_name_%d' % i].text()
row_json['code'] = self.vars['edit_code_%d' % i].text()
all_json[str(all_json_cnt)] = row_json
all_json_cnt = all_json_cnt + 1

# print("all_json = " + str(all_json))
data = json.dumps(all_json)

buy_money = self.order_money.text()

post_data = {"type": "order_save", "stock_id": myWindow.ki.user_id, "data": data, "buy_money": buy_money}
# print("post_data = " + str(post_data))

return_data = requests.post(myWindow.api_url, data=post_data)
return_data = return_data.text
#print("return_data = " + str(return_data))
r_data = json.loads(return_data)
#print(r_data['result'])
if r_data['result'] == "OK":
QMessageBox.information(self, "알림", "저장성공")
elif r_data['result'] == "NO":
QMessageBox.information(self, "알림", r_data['msg'])

def order_table_add(self):
cnt = self.order_table.rowCount()
self.btn_order_add_proc(cnt)

def btn_order_add_proc(self, rowCnt):
# print("btn_order_add_proc 호출됨")
self.order_table.insertRow(rowCnt)

self.vars['edit_name_%d' % rowCnt] = QLineEdit()
self.order_table.setCellWidget(rowCnt, 0, self.vars['edit_name_%d' % rowCnt])

self.vars['edit_code_%d' % rowCnt] = QLineEdit()
self.order_table.setCellWidget(rowCnt, 1, self.vars['edit_code_%d' % rowCnt])

self.vars['btn_remove_%d' % rowCnt] = QPushButton("삭제" + str(rowCnt))
self.vars['btn_remove_%d' % rowCnt].clicked.connect(partial(self.btn_remove_clicked, rowCnt))
self.order_table.setCellWidget(rowCnt, 2, self.vars['btn_remove_%d' % rowCnt])

def btn_remove_clicked(self, index):
# print("btn_remove_clicked 호출, index = " + str(index))
rowCnt = self.order_table.rowCount()
for i in range(rowCnt):
if index > i:
continue
elif index == i:
self.order_table.removeRow(index)
else:
edit_name_value = self.vars['edit_name_%d' % i].text()
edit_code_value = self.vars['edit_code_%d' % i].text()

upper_number = i - 1
self.btn_order_add_proc(upper_number)
self.vars['edit_name_%d' % upper_number].setText(edit_name_value)
self.vars['edit_code_%d' % upper_number].setText(edit_code_value)

self.order_table.removeRow(i)

if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
sys.exit(app.exec_())

 

Comments


제목 글쓴이
파이썬 공시뉴스 자동매매 프로그램 ver2.0 댓글 11 관리자
키움API, 나의 매수리스트 불러오기 관리자
Qt Designer XML 을 py 소스로 변경작업   관리자
관리종목 필터링 추가 관리자
파이썬 뉴스 자동매매, 매수리스트 완료 관리자
뉴스자동매매, 매수로직 적용완료 관리자
실시간 뉴스, 종목 키워드, 주문 설정, 매수 패턴 적용완료 관리자
종목코드 데이터베이스에 저장 관리자
파이썬을 이용한 뉴스매매 ver2.0 실시간 뉴스 + 주문설정 페이지 제작완료 관리자
키움 API를 이용한 뉴스매매 ver2.0 개발시작 관리자
최종 완성본 이라기보다는 일단 프로토타입 완성 댓글 2 관리자
매수성공 관리자
매수 API가 안되길래 키움증권에 문의남김2. 관리자
매수 API가 안되길래 키움증권에 문의남김. 관리자
공시뉴스기사와 키워드 매칭작업 관리자
공시뉴스 초단위로 불러오기, 쓰레드 문제 해결 관리자
키움 로그인 창 띄우기 댓글 1 관리자
개발에 도움받은 페이지 목록 관리자
뉴스 크롤링 완료 관리자
파이참(PyCharm) 설치 관리자