diff --git a/HTS_252670.py b/HTS_252670.py index 5b31c2f..65b10ff 100644 --- a/HTS_252670.py +++ b/HTS_252670.py @@ -1,7 +1,6 @@ import time import os from datetime import datetime, timedelta -import pandas as pd from hts.HTS import HTS from hts.OrderType import OrderType @@ -9,6 +8,8 @@ from hts.OrderType import OrderType from hts.BuySellChecker import BuySellChecker from hts.OrderChecker import OrderChecker from stock.util.LabelChecker import LabelChecker +from stock.util.SlackBot import SlackBot +from stock.analysis.StockStatus import StockStatus class HTS_252670 (HTS): @@ -18,6 +19,8 @@ class HTS_252670 (HTS): orderChecker = None buySellChecker = None labelChecker = None + slackBot = None + stockStatus = None def __init__(self, RESOURCE_PATH, stock_code, buy_count): super().__init__(RESOURCE_PATH) @@ -29,6 +32,9 @@ class HTS_252670 (HTS): self.orderChecker = OrderChecker(self.RESOURCE_PATH) self.buySellChecker = BuySellChecker() self.labelChecker = LabelChecker(RESOURCE_PATH) + self.slackBot = SlackBot() + self.stockStatus = StockStatus(RESOURCE_PATH) + return def getSellingPrice(self, log_time, stock_code, final_price, check=False): @@ -55,7 +61,29 @@ class HTS_252670 (HTS): print("ORDER_SELL", stock_code, log_time.strftime('%Y%m%d %H%M%S'), jangoDic[code]['매도가능'], sell_price) return - def buyRealTime(self, today): + def makeTickData(self, data, mins=30): + result = {"check": set(), + "time": [], + "open": [], + "close": [], + "high": [], + "low": [], + "vol": [], + "label": []} + + for i in range(mins, len(data['time'])+1): + result["check"].add(data['time'][i-1]) + result["time"].append(data['time'][i-1]) + + result["open"].append(data['open'][i-mins]) + result["close"].append(data['close'][i-1]) + result["high"].append(max(data['high'][i - mins: i])) + result["low"].append(min(data['low'][i - mins: i])) + result["vol"].append(sum(data['vol'][i - mins: i])) + + return result + + def buyRealTime(self, today, analyzed_day=1000): print ("START...") THIS_TIME = datetime.now() @@ -65,38 +93,31 @@ class HTS_252670 (HTS): 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'): + # 3시 까지만 매수를 시도한다. - - if THIS_TIME < datetime.strptime(today + " 145000", '%Y%m%d %H%M%S'): - if THIS_TIME.strftime('%S') in ("06", "16", "26", "36", "46", "56"): - # 데이터를 가지고 온다. - result = self.getRealTime(self.stock_code, today, LAST_DATA) - final_price = result["close"][len(result["close"])-1] - - # 10초마다 체크하여 체결된 내역이 있으면 50원 높게 매도를 주문한다. - self.getSellingPrice(THIS_TIME, self.stock_code, final_price, check=True) - if THIS_TIME.strftime('%S') == "03": # 매분 3초마다 실행한다. # 데이터를 가지고 온다. result = self.getRealTime(self.stock_code, today, LAST_DATA) - # 규칙 기반의 분석을 통해서 볼린저밴드 상/하단을 계산한다. + result_5 = self.makeTickData(result, mins=5) + result_30 = self.makeTickData(result, mins=30) + data = self.buySellChecker.analyze(result) + data.drop(data.index[:len(data) - analyzed_day], inplace=True) - # 만약 미체결 내역이 있는데, 지표가 꺽여 내려온다면, 매수 주문을 취소 시킨다. - last_index = len(data['close']) - 1 - if data['slow_k'][last_index-1]>=80 and data['slow_k'][last_index-1] > data['slow_k'][last_index]: - # 미체결 기록을 가져온다. - ORDER_LIST = self.requestOrderList() - orderListToCancel = self.orderChecker.remove(self.stock_code, OrderType.sell, ORDER_LIST) - self.cancelOrderList(orderListToCancel) - print("CANCEL", THIS_TIME.strftime('%Y%m%d %H%M%S'), len(orderListToCancel), len(ORDER_LIST)) + # 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. + data_5 = self.buySellChecker.analyze(result_5) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + data_5.drop(data_5.index[:len(data_5) - analyzed_day], inplace=True) + data_30 = self.buySellChecker.analyze(result_30) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + data_30.drop(data_30.index[:len(data_30) - analyzed_day], inplace=True) - # 사야 할 시점/가격과 팔아야 할 시점/가격을 체크한다. - bsLine, data = self.buySellChecker.checkTransaction(data, self.stock_code, isRealTime=True) + # 사야 할 시점과 팔아야 할 시점을 체크한다. + bsLine = self.buySellChecker.checkTransaction(stock_code, data, data_5, data_30, isRealTime=True) bs_buy_price = bsLine['buy'][0] bs_buy_weight = bsLine['buy_weight'][0] bs_sell_price = bsLine['sell'][0] @@ -110,33 +131,30 @@ class HTS_252670 (HTS): # 매수를 주문한다. orderNum = self.requestOrder(OrderType.buy, self.stock_code, BUY_COUNT , bs_buy_price) + # slackbot에 메시지를 보냄 + self.slackBot.post_to_slack(stock_code, stock_name, "BUY", bsLine['buy'][len(bsLine['buy']) - 1], buy_count) + self.orderChecker.add(today, stock_code, 1, buy_count, bs_buy_price, orderNum) - # 미체결 기록을 가져온다. - ORDER_LIST = self.requestOrderList() - # 매수 주문을 기록한다. - orderListToCancel = self.orderChecker.add(self.stock_code, OrderType.buy, orderNum, BUY_COUNT, bs_buy_price, ORDER_LIST) - # 1 시간 이전 미체결을 모두 취소한다. - self.cancelOrderList(orderListToCancel) # 로그 출력 - 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'), orderNum, stock_code, stock_name, bs_buy_price, buy_count) if bs_sell_price > 0: - # 미체결 기록을 가져온다. - ORDER_LIST = self.requestOrderList() - # 매도 주문을 기록을 가져온다. - orderListToCancel = self.orderChecker.delete(self.stock_code, OrderType.sell, ORDER_LIST) - # 매도 미체결을 모두 취소한다. - self.cancelOrderList(orderListToCancel) - # 매도한다. - self.getSellingPrice(THIS_TIME, self.stock_code, final_price) + orderNum = self.getSellingPrice(THIS_TIME, self.stock_code, final_price) + + # slackbot에 메시지를 보냄 + self.slackBot.post_to_slack(stock_code, stock_name, "SELL", bsLine['sell'][len(bsLine['sell']) - 1], -1) + self.orderChecker.delete(today, stock_code) + + # 로그 출력 + print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), str(orderNum), stock_code, stock_name, bs_sell_price) # 로그 출력 - print("TIMECHECK: %s, price: %d, avg3: %.2f, avg5: %.2f, avg10: %.2f, slow_k: %.2f, open: %d, high: %d, low: %d" % - (str(THIS_TIME), final_price, - data["avg3"][data_size - 1], data["avg6"][data_size - 1], data["avg9"][data_size - 1], data["slow_k"][data_size - 2], - data["open"][data_size - 1], data["high"][data_size - 1], data["low"][data_size - 1],)) + print("TIMECHECK: %s, price: %d, avg5: %.2f, avg30: %.2f, slow_k: %.2f, open: %d, high: %d, low: %d" % + (str(THIS_TIME), final_price, data["avg5"][data_size - 1], data["avg30"][data_size - 1], + data["slow_k"][data_size - 2], data["open"][data_size - 1], data["high"][data_size - 1], data["low"][data_size - 1],)) + 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분 사이는 잔량을 매도한다. diff --git a/HTS_Downloader.py b/HTS_Downloader.py index 9791a38..159e6f8 100644 --- a/HTS_Downloader.py +++ b/HTS_Downloader.py @@ -20,8 +20,8 @@ if __name__ == "__main__": # KODEX 인버스 * 2 stocks = [ - {"stock_code": "252670", "stock_name": "KODEX 200선물인버스2X", "start_date": datetime.strptime("20221121",'%Y%m%d'), "end_date": datetime.today()}, - {"stock_code": "122630", "stock_name": "KODEX 레버리지", "start_date": datetime.strptime("20220916",'%Y%m%d'), "end_date": datetime.today()} + {"stock_code": "252670", "stock_name": "KODEX 200선물인버스2X", "start_date": datetime.strptime("20230120",'%Y%m%d'), "end_date": datetime.today()}, + {"stock_code": "122630", "stock_name": "KODEX 레버리지", "start_date": datetime.strptime("20230120",'%Y%m%d'), "end_date": datetime.today()} ] hts = HTS_Downloader(RESOURCE_PATH) diff --git a/resources/hts.db b/resources/hts.db index e222cfa..c4cdb6f 100644 Binary files a/resources/hts.db and b/resources/hts.db differ