This commit is contained in:
dosangyoon
2022-07-30 16:08:37 +09:00
parent d230a51652
commit cddcdf4f35
6 changed files with 321 additions and 165 deletions

View File

@@ -31,12 +31,6 @@ class HTS_122630 (HTS):
def checkTransaction(self, data): def checkTransaction(self, data):
size = len(data["close"]) size = len(data["close"])
bsLine = {}
bsLine['buy'] = [-1 for i in range(size)]
bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)]
buy, weight, sell = -1, -1, -1
last_index = size - 1 last_index = size - 1
sell, weight = self.buySellChecker.getSellPriceAndWeight_15000(data, last_index) sell, weight = self.buySellChecker.getSellPriceAndWeight_15000(data, last_index)
buy, weight = self.buySellChecker.getBuyPriceAndWeight_15000(data, last_index) buy, weight = self.buySellChecker.getBuyPriceAndWeight_15000(data, last_index)
@@ -77,34 +71,41 @@ class HTS_122630 (HTS):
return 0, 0 return 0, 0
def buyRealTime(self, lastday, today): def buyRealTime(self, today):
timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist() timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist()
timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList} timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList}
print("START...") print ("START...")
THIS_TIME = datetime.now() THIS_TIME = datetime.now()
final_sell_check = False final_sell_check = False
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", LAST_DATA = self.getLastData(self.stock_code, today)
'%Y%m%d %H%M%S'):
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'):
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'): if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
# 3시 까지만 매수를 시도한다.
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]: if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
# 데이터를 가지고 온다. # 데이터를 가지고 온다.
result = self.getRealTime(self.stock_code, lastday, today) result = self.getRealTime(self.stock_code, today, LAST_DATA)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result) data = self.buySellChecker.analyzeByRule(result)
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data) bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, True)
bs_buy_price = bsLine['buy']
bs_weight = bsLine['buy_weight']
bs_sell_price = bsLine['sell']
data_size = len(data["close"]) data_size = len(data["close"])
final_price = data["close"][data_size - 1] final_price = data["close"][data_size-1]
if bs_buy_price > 0: if bs_buy_price > 0:
# 기본 100 주에 가중치를 추가해서 매수한다. # 기본 100 주에 가중치를 추가해서 매수한다.
#33BUY_COUNT = int(self.buy_count * bs_weight) BUY_COUNT = int(self.buy_count * bs_weight)
BUY_COUNT = int(self.buy_count * 1)
# 매수를 주문한다. # 매수를 주문한다.
orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT, bs_buy_price) orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT, bs_buy_price)
@@ -118,6 +119,7 @@ class HTS_122630 (HTS):
# 로그 출력 # 로그 출력
print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), BUY_COUNT, bs_buy_price, len(orderListToCancel), len(ORDER_LIST)) print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), BUY_COUNT, bs_buy_price, len(orderListToCancel), len(ORDER_LIST))
if bs_sell_price > 0: if bs_sell_price > 0:
# 미체결 기록을 가져온다. # 미체결 기록을 가져온다.
ORDER_LIST = self.requestOrderList() ORDER_LIST = self.requestOrderList()
@@ -136,9 +138,9 @@ class HTS_122630 (HTS):
# 로그 출력 # 로그 출력
print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), selling_count, selling_price, len(orderListToCancel), len(ORDER_LIST)) print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), selling_count, selling_price, len(orderListToCancel), len(ORDER_LIST))
# 로그 출력 # 로그 출력
print( print("TIMECHECK: %s, price: %d, open: %d, high: %d, low: %d, avg3: %.2f, avg5: %.2f, avg10: %.2f, avg20: %.2f, avg30: %.2f, avg60: %.2f,\n lower: %.2f, upper: %.2f, macd: %.2f, macds: %.2f, macdo: %.2f,\n rsi: %.2f, rsis: %.2f, fast_k: %.2f, slow_k: %.2f, slow_d: %.2f" %
"TIMECHECK: %s, price: %d, open: %d, high: %d, low: %d, avg3: %.2f, avg5: %.2f, avg10: %.2f, avg20: %.2f, avg30: %.2f, avg60: %.2f,\n lower: %.2f, upper: %.2f, macd: %.2f, macds: %.2f, macdo: %.2f,\n rsi: %.2f, rsis: %.2f, fast_k: %.2f, slow_k: %.2f, slow_d: %.2f" %
(str(THIS_TIME), final_price, data["open"][data_size - 1], data["high"][data_size - 1], (str(THIS_TIME), final_price, data["open"][data_size - 1], data["high"][data_size - 1],
data["low"][data_size - 1], data["low"][data_size - 1],
data["avg3"][data_size - 1], data["avg5"][data_size - 1], data["avg10"][data_size - 1], data["avg3"][data_size - 1], data["avg5"][data_size - 1], data["avg10"][data_size - 1],
@@ -151,10 +153,11 @@ class HTS_122630 (HTS):
timecheck[THIS_TIME] = True timecheck[THIS_TIME] = True
elif datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151600", '%Y%m%d %H%M%S'): elif datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151600", '%Y%m%d %H%M%S'):
# 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다.
if not final_sell_check: if not final_sell_check:
#### ####
# 손해 보지 않는 가격에 매도한다. # 손해봐도 매도한다.
#### ####
# 주문 리스트를 가져온다. # 주문 리스트를 가져온다.
@@ -163,9 +166,12 @@ class HTS_122630 (HTS):
self.cancelOrderList(orderList) self.cancelOrderList(orderList)
# 매도 가격을 가져온다. # 매도 가격을 가져온다.
result = self.getRealTime(self.stock_code, lastday, today) result = self.getRealTime(self.stock_code, today, LAST_DATA)
final_price = result["close"][len(result["close"]) - 1] final_price = result["close"][len(result["close"]) - 1]
selling_count, selling_price = self.getFinalSellingPrice(final_price) selling_count, selling_price = self.getFinalSellingPrice(final_price)
# selling_count, selling_price = self.getSellingPrice(final_price)
# 분석되 가격으로 매도 요청한다. # 분석되 가격으로 매도 요청한다.
if selling_count != 0 and selling_price != 0: if selling_count != 0 and selling_price != 0:
orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price) orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price)
@@ -193,15 +199,8 @@ if __name__ == "__main__":
hts = HTS_122630(RESOURCE_PATH, stock_code, buy_count) hts = HTS_122630(RESOURCE_PATH, stock_code, buy_count)
today_str = today.strftime('%Y%m%d') today_str = today.strftime('%Y%m%d')
lastday_str = ""
for i in range(1, 10):
lastday_str = (today - timedelta(i)).strftime('%Y%m%d')
last_hts_data_filename = os.path.join(RESOURCE_PATH, "hts", stock_code + "_" + lastday_str + ".csv")
if os.path.isfile(last_hts_data_filename):
break
hts.buyRealTime(lastday_str, today_str) hts.buyRealTime(today_str)
#hts.writeStockData(stock_code, today_str)
db_filename = os.path.join(RESOURCE_PATH, "hts.db") db_filename = os.path.join(RESOURCE_PATH, "hts.db")
hts.insertStockData(db_filename, stock_code, stock_name, today_str) hts.insertStockData(db_filename, stock_code, stock_name, today_str)

View File

@@ -29,20 +29,6 @@ class HTS_252670 (HTS):
self.buySellChecker = BuySellChecker() self.buySellChecker = BuySellChecker()
return return
def checkTransaction(self, data):
size = len(data["close"])
bsLine = {}
bsLine['buy'] = [-1 for i in range(size)]
bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)]
last_index = size - 1
#buy, weight, sell = self.buySellChecker.getPriceAndWeight3(hts, last_index)
sell, weight = self.buySellChecker.getSellPriceAndWeight_3000(data, last_index)
buy, weight = self.buySellChecker.getBuyPriceAndWeight_3000(data, last_index)
return buy, weight, sell
def getSellingPrice(self, final_price): def getSellingPrice(self, final_price):
# 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다.
jangoDic = self.requstJango() jangoDic = self.requstJango()
@@ -78,7 +64,7 @@ class HTS_252670 (HTS):
return 0, 0 return 0, 0
def buyRealTime(self, lastday, today): def buyRealTime(self, today):
timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist() timecheckList = pd.read_csv("hts/timecheck.csv").values.tolist()
timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList} timecheck = {today + " " + str(second).zfill(6):False for second, check in timecheckList}
@@ -86,29 +72,33 @@ class HTS_252670 (HTS):
print ("START...") print ("START...")
THIS_TIME = datetime.now() THIS_TIME = datetime.now()
final_sell_check = False final_sell_check = False
LAST_DATA = self.getLastData(self.stock_code, today)
while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'): while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'):
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 150000", '%Y%m%d %H%M%S'): if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
# 3시 까지만 매수를 시도한다. # 3시 까지만 매수를 시도한다.
if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]: if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]:
# 데이터를 가지고 온다. # 데이터를 가지고 온다.
result = self.getRealTime(self.stock_code, lastday, today) result = self.getRealTime(self.stock_code, today, LAST_DATA)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result) data = self.buySellChecker.analyzeByRule(result)
# 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다.
bs_buy_price, bs_weight, bs_sell_price = self.checkTransaction(data) bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, True)
bs_buy_price = bsLine['buy']
bs_weight = bsLine['buy_weight']
bs_sell_price = bsLine['sell']
data_size = len(data["close"]) data_size = len(data["close"])
final_price = data["close"][data_size-1] final_price = data["close"][data_size-1]
if bs_buy_price > 0: if bs_buy_price > 0:
# 기본 100 주에 가중치를 추가해서 매수한다. # 기본 100 주에 가중치를 추가해서 매수한다.
BUY_COUNT = int(self.buy_count * bs_weight) BUY_COUNT = int(self.buy_count * bs_weight)
#BUY_COUNT = int(self.buy_count * 1)
# 매수를 주문한다. # 매수를 주문한다.
orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT , bs_buy_price) orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT , bs_buy_price)
@@ -159,6 +149,9 @@ class HTS_252670 (HTS):
# 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다. # 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다.
if not final_sell_check: if not final_sell_check:
####
# 손해 보지 않는 가격에 매도한다.
####
# 주문 리스트를 가져온다. # 주문 리스트를 가져온다.
orderList = self.requestOrderList() orderList = self.requestOrderList()
@@ -166,10 +159,12 @@ class HTS_252670 (HTS):
self.cancelOrderList(orderList) self.cancelOrderList(orderList)
# 매도 가격을 가져온다. # 매도 가격을 가져온다.
result = self.getRealTime(self.stock_code, lastday, today) result = self.getRealTime(self.stock_code, today, LAST_DATA)
final_price = result["close"][len(result["close"]) - 1] final_price = result["close"][len(result["close"]) - 1]
#selling_count, selling_price = self.getFinalSellingPrice(final_price) #selling_count, selling_price = self.getFinalSellingPrice(final_price)
selling_count, selling_price = self.getSellingPrice(final_price) selling_count, selling_price = self.getSellingPrice(final_price)
# 분석된 가격으로 매도 요청한다. # 분석된 가격으로 매도 요청한다.
if selling_count != 0 and selling_price != 0: if selling_count != 0 and selling_price != 0:
orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price) orderNum = self.requestOrder(OrderType.sell, self.stock_code, selling_count, selling_price)
@@ -197,15 +192,8 @@ if __name__ == "__main__":
hts = HTS_252670(RESOURCE_PATH, stock_code, buy_count) hts = HTS_252670(RESOURCE_PATH, stock_code, buy_count)
today_str = today.strftime('%Y%m%d') today_str = today.strftime('%Y%m%d')
lastday_str = ""
for i in range(1, 10):
lastday_str = (today - timedelta(i)).strftime('%Y%m%d')
last_hts_data_filename = os.path.join(RESOURCE_PATH, "hts", stock_code + "_" + lastday_str + ".csv")
if os.path.isfile(last_hts_data_filename):
break
hts.buyRealTime(lastday_str, today_str) hts.buyRealTime(today_str)
#hts.writeStockData(stock_code, today_str)
db_filename = os.path.join(RESOURCE_PATH, "hts.db") db_filename = os.path.join(RESOURCE_PATH, "hts.db")
hts.insertStockData(db_filename, stock_code, stock_name, today_str) hts.insertStockData(db_filename, stock_code, stock_name, today_str)

View File

@@ -1,20 +1,22 @@
from math import nan from math import nan
from datetime import datetime, timedelta from datetime import datetime, timedelta
import csv import copy
import pandas as pd import pandas as pd
import plotly.graph_objects as go import plotly.graph_objects as go
from plotly import subplots from plotly import subplots
import sqlite3 import sqlite3
import os import os
from hts.HTS import HTS
from hts.BuySellChecker import BuySellChecker from hts.BuySellChecker import BuySellChecker
class Simulation: class Simulation (HTS):
buySellChecker = None buySellChecker = None
stock_code = None stock_code = None
def __init__(self, RESOURCE_PATH, stock_code): def __init__(self, RESOURCE_PATH, stock_code):
super().__init__(RESOURCE_PATH)
self.buySellChecker = BuySellChecker() self.buySellChecker = BuySellChecker()
self.stock_code = stock_code self.stock_code = stock_code
@@ -22,59 +24,6 @@ class Simulation:
#self.connect() #self.connect()
return return
def getCSV(self, fileName, given_day, result):
with open(fileName, 'r', encoding='utf-8') as infp:
reader = csv.reader(infp)
next(reader)
for rows in reader:
days = rows[0] # hts.날짜
time = rows[1] # hts.시간
open_v = rows[2] # hts.시가
high = rows[3] # hts.고가
low = rows[4] # hts.저가
close = rows[5] # hts.종가
vol = rows[6] # hts.거래량
start_time = datetime.strptime(given_day + " 090000", '%Y%m%d %H%M%S')
temp = datetime.strptime(str(days) + " " + str(time).zfill(4)+"00", '%Y%m%d %H%M%S')
#if temp < start_time:
# continue
result["time"].append(temp)
result["open"].append(int(open_v))
result["close"].append(int(close))
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
return
def getDBData(self, stock_code, lastday, result):
tableName = 'hts'
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor()
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
db_result = cursor.fetchall()
for rows in db_result:
ymd = rows[0] # hts.날짜
hms = rows[1] # hts.시간
open = rows[2] # hts.시가
high = rows[3] # hts.고가
low = rows[4] # hts.저가
close = rows[5] # hts.종가
vol = rows[6] # hts.거래량
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
result["time"].append(temp)
result["open"].append(int(open))
result["close"].append(int(close))
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
return
def draw(self, stock_code, given_day, data, bsLine): def draw(self, stock_code, given_day, data, bsLine):
# 어제 데이터는 지운다. # 어제 데이터는 지운다.
data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])] data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])]
@@ -180,30 +129,27 @@ class Simulation:
return return
def getRealTime(self, stock_code, today, LAST_DATA=None):
if LAST_DATA is not None:
result = copy.deepcopy(LAST_DATA)
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
self.getDBData(stock_code, today, result)
return result
def simulate(self, today): def simulate(self, today):
result = {"check": set(), LAST_DATA = self.getLastData(self.stock_code, today)
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
# 데이터를 가지고 온다. result = self.getRealTime(self.stock_code, today, LAST_DATA)
#self.getCSV(path + "/" + self.stock_code + "_" + last_day + ".csv", last_day, result)
#self.getCSV(path + "/" + self.stock_code + "_" + today + ".csv", last_day, result)
for i in range(1, 10):
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
self.getDBData(self.stock_code, last_day, result)
if len(result['time']) > 0:
break
self.getDBData(self.stock_code, today, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다. # 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.buySellChecker.analyze(result) data = self.buySellChecker.analyzeByRule(result)
# 사야 할 시점과 팔아야 할 시점을 체크한다. # 사야 할 시점과 팔아야 할 시점을 체크한다.
bsLine = self.buySellChecker.checkTransaction(data, self.stock_code) bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, False)
# 그래프를 그린다. # 그래프를 그린다.
self.draw(self.stock_code, today, data, bsLine) self.draw(self.stock_code, today, data, bsLine)

View File

@@ -10,6 +10,7 @@ class BuySellChecker:
common = None common = None
stochastic = None stochastic = None
rsi = None rsi = None
macd = None
ichimokuCloud = None ichimokuCloud = None
def __init__(self): def __init__(self):
@@ -752,7 +753,7 @@ class BuySellChecker:
def analyze(self, result): def analyzeByRule(self, result):
open = result["open"] open = result["open"]
close = result["close"] close = result["close"]
high = result["high"] high = result["high"]
@@ -835,24 +836,44 @@ class BuySellChecker:
return data return data
def checkTransaction(self, data, stock_code): def checkTransaction(self, data, stock_code, type=True):
size = len(data["close"]) # 4일치 중에서 앞에 2일은 제거한다.
date = data['date'].dt.date.unique().tolist()
data = data[data['date'].dt.date != date[0]]
data = data[data['date'].dt.date != date[1]]
# 어제 오늘 데이터로 분석
bsLine = {} bsLine = {}
bsLine['buy'] = [-1 for i in range(size)] size = len(data["close"])
bsLine['weight'] = [-1 for i in range(size)] if type:
bsLine['sell'] = [-1 for i in range(size)] last_index = size - 1
for i in range(size):
if stock_code == "252670": if stock_code == "252670":
sell, weight = self.getSellPriceAndWeight_3000(data, i) sell, weight = self.getSellPriceAndWeight_3000(data, last_index)
buy, weight = self.getBuyPriceAndWeight_3000(data, i) buy, weight = self.getBuyPriceAndWeight_3000(data, last_index)
else: else:
sell, weight = self.getSellPriceAndWeight_15000(data, i) sell, weight = self.getSellPriceAndWeight_15000(data, last_index)
buy, weight = self.getBuyPriceAndWeight_15000(data, i) buy, weight = self.getBuyPriceAndWeight_15000(data, last_index)
bsLine['buy'][i] = buy bsLine['buy'] = buy
bsLine['weight'][i] = weight bsLine['buy_weight'] = weight
bsLine['sell'][i] = sell bsLine['sell'] = sell
bsLine['sell_weight'] = weight
else:
bsLine['buy'] = [-1 for i in range(size)]
bsLine['weight'] = [-1 for i in range(size)]
bsLine['sell'] = [-1 for i in range(size)]
return bsLine for i in range(size):
if stock_code == "252670":
sell, weight = self.getSellPriceAndWeight_3000(data, i)
buy, weight = self.getBuyPriceAndWeight_3000(data, i)
else:
sell, weight = self.getSellPriceAndWeight_15000(data, i)
buy, weight = self.getBuyPriceAndWeight_15000(data, i)
bsLine['buy'][i] = buy
bsLine['weight'][i] = weight
bsLine['sell'][i] = sell
return bsLine, data

View File

@@ -1,10 +1,12 @@
import os.path import os.path
import copy
import win32com.client import platform
if platform.system().lower().find("window") >= 0:
import win32com.client
import csv import csv
import time import time
import sqlite3 import sqlite3
from datetime import datetime from datetime import datetime, timedelta
from hts.OrderItem import OrderItem from hts.OrderItem import OrderItem
class HTS: class HTS:
@@ -546,12 +548,12 @@ class HTS:
result["vol"].append(int(vol)) result["vol"].append(int(vol))
return return
def getDBData(self, stock_code, lastday, result): def getDBData(self, stock_code, day, result):
tableName = 'hts' tableName = 'hts'
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db")) conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,)) cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, day,))
db_result = cursor.fetchall() db_result = cursor.fetchall()
for rows in db_result: for rows in db_result:
ymd = rows[0] # hts.날짜 ymd = rows[0] # hts.날짜
@@ -570,10 +572,21 @@ class HTS:
result["high"].append(int(high)) result["high"].append(int(high))
result["low"].append(int(low)) result["low"].append(int(low))
result["vol"].append(int(vol)) result["vol"].append(int(vol))
return return
# 주식 현재가 조회 def isValidYMD(self, stock_code, day):
def getRealTime(self, stock_code, lastday, today): tableName = 'hts'
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor()
cursor.execute('SELECT ymd, count(*) as cnt FROM ' + tableName + ' WHERE CODE=? and ymd=?', (stock_code, day,))
db_result = cursor.fetchone()
if db_result[1] > 0:
return True
return False
def getLastData(self, stock_code, today, n=3):
result = {"check": set(), result = {"check": set(),
"time": [], "time": [],
"open": [], "open": [],
@@ -582,9 +595,29 @@ class HTS:
"low": [], "low": [],
"vol": []} "vol": []}
#last_stock_filename = os.path.join(self.RESOURCE_PATH, "hts", stock_code + "_" + lastday + ".csv") days = []
#self.getCSV(last_stock_filename, result) for i in range(1, 10):
self.getDBData(stock_code, lastday, result) last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
isValid = self.isValidYMD(stock_code, last_day)
if isValid:
days.append(last_day)
if len(days) >= 3:
break
days.sort()
for day in days:
self.getDBData(stock_code, day, result)
return result
# 주식 현재가 조회
def getRealTime(self, stock_code, today, LAST_DATA=None):
if LAST_DATA is not None:
result = copy.deepcopy(LAST_DATA)
else:
result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": []}
self.getDBData(stock_code, today, result)
int_given_day = int(today) int_given_day = int(today)
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos") objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")

View File

@@ -1,15 +1,184 @@
import os
import sqlite3
from datetime import datetime, timedelta
import pandas as pd
from stock.analysis.Common import Common
from stock.analysis.Stochastic import Stochastic
from stock.analysis.RSI import RSI
from stock.analysis.MACD import MACD
from stock.analysis.IchimokuCloud import IchimokuCloud
class Stock2Vector: class Stock2Vector:
def __init__(self): RESOURCE_PATH = None
common = None
stochastic = None
rsi = None
macd = None
ichimokuCloud = None
def __init__(self, RESOURCE_PATH):
self.RESOURCE_PATH = RESOURCE_PATH
self.common = Common()
self.stochastic = Stochastic()
self.rsi = RSI()
self.macd = MACD()
self.ichimokuCloud = IchimokuCloud()
return return
def read(self, fileName): def analyze(self, result):
return None open = result["open"]
close = result["close"]
high = result["high"]
low = result["low"]
vol = result["vol"]
def process(self, vector): close_df = pd.DataFrame(close)
avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist()
avg3 = [item[0] for item in avg3_list]
avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist()
avg5 = [item[0] for item in avg5_list]
avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist()
avg10 = [item[0] for item in avg10_list]
avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist()
avg20 = [item[0] for item in avg20_list]
avg30_list = close_df.rolling(window=30).mean().fillna(close[0]).values.tolist()
avg30 = [item[0] for item in avg30_list]
avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist()
avg60 = [item[0] for item in avg60_list]
df = pd.DataFrame(close)
max20 = df.rolling(window=20).mean()
stddev20 = df.rolling(window=20).std()
upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드
lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드
upper, lower = [], []
for i in range(len(upper_df)):
if i < 10:
upper.append(upper_df.values[0][0])
lower.append(lower_df.values[0][0])
else:
upper.append(upper_df.values[i][0])
lower.append(lower_df.values[i][0])
point_temp = result["time"]
STOCK = []
for i in range(len(open)):
STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i],
'avg3': avg3[i], 'avg5': avg5[i],'avg10': avg10[i],'avg20': avg20[i],'avg30': avg30[i],'avg60': avg60[i]})
# stochastic 계산
stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5)
stochastic_df = stochastic_df.fillna(100)
fast_k = stochastic_df['fast_k'].values.tolist()
slow_k = stochastic_df['slow_k'].values.tolist()
slow_d = stochastic_df['slow_d'].values.tolist()
# macd 계산
macd_df = self.macd.apply(STOCK, short=12, long=26, t=9)
macd_df = macd_df.fillna(100)
macd = macd_df['macd'].values.tolist()
macds = macd_df['macds'].values.tolist()
macdo = macd_df['macdo'].values.tolist()
# rsi 계산
rsi_df = self.rsi.apply(STOCK, period=30, window=5)
rsi_df = rsi_df.fillna(100)
rsi = rsi_df['rsi'].values.tolist()
rsis = rsi_df['rsis'].values.tolist()
# ichimokuCloud 계산
# ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52)
# ichimokuCloud_df = rsi_df.fillna(100)
# changeLine = rsi_df['changeLine'].values.tolist()
# baseLine = rsi_df['baseLine'].values.tolist()
# leadingSpan1 = rsi_df['leadingSpan1'].values.tolist()
# leadingSpan2 = rsi_df['leadingSpan2'].values.tolist()
temp = {"date": point_temp,
"open": open, "high": high, "low": low, "close": close, "volume": vol, "upper": upper, "lower": lower,
"avg3": avg3, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg60": avg60,
"macd": macd, "macds": macds, "macdo": macdo,
"fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d,
"rsi": rsi, "rsis": rsis}
data = pd.DataFrame(temp)
df_final_time = pd.DatetimeIndex(point_temp)
data.index = df_final_time
data.fillna(0)
return data
def getDBData(self, stock_code, lastday, result):
tableName = 'hts'
conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db"))
cursor = conn.cursor()
cursor.execute('SELECT ymd, hms, open, high, low, close, volume FROM ' + tableName + ' WHERE CODE=? and ymd=? order by ymd, hms', (stock_code, lastday,))
db_result = cursor.fetchall()
for rows in db_result:
ymd = rows[0] # hts.날짜
hms = rows[1] # hts.시간
open = rows[2] # hts.시가
high = rows[3] # hts.고가
low = rows[4] # hts.저가
close = rows[5] # hts.종가
vol = rows[6] # hts.거래량
temp = datetime.strptime(str(ymd) + " " + str(hms).zfill(4) + "00", '%Y%m%d %H%M%S')
result["time"].append(temp)
result["open"].append(int(open))
result["close"].append(int(close))
result["high"].append(int(high))
result["low"].append(int(low))
result["vol"].append(int(vol))
return return
def vectorize(self, stock_code, given_day):
result = {"check": set(),
"time": [],
"open": [],
"close": [],
"high": [],
"low": [],
"vol": []}
for i in range(1, 10):
last_day = (datetime.strptime(given_day, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
self.getDBData(stock_code, last_day, result)
if len(result['time']) > 0:
break
self.getDBData(stock_code, given_day, result)
# 분석을 통해서 볼린저밴드 상/하단을 계산한다.
data = self.analyze(result)
return data
if __name__ == "__main__": if __name__ == "__main__":
stock2Vector = Stock2Vector() PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__))))))
fileName = "./resources/hts/252670_20220726.csv" RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
stock2Vector = Stock2Vector(RESOURCE_PATH)
# to check bying
stock_codes = {
# 252670
# 122630
"122630": ['20220725'],
}
for stock_code in stock_codes:
for given_day in stock_codes[stock_code]:
stock2Vector.vectorize(stock_code, given_day)
print ("done...")