Browse Source

moneydare

master
hyeonji0409 5 years ago
commit
bee0f632a6
  1. 3
      .idea/.gitignore
  2. 1
      .idea/.name
  3. 8
      .idea/Auto_stock.iml
  4. 6
      .idea/inspectionProfiles/profiles_settings.xml
  5. 7
      .idea/misc.xml
  6. 8
      .idea/modules.xml
  7. 6
      .idea/vcs.xml
  8. 220
      Kiwoom.py
  9. BIN
      __pycache__/Kiwoom.cpython-37.pyc
  10. BIN
      __pycache__/Kiwoom.cpython-38.pyc
  11. BIN
      __pycache__/Kiwoom.cpython-39.pyc
  12. BIN
      __pycache__/webreader.cpython-37.pyc
  13. BIN
      __pycache__/webreader.cpython-38.pyc
  14. BIN
      __pycache__/widgetfile.cpython-37.pyc
  15. BIN
      __pycache__/widgetfile.cpython-38.pyc
  16. 0
      buy_list.txt
  17. 2
      icon.png.url
  18. 0
      java.js
  19. BIN
      magic.xlsx
  20. 73
      magic_formula.py
  21. BIN
      magic_formula_data.xlsx
  22. 154
      predict.py
  23. 155
      pymon.py
  24. 381
      pytrader.py
  25. 649
      pytrader.ui
  26. 5
      sell_list.txt
  27. 17
      table.html
  28. 25
      test.html
  29. 2
      tmp/checkpoint
  30. BIN
      tmp/ckeckpointer.ckpt.data-00000-of-00001
  31. BIN
      tmp/ckeckpointer.ckpt.index
  32. 116
      webreader.py
  33. 15
      widgetfile.py

3
.idea/.gitignore

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

1
.idea/.name

@ -0,0 +1 @@
predict.py

8
.idea/Auto_stock.iml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.7 (5)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

6
.idea/inspectionProfiles/profiles_settings.xml

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

7
.idea/misc.xml

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (5)" project-jdk-type="Python SDK" />
<component name="PyCharmProfessionalAdvertiser">
<option name="shown" value="true" />
</component>
</project>

8
.idea/modules.xml

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/Auto_stock.iml" filepath="$PROJECT_DIR$/.idea/Auto_stock.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

220
Kiwoom.py

@ -0,0 +1,220 @@
import sys
from PyQt5.QtWidgets import *
from PyQt5.QAxContainer import *
from PyQt5.QtCore import *
import time
import pandas as pd
import sqlite3
TR_REQ_TIME_INTERVAL = 0.05
class Kiwoom(QAxWidget):
def __init__(self):
super().__init__()
self._create_kiwoom_instance()
self._set_signal_slots()
def _create_kiwoom_instance(self):
self.setControl("KHOPENAPI.KHOpenAPICtrl.1")
def _set_signal_slots(self):
self.OnEventConnect.connect(self._event_connect)
self.OnReceiveTrData.connect(self._receive_tr_data)
self.OnReceiveChejanData.connect(self._receive_chejan_data)
def comm_connect(self):
self.dynamicCall("CommConnect()")
self.login_event_loop = QEventLoop()
self.login_event_loop.exec_()
def _event_connect(self, err_code):
if err_code == 0:
print("connected")
else:
print("disconnected")
self.login_event_loop.exit()
def get_code_list_by_market(self, market):
code_list = self.dynamicCall("GetCodeListByMarket(QString)", market)
code_list = code_list.split(';')
return code_list[:-1]
def get_master_code_name(self, code):
code_name = self.dynamicCall("GetMasterCodeName(QString)", code)
return code_name
def get_connect_state(self):
ret = self.dynamicCall("GetConnectState()")
return ret
def get_login_info(self, tag):
ret = self.dynamicCall("GetLoginInfo(QString)", tag)
return ret
def set_input_value(self, id, value):
self.dynamicCall("SetInputValue(QString, QString)", id, value)
def comm_rq_data(self, rqname, trcode, next, screen_no):
self.dynamicCall("CommRqData(QString, QString, int, QString)", rqname, trcode, next, screen_no)
self.tr_event_loop = QEventLoop()
self.tr_event_loop.exec_()
def _comm_get_data(self, code, real_type, field_name, index, item_name):
ret = self.dynamicCall("CommGetData(QString, QString, QString, int, QString)", code,
real_type, field_name, index, item_name)
return ret.strip()
def _get_repeat_cnt(self, trcode, rqname):
ret = self.dynamicCall("GetRepeatCnt(QString, QString)", trcode, rqname)
return ret
def send_order(self, rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no):
self.dynamicCall("SendOrder(QString, QString, QString, int, QString, int, int, QString, QString)",
[rqname, screen_no, acc_no, order_type, code, quantity, price, hoga, order_no])
def get_chejan_data(self, fid):
ret = self.dynamicCall("GetChejanData(int)", fid)
return ret
def get_server_gubun(self):
ret = self.dynamicCall("KOA_Functions(QString, QString)", "GetServerGubun", "")
return ret
def _receive_chejan_data(self, gubun, item_cnt, fid_list):
print(gubun)
print(self.get_chejan_data(9203))
print(self.get_chejan_data(302))
print(self.get_chejan_data(900))
print(self.get_chejan_data(901))
def _receive_tr_data(self, screen_no, rqname, trcode, record_name, next, unused1, unused2, unused3, unused4):
if next == '2':
self.remained_data = True
else:
self.remained_data = False
if rqname == "opt10081_req":
self._opt10081(rqname, trcode)
elif rqname == "opw00001_req":
self._opw00001(rqname, trcode)
elif rqname == "opw00018_req":
self._opw00018(rqname, trcode)
try:
self.tr_event_loop.exit()
except AttributeError:
pass
@staticmethod
def change_format(data):
strip_data = data.lstrip('-0')
if strip_data == '' or strip_data == '.00':
strip_data = '0'
try:
format_data = format(int(strip_data), ',d')
except:
format_data = format(float(strip_data))
if data.startswith('-'):
format_data = '-' + format_data
return format_data
@staticmethod
def change_format2(data):
strip_data = data.lstrip('-0')
if strip_data == '':
strip_data = '0'
if strip_data.startswith('.'):
strip_data = '0' + strip_data
if data.startswith('-'):
strip_data = '-' + strip_data
return strip_data
def _opw00001(self, rqname, trcode):
d2_deposit = self._comm_get_data(trcode, "", rqname, 0, "d+2추정예수금")
self.d2_deposit = Kiwoom.change_format(d2_deposit)
def _opt10081(self, rqname, trcode):
data_cnt = self._get_repeat_cnt(trcode, rqname)
for i in range(data_cnt):
date = self._comm_get_data(trcode, "", rqname, i, "일자")
open = self._comm_get_data(trcode, "", rqname, i, "시가")
high = self._comm_get_data(trcode, "", rqname, i, "고가")
low = self._comm_get_data(trcode, "", rqname, i, "저가")
close = self._comm_get_data(trcode, "", rqname, i, "현재가")
volume = self._comm_get_data(trcode, "", rqname, i, "거래량")
self.ohlcv['date'].append(date)
self.ohlcv['open'].append(int(open))
self.ohlcv['high'].append(int(high))
self.ohlcv['low'].append(int(low))
self.ohlcv['close'].append(int(close))
self.ohlcv['volume'].append(int(volume))
def reset_opw00018_output(self):
self.opw00018_output = {'single': [], 'multi': []}
def _opw00018(self, rqname, trcode):
# single data
total_purchase_price = self._comm_get_data(trcode, "", rqname, 0, "총매입금액")
total_eval_price = self._comm_get_data(trcode, "", rqname, 0, "총평가금액")
total_eval_profit_loss_price = self._comm_get_data(trcode, "", rqname, 0, "총평가손익금액")
total_earning_rate = self._comm_get_data(trcode, "", rqname, 0, "총수익률(%)")
estimated_deposit = self._comm_get_data(trcode, "", rqname, 0, "추정예탁자산")
self.opw00018_output['single'].append(Kiwoom.change_format(total_purchase_price))
self.opw00018_output['single'].append(Kiwoom.change_format(total_eval_price))
self.opw00018_output['single'].append(Kiwoom.change_format(total_eval_profit_loss_price))
total_earning_rate = Kiwoom.change_format(total_earning_rate)
if self.get_server_gubun():
total_earning_rate = float(total_earning_rate) / 100
total_earning_rate = str(total_earning_rate)
self.opw00018_output['single'].append(total_earning_rate)
self.opw00018_output['single'].append(Kiwoom.change_format(estimated_deposit))
# multi data
rows = self._get_repeat_cnt(trcode, rqname)
for i in range(rows):
name = self._comm_get_data(trcode, "", rqname, i, "종목명")
quantity = self._comm_get_data(trcode, "", rqname, i, "보유수량")
purchase_price = self._comm_get_data(trcode, "", rqname, i, "매입가")
current_price = self._comm_get_data(trcode, "", rqname, i, "현재가")
eval_profit_loss_price = self._comm_get_data(trcode, "", rqname, i, "평가손익")
earning_rate = self._comm_get_data(trcode, "", rqname, i, "수익률(%)")
quantity = Kiwoom.change_format(quantity)
purchase_price = Kiwoom.change_format(purchase_price)
current_price = Kiwoom.change_format(current_price)
eval_profit_loss_price = Kiwoom.change_format(eval_profit_loss_price)
earning_rate = Kiwoom.change_format2(earning_rate)
self.opw00018_output['multi'].append([name, quantity, purchase_price, current_price, eval_profit_loss_price,
earning_rate])
if __name__ == "__main__":
app = QApplication(sys.argv)
kiwoom = Kiwoom()
kiwoom.comm_connect()
kiwoom.reset_opw00018_output()
account_number = kiwoom.get_login_info("ACCNO")
account_number = account_number.split(';')[0]
kiwoom.set_input_value("계좌번호", account_number)
kiwoom.comm_rq_data("opw00018_req", "opw00018", 0, "2000")
print(kiwoom.opw00018_output['single'])
print(kiwoom.opw00018_output['multi'])

BIN
__pycache__/Kiwoom.cpython-37.pyc

BIN
__pycache__/Kiwoom.cpython-38.pyc

BIN
__pycache__/Kiwoom.cpython-39.pyc

BIN
__pycache__/webreader.cpython-37.pyc

BIN
__pycache__/webreader.cpython-38.pyc

BIN
__pycache__/widgetfile.cpython-37.pyc

BIN
__pycache__/widgetfile.cpython-38.pyc

0
buy_list.txt

2
icon.png.url

@ -0,0 +1,2 @@
[InternetShortcut]
URL=https://github.com/pystockhub/book/blob/master/ch18/day04/icon.png

0
java.js

BIN
magic.xlsx

73
magic_formula.py

@ -0,0 +1,73 @@
import xlrd
import pandas as pd
# df = pd.read_ex
file_path = 'magic_formula_data.xlsx'
wd = xlrd.open_workbook(file_path)
pbr_sh = wd.sheet_by_name('PBR')
#'pbr' 순위 구하기. 양수 값의 데이터만 필요 & pbr값 작을수록 좋음
pbr_dict = {}
for i in range(1, pbr_sh.nrows):
data = pbr_sh.row_values(i)
name = data[0]
pbr = data[1]
if pbr > 0:
pbr_dict[name] = pbr
import operator
sorted_pbr = sorted(pbr_dict.items(),key=operator.itemgetter(1))
#pbr 순위 지정
pbr_rank = {}
for num, firm in enumerate(sorted_pbr):
pbr_rank[firm[0]] = num + 1
#GP_A 순위 구하기. 값이 존재하는 데이터만 필요 & GP_A 값 클 수록 좋음
gp_a_sh = wd.sheet_by_name('GP_A')
gp_a_dict = {}
for j in range(1, gp_a_sh.nrows):
data = gp_a_sh.row_values(j)
name = data[0]
gp_a = data[1]
if gp_a != 0:
gp_a_dict[name] = gp_a
sorted_gp_a = sorted(gp_a_dict.items(), key=operator.itemgetter(1), reverse=True)
gp_a_rank = {}
for num, firm in enumerate(sorted_gp_a):
gp_a_rank[firm[0]] = num + 1
total_rank = {}
for name in gp_a_rank.keys():
if name in pbr_rank.keys():
total_rank[name] = pbr_rank[name] + gp_a_rank[name]
#total_rank의 value 값을 기준키로 하여 total_rank를 오르차순으로 저장. value값이 작은 순서대로 정렬
sorted_total = sorted(total_rank.items(), key=operator.itemgetter(1))
magic_rank = {}
for num, firm in enumerate(sorted_total):
magic_rank[firm[0]] = num +1
sorted_magic = sorted(magic_rank.items(), key=operator.itemgetter(1))
print(sorted_magic[:20])
df = pd.DataFrame.from_records(sorted_magic[:20])
df.to_excel('magic.xlsx')

BIN
magic_formula_data.xlsx

154
predict.py

@ -0,0 +1,154 @@
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import os
import tensorflow as tf
import FinanceDataReader as fdr
#from Kiwoom import *
warnings.filterwarnings('ignore')
plt.rcParams['font.family'] = 'NanumGothic'
# 삼성전자(005930) 전체 (1996-11-05 ~ 현재)
# 데브시스터즈(194480)
# gs리테일(007070)
# 쎄미시스코(136510)
#해당시점 이후의 데이터
#apple = fdr.DataReader('AAPL', '2017')
STOCK_CODE = '005930'
stock = fdr.DataReader(STOCK_CODE)
stock.head()
stock.tail()
stock.index
stock['Year'] = stock.index.year
stock['Month'] = stock.index.month
stock['Day'] = stock.index.day
stock.head()
#plt.figure(figsize=(16, 9))
#sns.lineplot(y=stock['Close'], x=stock.index)
#plt.xlabel('time')
#plt.ylabel('price')
#time_steps = [['1990', '2000'],
# ['2000', '2010'],
# ['2010', '2015'],
# ['2015', '2021']]
#fig, axes = plt.subplots(2, 2)
##fig.set_size_inches(16, 9)
#for i in range(4):
# ax = axes[i//2, i%2]
# df = stock.loc[(stock.index > time_steps[i][0]) & (stock.index < time_steps[i][1])]
#sns.lineplot(y=df['Close'], x=df.index, ax=ax)
#ax.set_title(f'{time_steps[i][0]}~{time_steps[i][1]}')
#ax.set_xlabel('time')
#ax.set_ylabel('price')
#plt.tight_layout()
#plt.show()
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
# 스케일을 적용할 column을 정의합니다.
scale_cols = ['Open', 'High', 'Low', 'Close', 'Volume']
# 스케일 후 columns
scaled = scaler.fit_transform(stock[scale_cols])
scaled
df = pd.DataFrame(scaled, columns=scale_cols)
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(df.drop('Close', 1), df['Close'], test_size=0.2, random_state=0, shuffle=False)
x_train.shape, y_train.shape
x_test.shape, y_test.shape
x_train
#데이터셋구성
def windowed_dataset(series, window_size, batch_size, shuffle):
series = tf.expand_dims(series, axis=-1)
ds = tf.data.Dataset.from_tensor_slices(series)
ds = ds.window(window_size + 1, shift=1, drop_remainder=True)
ds = ds.flat_map(lambda w: w.batch(window_size + 1))
if shuffle:
ds = ds.shuffle(1000)
ds = ds.map(lambda w: (w[:-1], w[-1]))
return ds.batch(batch_size).prefetch(1)
WINDOW_SIZE=20
BATCH_SIZE=32
train_data = windowed_dataset(y_train, WINDOW_SIZE, BATCH_SIZE, True)
test_data = windowed_dataset(y_test, WINDOW_SIZE, BATCH_SIZE, False)
# 아래의 코드로 데이터셋의 구성을 확인해 볼 수 있습니다.
#X: (batch_size, window_size, feature)
#Y: (batch_size, feature)
for data in train_data.take(1):
print(f'데이터셋(X) 구성(batch_size, window_size, feature갯수): {data[0].shape}')
print(f'데이터셋(Y) 구성(batch_size, window_size, feature갯수): {data[1].shape}')
#모델
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, LSTM, Conv1D, Lambda
from tensorflow.keras.losses import Huber
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint
model = Sequential([
# 1차원 feature map 생성
Conv1D(filters=32, kernel_size=5,
padding="causal",
activation="relu",
input_shape=[WINDOW_SIZE, 1]),
# LSTM
LSTM(16, activation='tanh'),
Dense(16, activation="relu"),
Dense(1),
])
# Sequence 학습에 비교적 좋은 퍼포먼스를 내는 Huber()를 사용합니다.
loss = Huber()
optimizer = Adam(0.0005)
model.compile(loss=Huber(), optimizer=optimizer, metrics=['mse'])
# earlystopping은 10번 epoch통안 val_loss 개선이 없다면 학습을 멈춥니다.
earlystopping = EarlyStopping(monitor='val_loss', patience=10)
# val_loss 기준 체크포인터도 생성합니다.
filename = os.path.join('tmp', 'ckeckpointer.ckpt')
checkpoint = ModelCheckpoint(filename,
save_weights_only=True,
save_best_only=True,
monitor='val_loss',
verbose=1)
history = model.fit(train_data,
validation_data=(test_data),
epochs=50,
callbacks=[checkpoint, earlystopping])
model.load_weights(filename)
pred = model.predict(test_data)
pred.shape
plt.figure(figsize=(12, 9))
plt.plot(np.asarray(y_test)[20:], label='actual')
plt.plot(pred, label='prediction')
plt.grid()
plt.legend(loc='best')
#plt.tight_layout()
plt.show()

155
pymon.py

@ -0,0 +1,155 @@
import sys
from PyQt5.QtWidgets import *
import Kiwoom
import time
from pandas import DataFrame
import datetime
import webreader
import numpy as np
MARKET_KOSPI = 0
MARKET_KOSDAQ = 10
class PyMon:
def __init__(self):
self.kiwoom = Kiwoom.Kiwoom()
self.kiwoom.comm_connect()
self.get_code_list()
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.ohlcv = {'date': [], 'open': [], 'high': [], 'low': [], 'close': [], 'volume': []}
self.kiwoom.set_input_value("종목코드", code)
self.kiwoom.set_input_value("기준일자", start)
self.kiwoom.set_input_value("수정주가구분", 1)
self.kiwoom.comm_rq_data("opt10081_req", "opt10081", 0, "0101")
#0.2초의 간격을 두어 TR 요청 -> 더 늘려도 될 듯...?
time.sleep(0.5)
df = DataFrame(self.kiwoom.ohlcv, columns=['open', 'high', 'low', 'close', 'volume'],
index=self.kiwoom.ohlcv['date'])
return df
#이전 시점의 평균 거래랑을 특정 거래일 이전의 20일 동안의 평균 거래량으로 정의
#특정 거래일의 거래량이 평균 거래량보다 25% 초과일 때 급등한 것으로 정의
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) < 11:
return False
sum_vol20 = 0
today_vol = 0
for i, vol in enumerate(volumes):
if i == 0:
today_vol = vol
elif 1 <= i <= 10:
sum_vol20 += vol
else:
break
avg_vol20 = sum_vol20 / 10
# 25% 초과인지 알아내는 부분, 초과한다면 True
if today_vol > avg_vol20 * 10:
return True
#선정된 종목에 대한 정보 파일로 쓰기
# 매수전이라고 buylist에 적었기 때문에 다음날 코드를 실행하면 pytrader에서 프로그램 실행.
def update_buy_list(self, buy_list):
f = open("buy_list.txt", "wt")
for code in buy_list:
f.writelines("매수;%s;시장가;10;0;매수전\n" % (code))
f.close()
def run(self):
buy_list = []
num = len(self.kosdaq_codes)
for i, code in enumerate(self.kosdaq_codes):
print(i, '/', num)
if self.check_speedy_rising_volume(code):
buy_list.append(code)
self.update_buy_list(buy_list)
def calculate_estimated_dividend_to_treasury(self, code):
estimated_dividend_yield = webreader.get_estimated_dividend_yield(code)
print("calculate_estimated_dividend_to_treasury", estimated_dividend_yield)
if estimated_dividend_yield == 0:
estimated_dividend_yield = webreader.get_dividend_yield(code)
if estimated_dividend_yield == "":
estimated_dividend_yield = 0
current_3year_treasury = webreader.get_current_3year_treasury()
estimated_dividend_to_treasury = float(estimated_dividend_yield) / float(current_3year_treasury)
return estimated_dividend_to_treasury
def get_min_max_dividend_to_treasury(self, code):
previous_dividend_yield = webreader.get_previous_dividend_yield(code)
three_years_treasury = webreader.get_3year_treasury()
now = datetime.datetime.now()
cur_year = now.year
previous_dividend_to_treasury = {}
for year in range(cur_year-5, cur_year):
if year in previous_dividend_yield.keys() and year in three_years_treasury.keys():
ratio = float(previous_dividend_yield[year]) / float(three_years_treasury[year])
previous_dividend_to_treasury[year] = ratio
#print(previous_dividend_to_treasury)
if not previous_dividend_yield:
return (0, 0)
min_ratio = min(previous_dividend_to_treasury.values())
max_ratio = max(previous_dividend_to_treasury.values())
return (min_ratio, max_ratio)
def buy_check_by_dividend_algorithm(self, code):
estimated_dividend_to_treasury = self.calculate_estimated_dividend_to_treasury(code)
(min_ratio, max_ratio) = self.get_min_max_dividend_to_treasury(code)
if estimated_dividend_to_treasury >= max_ratio and max_ratio != 0:
return (1, estimated_dividend_to_treasury)
else:
return (0, estimated_dividend_to_treasury)
def run_dividend(self):
buy_list = []
for code in self.kospi_codes[100:150]:
time.sleep(0.5)
ret = self.buy_check_by_dividend_algorithm(code)
if ret[0] == 1:
buy_list.append((code, ret[1]))
sorted_list = sorted(buy_list, key=lambda t:t[1], reverse=True)
buy_list = []
for i in range(0, 5):
code = sorted_list[i][0]
buy_list.append(code)
self.update_buy_list(buy_list)
if __name__ == "__main__":
app = QApplication(sys.argv)
pymon = PyMon()
pymon.run_dividend()
#print(pymon.calculate_estimated_dividend_to_treasury('058470'))
#print(pymon.get_min_max_dividend_to_treasury("058470"))
#print(pymon.buy_check_by_dividend_algorithm("058470"))

381
pytrader.py

@ -0,0 +1,381 @@
import sys
from PyQt5.QtCore import *
from Kiwoom import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5 import uic
from widgetfile import *
from PyQt5 import QtCore, QtGui, QtWidgets
import time
from pandas_datareader import data
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from mplfinance.original_flavor import candlestick2_ohlc
from datetime import datetime
import matplotlib.ticker as ticker
import os
import plotly.graph_objects as go
import tkinter as tk
from tkinter import ttk
from IPython.display import display
form_class = uic.loadUiType("pytrader.ui")[0]
start_date = datetime(2020,5,8)
end_date = datetime(2020,10,8)
dialog = tk.Tk()
dialog1 = tk.Tk()
dialog2 = tk.Tk()
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.pushButton_4.clicked.connect(self.show_graph)
self.pushButton_5.clicked.connect(self.dialog_open)
self.pushButton_6.clicked.connect(self.dialog_open1)
self.pushButton_7.clicked.connect(self.dialog_open2)
# 차트확인하기 버튼
self.button = QPushButton('차트 확인',self)
self.button.clicked.connect(self.chart)
#self.button.clicked.connect(self.show_graph)
self.button.setGeometry(105,239,75,23)
self.chart = QDialog()
self.canvas = FigureCanvas(Figure())
self.load_buy_sell_list()
def dialog_open(self):
label = ttk.Label(dialog, text="현재 날짜를 기준으로 과거 거래 일 별로 시가, 고가, 저가, 종가, 거래량을 가져와 특정 거래일의 거래량이 평균 거래량보다 25% 초과시 매매하는 알고리즘")
label.pack()
dialog.title("급등주")
#self.dialog.geometry("300x300")
label.mainloop()
# def change_test(self):
# change_label.configure(text="text change")
# change_button
def dialog_open1(self):
label1 = ttk.Label(dialog1,
text="상위 20개의 종목을 추천하여 매수할 수 있도록 하는 알고리즘")
label1.pack()
dialog.title("신마법공식")
# self.dialog.geometry("300x300")
label1.mainloop()
def dialog_open2(self):
label2 = ttk.Label(dialog2,
text="과거의 데이터를 가지고 와 알고리즘 스스로 반복해 공부하여 향후 해당 주가에 대한 예측을 하는 알고리즘")
label2.pack()
dialog.title("주가예측")
# self.dialog.geometry("300x300")
label2.mainloop()
def show_graph(self):
code = self.lineEdit.text()
self.fig = plt.figure(figsize=(20, 10))
df1 = data.DataReader(code + ".ks", "yahoo")
ax = self.fig.add_subplot(111)
df1['MA20'] = df1['Adj Close'].rolling(window=20).mean()
df1['MA60'] = df1['Adj Close'].rolling(window=60).mean()
self.graph_viewer.canvas.axes.plot(df1.index, df1['Adj Close'], label='Adj Close')
self.graph_viewer.canvas.axes.plot(df1.index, df1['MA20'], label='MA20')
self.graph_viewer.canvas.axes.plot(df1.index, df1['MA60'], label='MA60')
data_name = '이동평균선'
#self.graph_viewer.canvas.axes.plot(x_list, y_list, label=data_name)
self.graph_viewer.canvas.axes.legend()
self.graph_viewer.canvas.axes.set_xlabel('Date')
self.graph_viewer.canvas.axes.set_ylabel('주가')
self.graph_viewer.canvas.draw()
def chart(self):
self.chart.setGeometry(600, 200, 1200, 600)
self.chart.setWindowTitle("PyChart Viewer v0.1")
self.chart.setWindowIcon(QIcon('icon.png'))
self.chart.lineEdit = QLineEdit()
self.chart.button1 = QPushButton("차트그리기")
self.chart.button1.clicked.connect(self.ButtonClicked)
self.chart.button2 = QPushButton("유동성차트 확인")
self.chart.button2.clicked.connect(self.ButtonClicked1)
self.fig = plt.Figure()
self.canvas = FigureCanvas(self.fig)
leftLayout = QVBoxLayout()
leftLayout.addWidget(self.canvas)
# Right Layout
rightLayout = QVBoxLayout()
rightLayout.addWidget(self.lineEdit)
rightLayout.addWidget(self.chart.button1)
rightLayout.addWidget(self.chart.button2)
rightLayout.addStretch(1)
layout = QHBoxLayout()
layout.addLayout(leftLayout)
layout.addLayout(rightLayout)
layout.setStretchFactor(leftLayout, 1)
layout.setStretchFactor(rightLayout, 0)
self.chart.setLayout(layout)
self.chart.show()
def ButtonClicked1(self):
code = self.lineEdit.text()
df = data.DataReader(code + ".ks", "yahoo")
candle = go.Candlestick(x=df.index,
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Close'])
fig = go.Figure(data=candle)
fig.show()
def ButtonClicked(self):
code = self.lineEdit.text()
df = data.DataReader(code + ".ks", "yahoo")
df['MA20'] = df['Adj Close'].rolling(window=20).mean()
df['MA60'] = df['Adj Close'].rolling(window=60).mean()
ax = self.fig.add_subplot(111)
"""ax.plot(df.index, df['Adj Close'], label='Adj Close')
ax.plot(df.index, df['MA20'], label='MA20')
ax.plot(df.index, df['MA60'], label='MA60')"""
ax.legend(loc='upper right')
candlestick2_ohlc(ax, df['Open'], df['High'],
df['Low'], df['Close'],
width=0.5, colorup='r', colordown='b')
ax.set_title('KOSPI INDEX', fontsize=22)
ax.set_xlabel('Date')
ax.grid()
plt.pause(0.001)
self.canvas.draw()
def closeEvent(self, event):
self.deleteLater()
def trade_stocks(self):
hoga_lookup = {'지정가': "00", '시장가': "03"}
f = open("buy_list.txt", 'rt', encoding='utf-8')
buy_list = f.readlines()
f.close()
f = open("sell_list.txt", 'rt', encoding='utf-8')
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", 'w', encoding='utf-8')
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", 'w', encoding='utf-8')
for row_data in sell_list:
f.write(row_data)
f.close()
def load_buy_sell_list(self):
f = open("buy_list.txt", 'rt', encoding='utf-8')
buy_list = f.readlines()
f.close()
f = open("sell_list.txt", 'rt', encoding='utf-8')
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.05)
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 closeEvent(self, event):
self.deleteLater()
if __name__ == "__main__":
app = QApplication(sys.argv)
myWindow = MyWindow()
myWindow.show()
sys.exit(app.exec())
window = MWindow()

649
pytrader.ui

@ -0,0 +1,649 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1055</width>
<height>789</height>
</rect>
</property>
<property name="windowTitle">
<string>PyTrader v0.4</string>
</property>
<property name="windowIcon">
<iconset>
<normaloff>Auto_Stock-main/Auto_Stock-main/icon.png</normaloff>Auto_Stock-main/Auto_Stock-main/icon.png</iconset>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 230, 216);</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>10</x>
<y>19</y>
<width>181</width>
<height>251</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 9pt &quot;나눔고딕&quot;;
background-color: rgb(255, 255, 255);
</string>
</property>
<property name="title">
<string>수동주문</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>계좌</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox">
<property name="geometry">
<rect>
<x>45</x>
<y>15</y>
<width>120</width>
<height>22</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);
</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>10</x>
<y>50</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>주문</string>
</property>
</widget>
<widget class="QComboBox" name="comboBox_2">
<property name="geometry">
<rect>
<x>45</x>
<y>45</y>
<width>120</width>
<height>22</height>
</rect>
</property>
<item>
<property name="text">
<string>신규매수</string>
</property>
</item>
<item>
<property name="text">
<string>신규매도</string>
</property>
</item>
<item>
<property name="text">
<string>매수취소</string>
</property>
</item>
<item>
<property name="text">
<string>매도취소</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>10</x>
<y>80</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>종목</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit">
<property name="geometry">
<rect>
<x>45</x>
<y>75</y>
<width>120</width>
<height>20</height>
</rect>
</property>
</widget>
<widget class="QComboBox" name="comboBox_3">
<property name="geometry">
<rect>
<x>45</x>
<y>135</y>
<width>120</width>
<height>22</height>
</rect>
</property>
<item>
<property name="text">
<string>지정가</string>
</property>
</item>
<item>
<property name="text">
<string>시장가</string>
</property>
</item>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>10</x>
<y>140</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>종류</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>10</x>
<y>170</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>수량</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>45</x>
<y>165</y>
<width>120</width>
<height>22</height>
</rect>
</property>
<property name="maximum">
<number>1000000</number>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>10</x>
<y>200</y>
<width>31</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>가격</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBox_2">
<property name="geometry">
<rect>
<x>45</x>
<y>195</y>
<width>120</width>
<height>22</height>
</rect>
</property>
<property name="prefix">
<string/>
</property>
<property name="maximum">
<number>10000000</number>
</property>
<property name="singleStep">
<number>100</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>10</x>
<y>220</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);
border-radius: 20px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>현금주문</string>
</property>
</widget>
<widget class="QLineEdit" name="lineEdit_2">
<property name="geometry">
<rect>
<x>45</x>
<y>105</y>
<width>120</width>
<height>20</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);</string>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_2">
<property name="geometry">
<rect>
<x>200</x>
<y>9</y>
<width>831</width>
<height>441</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 9pt &quot;나눔고딕&quot;;
</string>
</property>
<property name="title">
<string>잔고 및 보유종목현황</string>
</property>
<widget class="QTableWidget" name="tableWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>811</width>
<height>65</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);
</string>
</property>
<property name="rowCount">
<number>1</number>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>135</number>
</attribute>
<row/>
<column>
<property name="text">
<string>예수금 (d+2)</string>
</property>
</column>
<column>
<property name="text">
<string>총매입</string>
</property>
</column>
<column>
<property name="text">
<string>총평가</string>
</property>
</column>
<column>
<property name="text">
<string>총손익</string>
</property>
</column>
<column>
<property name="text">
<string>총수익률 (%)</string>
</property>
</column>
<column>
<property name="text">
<string>추정자산</string>
</property>
<property name="textAlignment">
<set>AlignCenter</set>
</property>
</column>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>750</x>
<y>410</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);
font: 9pt &quot;나눔고딕&quot;;
border-radius: 25px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>조회</string>
</property>
</widget>
<widget class="QGroupBox" name="groupBox_4">
<property name="geometry">
<rect>
<x>670</x>
<y>-140</y>
<width>611</width>
<height>131</height>
</rect>
</property>
<property name="title">
<string>잔고확인</string>
</property>
<widget class="QTableWidget" name="tableWidget_3">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>591</width>
<height>61</height>
</rect>
</property>
<column>
<property name="text">
<string>예수금</string>
</property>
</column>
<column>
<property name="text">
<string>총매입</string>
</property>
</column>
<column>
<property name="text">
<string>총평가</string>
</property>
</column>
<column>
<property name="text">
<string>총손익</string>
</property>
</column>
<column>
<property name="text">
<string>총수익률</string>
</property>
</column>
<column>
<property name="text">
<string>추정자산</string>
</property>
</column>
</widget>
<widget class="QPushButton" name="pushButton_3">
<property name="geometry">
<rect>
<x>490</x>
<y>90</y>
<width>75</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>현금주문</string>
</property>
</widget>
</widget>
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>660</x>
<y>410</y>
<width>81</width>
<height>16</height>
</rect>
</property>
<property name="text">
<string>실시간 조회</string>
</property>
</widget>
<widget class="QTableWidget" name="tableWidget_2">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>811</width>
<height>311</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);
</string>
</property>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>135</number>
</attribute>
<column>
<property name="text">
<string>종목명</string>
</property>
</column>
<column>
<property name="text">
<string>보유량</string>
</property>
</column>
<column>
<property name="text">
<string>매입가</string>
</property>
</column>
<column>
<property name="text">
<string>현재가</string>
</property>
</column>
<column>
<property name="text">
<string>평가손익</string>
</property>
</column>
<column>
<property name="text">
<string>수익률 (%)</string>
</property>
</column>
</widget>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>0</x>
<y>280</y>
<width>201</width>
<height>201</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">font: 9pt &quot;나눔고딕&quot;;
</string>
</property>
<property name="title">
<string>자동 선정 종목 리스트</string>
</property>
<widget class="QTableWidget" name="tableWidget_4">
<property name="geometry">
<rect>
<x>10</x>
<y>20</y>
<width>181</width>
<height>171</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);
border-radius:15px;</string>
</property>
<column>
<property name="text">
<string>주문유형</string>
</property>
</column>
<column>
<property name="text">
<string>종목명</string>
</property>
</column>
<column>
<property name="text">
<string>호가구분</string>
</property>
</column>
<column>
<property name="text">
<string>수량</string>
</property>
</column>
<column>
<property name="text">
<string>가격</string>
</property>
</column>
<column>
<property name="text">
<string>상태</string>
</property>
</column>
</widget>
</widget>
<widget class="Widget" name="graph_viewer" native="true">
<property name="geometry">
<rect>
<x>200</x>
<y>459</y>
<width>831</width>
<height>281</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="pushButton_4">
<property name="geometry">
<rect>
<x>20</x>
<y>490</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);
font: 9pt &quot;나눔고딕&quot;;
border-radius: 15px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>그래프 조회</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_5">
<property name="geometry">
<rect>
<x>20</x>
<y>550</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(246,211,148);
font: 9pt &quot;나눔고딕&quot;;
border-radius: 15px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>알고리즘 설명</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_6">
<property name="geometry">
<rect>
<x>20</x>
<y>620</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(242, 178, 121);
font: 9pt &quot;나눔고딕&quot;;
border-radius: 15px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>오늘도 공부하는 개미</string>
</property>
</widget>
<widget class="QPushButton" name="pushButton_7">
<property name="geometry">
<rect>
<x>20</x>
<y>690</y>
<width>161</width>
<height>41</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color:rgb(246,211,148);
font: 9pt &quot;나눔고딕&quot;;
border-radius: 15px;
border-color: rgb(255, 255, 255);</string>
</property>
<property name="text">
<string>기업 데이터는 여기서~</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1055</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>Widget</class>
<extends>QWidget</extends>
<header>widgetfile.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

5
sell_list.txt

@ -0,0 +1,5 @@
매수;001720;시장가;10;0;매수전
매수;001725;시장가;10;0;매수전
매수;002460;시장가;10;0;매수전
매수;001800;시장가;10;0;매수전
매수;001790;시장가;10;0;매수전

17
table.html

@ -0,0 +1,17 @@
<html>
<table border=1>
<tr>
<td> 항목 </td>
<td> 2013 </td>
<td> 2014 </td>
<td> 2015 </td>
</tr>
<tr>
<td> 매출액 </td>
<td> 100 </td>
<td> 200 </td>
<td> 300 </td>
</tr>
</table>
</html>

25
test.html

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<Script>
var account = {
예금주:"황기태", 계좌번호:"711-21-902010", 잔액:"20000"
}
document.write(account);
</Script>
</body>
</html>

2
tmp/checkpoint

@ -0,0 +1,2 @@
model_checkpoint_path: "ckeckpointer.ckpt"
all_model_checkpoint_paths: "ckeckpointer.ckpt"

BIN
tmp/ckeckpointer.ckpt.data-00000-of-00001

BIN
tmp/ckeckpointer.ckpt.index

116
webreader.py

@ -0,0 +1,116 @@
import requests
import pandas as pd
from bs4 import BeautifulSoup
import numpy as np
import datetime
pd.set_option('display.expand_frame_repr', False)
import re
def get_financial_statements(code):
# 인증값 추출
re_enc = re.compile("encparam: '(.*)'", re.IGNORECASE)
re_id = re.compile("id: '([a-zA-Z0-9]*)' ?", re.IGNORECASE)
url = "http://companyinfo.stock.naver.com/v1/company/c1010001.aspx?cmp_cd={}".format(code)
html = requests.get(url, verify=False).text
search = re_enc.search(html)
if search is None:
return {}
encparam = re_enc.search(html).group(1)
encid = re_id.search(html).group(1)
# 스크래핑
url = "http://companyinfo.stock.naver.com/v1/company/ajax/cF1001.aspx?cmp_cd={}&fin_typ=0&freq_typ=A&encparam={}&id={}".format(
code, encparam, encid)
headers = {"Referer": "HACK"}
html = requests.get(url, headers=headers, verify=False).text
soup = BeautifulSoup(html, "html5lib")
dividend = soup.select("table:nth-of-type(2) tr:nth-of-type(31) td span")
years = soup.select("table:nth-of-type(2) th")
dividend_dict = {}
for i in range(len(dividend)):
dividend_dict[years[i + 3].text.strip()[:4]] = dividend[i].text
return dividend_dict
def get_3year_treasury():
url = "http://www.index.go.kr/strata/jsp/showStblGams3.jsp?stts_cd=107301&idx_cd=1073&freq=Y&period=1997%3A2021"
html = requests.get(url, verify=False).text
soup = BeautifulSoup(html, 'html5lib')
td_data = soup.select("tr td")
treasury_3year = {}
start_year = 1998
for x in td_data:
treasury_3year[start_year] = x.text
start_year += 1
if start_year == datetime.datetime.now().year:
break
return treasury_3year
def get_dividend_yield(code):
url = "http://companyinfo.stock.naver.com/company/c1010001.aspx?cmp_cd=" + code
html = requests.get(url, verify=False).text
soup = BeautifulSoup(html, 'html5lib')
dt_data = soup.select("td dl dt")
dividend_yield = dt_data[-2].text
dividend_yield = dividend_yield.split(' ')[1]
dividend_yield = dividend_yield[:-1]
return dividend_yield
def get_estimated_dividend_yield(code):
dividend_yield = get_financial_statements(code)
if len(dividend_yield) == 0:
return 0
dividend_yield = sorted(dividend_yield.items())[-1]
return dividend_yield[1]
def get_current_3year_treasury():
url = "http://finance.naver.com/marketindex/interestDailyQuote.nhn?marketindexCd=IRR_GOVT03Y&page=1"
html = requests.get(url, verify=False).text
soup = BeautifulSoup(html, 'html5lib')
td_data = soup.select("tr td")
return td_data[1].text
def get_previous_dividend_yield(code):
dividend_yield = get_financial_statements(code)
now = datetime.datetime.now()
cur_year = now.year
previous_dividend_yield = {}
for year in range(cur_year - 5, cur_year):
if str(year) in dividend_yield:
previous_dividend_yield[year] = dividend_yield[str(year)]
return previous_dividend_yield
if __name__ == "__main__":
estimated_dividend_yield = get_estimated_dividend_yield("058470")
print(estimated_dividend_yield)
current_3year_treasury = get_current_3year_treasury()
print(current_3year_treasury)
estimated_dividend_to_treasury = float(estimated_dividend_yield) / float(current_3year_treasury)
print(estimated_dividend_to_treasury)
# print(get_estimated_dividend_yield('058470'))
# print(get_current_3year_treasury())
# print(get_previous_dividend_yield('058470'))

15
widgetfile.py

@ -0,0 +1,15 @@
from PyQt5.QtWidgets import*
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class Widget(QWidget):
def __init__(self, parent = None):
QWidget.__init__(self, parent)
self.canvas = FigureCanvas(Figure())
vertical_layout=QVBoxLayout()
vertical_layout.addWidget(self.canvas)
vertical_layout.setContentsMargins(1, 1, 1, 1)
self.canvas.axes=self.canvas.figure.add_subplot(111)
self.setLayout(vertical_layout)\
Loading…
Cancel
Save