diff --git a/hts/HTS.py b/hts/HTS.py index fa66154..f893361 100644 --- a/hts/HTS.py +++ b/hts/HTS.py @@ -456,13 +456,13 @@ class HTS: return data - def insertStockData(self, inFileName, stock_code, stock_name, today): + def insertStockData(self, db_filename, stock_code, stock_name, today): tableName = 'hts' - conn = sqlite3.connect(inFileName) + conn = sqlite3.connect(db_filename) cursor = conn.cursor() # 테이블 생성 - cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL)") + cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, label INTEGER DEFAULT 0)") # 키 생성 create_key = "CREATE INDEX IF NOT EXISTS " + tableName + "_idx on " + tableName + " (CODE, ymd, hms) " @@ -474,7 +474,7 @@ class HTS: items = self.getStockInfo(stock_code, today) - conn = sqlite3.connect(inFileName) + conn = sqlite3.connect(db_filename) cursor = conn.cursor() idx = 0 for item in items: @@ -548,6 +548,46 @@ class HTS: result["vol"].append(int(vol)) return + def updateLabel(self, db_filename, stock_code, bsLine, data, ymd): + tableName = 'hts' + conn = sqlite3.connect(db_filename) + cursor = conn.cursor() + + cursor.execute('Update ' + tableName + ' set label=? WHERE CODE=? and ymd=?', (0, stock_code, ymd,)) + + for i in range(len(bsLine["buy"])): + if bsLine["buy"][i] > 0: + ymd = data['date'][i].strftime('%Y%m%d') + hms = data['date'][i].strftime('%H%M') + cursor.execute('Update ' + tableName + ' set label=? WHERE CODE=? and ymd=? and hms=?', (2, stock_code, ymd, hms)) + + for i in range(len(bsLine["sell"])): + if bsLine["sell"][i] > 0: + ymd = data['date'][i].strftime('%Y%m%d') + hms = data['date'][i].strftime('%H%M') + cursor.execute('Update ' + tableName + ' set label=? WHERE CODE=? and ymd=? and hms=?', (1, stock_code, ymd, hms)) + + conn.commit() + cursor.close() + conn.close() + print("insert...", stock_code, ymd) + return + + def getYMD(self, stock_code): + tableName = 'hts' + conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db")) + cursor = conn.cursor() + + result = [] + cursor.execute('SELECT distinct ymd FROM ' + tableName + ' WHERE CODE=? order by ymd', (stock_code,)) + db_result = cursor.fetchall() + for rows in db_result: + ymd = rows[0] # hts.날짜 + + result.append(ymd) + + return result + def getDBData(self, stock_code, day, result): tableName = 'hts' conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "hts.db")) diff --git a/resources/hts.db b/resources/hts.db index d7570ba..b48e16b 100644 Binary files a/resources/hts.db and b/resources/hts.db differ diff --git a/stock/util/DBManager.py b/stock/util/DBManager.py index 5fb7564..8d563d1 100644 --- a/stock/util/DBManager.py +++ b/stock/util/DBManager.py @@ -14,7 +14,7 @@ class DBManager: cursor = conn.cursor() # 테이블 생성 - cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, label INTEGER)") + cursor.execute("CREATE TABLE IF NOT EXISTS " + tableName + " (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, label INTEGER DEFAULT 0)") # 키 생성 create_key = "CREATE INDEX IF NOT EXISTS " + tableName + "_idx on " + tableName + " (CODE, ymd, hms, label) " diff --git a/stock/util/LabelMaker.py b/stock/util/LabelMaker.py index bdac927..7b6c5bd 100644 --- a/stock/util/LabelMaker.py +++ b/stock/util/LabelMaker.py @@ -1,5 +1,6 @@ import os import csv +import logging from math import nan import pandas as pd import plotly.graph_objects as go @@ -17,7 +18,7 @@ class LabelMaker (HTS): self.buySellChecker = BuySellChecker() return - def checkTransaction(self, data): + def checkTransaction(self, data, duration=60): bsLine = {} size = len(data["close"]) @@ -27,18 +28,17 @@ class LabelMaker (HTS): bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1 for i in range(size)] + # 매수 처리 p_min_price = 999999999 - p_max_price = 999999999 - for i in range(size-60): - min_price, min_price_c, max_price, max_price_c = 9999999, -1, 0, -1 - for c in range(i, i+60): + # - 10을 한 것은 3시 11분까지 매매를 하기 위함임 + for i in range(size-duration-10): + min_price, min_price_c, = 9999999, -1 + for c in range(i, i+duration): if min(data["close"][c], data["close"][c]) < min_price: min_price = min(data["close"][c], data["close"][c]) min_price_c = c - if max(data["close"][c], data["close"][c]) > max_price: - max_price = max(data["close"][c], data["close"][c]) - max_price_c = c + # 매수 처리 if min_price_c > 0: isValid = True for c in range(2, 10): @@ -50,17 +50,43 @@ class LabelMaker (HTS): bsLine['buy'][min_price_c] = min_price bsLine['buy_weight'][min_price_c] = 1 p_min_price = min_price - if max_price_c > 0 and bsLine['buy'][max_price_c-2] < 0: - isValid = True - for c in range(2, 10): - if bsLine['buy'][max_price_c - c] > 0: - isValid = False - break - if isValid: - if max_price > p_max_price: - bsLine['sell'][max_price_c] = max_price - bsLine['sell_weight'][max_price_c] = 1 - p_max_price = max_price + + # 매도 처리 + buy_i = [c for c in range(size) if bsLine['buy'][c] > 0] + for i in range(len(buy_i)): + if i < len(buy_i)-1: + boundry = data["high"][buy_i[i]+1: buy_i[i+1]] + if len(boundry) > 1: + max_price = max(boundry) + for c in range(buy_i[i], buy_i[i+1]): + if data["high"][c] == max_price: + isValid = False + for d in range(c - 1, 0, -1): + if bsLine['sell'][d] > 0 and bsLine['buy'][d] < 0: + break + if bsLine['sell'][d] < 0 and bsLine['buy'][d] > 0: + isValid = True + break + if isValid: + bsLine['sell'][c] = max_price + bsLine['sell_weight'][c] = 1 + else: + boundry = data["high"][buy_i[i] + 1:] + if len(boundry) > 1: + max_price = max(boundry) + for c in range(buy_i[i], len(data["high"])): + if data["high"][c] == max_price: + isValid = False + for d in range(c-1, 0, -1): + if bsLine['sell'][d] > 0 and bsLine['buy'][d] < 0 : + break + if bsLine['sell'][d] < 0 and bsLine['buy'][d] > 0 : + isValid = True + break + if isValid: + bsLine['sell'][c] = max_price + bsLine['sell_weight'][c] = 1 + return bsLine, data def draw_simple(self, stock_code, given_day, data, bsLine): @@ -200,15 +226,18 @@ class LabelMaker (HTS): return - def writeLabelFile(self, bsLine, data, ymd): - outFileName = os.path.join(self.RESOURCE_PATH, "tmp", ymd+".sell.csv") + def writeLabelFile(self, stock_code, bsLine, data, ymd): + if not os.path.isdir(os.path.join(self.RESOURCE_PATH, "tmp")): + os.mkdir(os.path.join(self.RESOURCE_PATH, "tmp")) + + outFileName = os.path.join(self.RESOURCE_PATH, "tmp", stock_code+"."+ymd+".sell.csv") with open(outFileName, "w", encoding="utf-8") as outFp: writer = csv.writer(outFp) for i, price in enumerate(bsLine["sell"]): if price != -1: writer.writerow([data['date'][i], bsLine["sell"][i]]) - outFileName = os.path.join(self.RESOURCE_PATH, "tmp", ymd + ".buy.csv") + outFileName = os.path.join(self.RESOURCE_PATH, "tmp", stock_code+"."+ymd + ".buy.csv") with open(outFileName, "w", encoding="utf-8") as outFp: writer = csv.writer(outFp) for i, price in enumerate(bsLine["buy"]): @@ -216,25 +245,42 @@ class LabelMaker (HTS): writer.writerow([data['date'][i], bsLine["buy"][i]]) return - def makeCandidate(self, stock_code, ymd="20220727"): + def makeCandidate(self, stock_code, ymd="20220727", view=False): result = {"check": set(), "time": [], "open": [], "close": [], "high": [], "low": [], "vol": [], "label": []} self.getDBData(stock_code, ymd, result) data = self.buySellChecker.analyze(result) bsLine, data = self.checkTransaction(data) - self.writeLabelFile(bsLine, data, ymd) - self.draw_simple(stock_code, ymd, data, bsLine) - self.draw_detail(stock_code, ymd, data, bsLine) - return + self.writeLabelFile(stock_code, bsLine, data, ymd) + if view: + self.draw_simple(stock_code, ymd, data, bsLine) + #self.draw_detail(stock_code, ymd, data, bsLine) + + return bsLine, data + + def getDate(self, stock_code): + ymds = self.getYMD(stock_code) + return ymds if __name__ == "__main__": PROJECT_HOME = os.path.join(os.path.dirname(os.path.join(os.path.dirname(os.path.join(os.path.dirname(__file__)))))) RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources") + db_filename = os.path.join(RESOURCE_PATH, "hts.db") labelMaker = LabelMaker() + view = True stock_code = "252670" - #stock_code = "122630" + ymd = "20200701" - labelMaker.makeCandidate(stock_code, "20220801") \ No newline at end of file + if view: + bsLine, data = labelMaker.makeCandidate(stock_code, ymd, view=view) + else: + stock_codes = ["252670", "122630"] + for stock_code in stock_codes: + ymds = labelMaker.getDate(stock_code) + for ymd in ymds: + logging.info(stock_code, ymd) + bsLine, data = labelMaker.makeCandidate(stock_code, ymd) + labelMaker.updateLabel(db_filename, stock_code, bsLine, data, ymd)