diff --git a/HTS_Alert.py b/HTS_Alert.py new file mode 100644 index 0000000..5654a68 --- /dev/null +++ b/HTS_Alert.py @@ -0,0 +1,185 @@ +import re +import os +import time +import math +import sqlite3 +from datetime import datetime + +from hts.HTS import HTS +from hts.OrderType import OrderType + +from hts.BuySellChecker import BuySellChecker +from hts.OrderChecker import OrderChecker +from stock.util.SlackBot import SlackBot +from stock.analysis.StockStatus import StockStatus + +class HTS_Stocks (HTS): + + RESOURCE_PATH = None + orderChecker = None + buySellChecker = None + labelChecker = None + slackBot = None + stockStatus = None + analyzed_day = None + MAX_BUY_PRICE = None + + conn_stock = None + cursor_stock = None + + def __init__(self, RESOURCE_PATH): + super().__init__(RESOURCE_PATH) + self.slackBot = SlackBot() + + self.RESOURCE_PATH = RESOURCE_PATH + self.stockStatus = StockStatus(RESOURCE_PATH) + + self.buySellChecker = BuySellChecker() + self.orderChecker = OrderChecker(self.RESOURCE_PATH, "STOCK") + + self.analyzed_day = 120 + self.MAX_BUY_PRICE = 300000 + + return + + def connect2StockDB(self): + + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) + self.cursor_stock = self.conn_stock.cursor() + + return + + def disconnectStockDB(self): + + self.cursor_stock.close() + self.conn_stock.close() + return + + def getCompanyInfo(self, today_stock): + + self.cursor_stock.execute('SELECT distinct code, name FROM stock order by code') + all_stocks = self.cursor_stock.fetchall() + + valid_company = dict() + self.cursor_stock.execute('select CODE, NAME, max(ymd) as ymd from fnguide where type != "E" and sales > 0 group by 1 order by sales desc') + items = self.cursor_stock.fetchall() + for i, item in enumerate(items): + if item[0] in today_stock: + valid_company[item[0]] = i + + return all_stocks, valid_company + + def buyRealTime(self, today, n = 200): + print ("START...") + THIS_TIME = datetime.now() + + today_stock = self.get_today_stock() + all_stocks, valid_company = self.getCompanyInfo(today_stock) + + while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'): + + # 1515 까지만 매수를 시도한다. + if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'): + + # 매도를 체크한다. + #self.sellStocks() + + for idx, item in enumerate(all_stocks): + if THIS_TIME < datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') or datetime.strptime(today + " 151500", '%Y%m%d %H%M%S') < THIS_TIME: + break + + time.sleep(0.1) + + stock_code = item[0] + stock_name = item[1] + if (stock_code not in valid_company): + continue + + print("%5d: %8s, %-50s" % (idx, stock_code, stock_name)) + + stock = self.stockStatus.fetchLastData(self.cursor_stock, stock_code, n) + try: + self.getRealTime_DailyCheck(today, stock_code, stock) + data = self.stockStatus.analyze(stock, self.analyzed_day) + except: + print("#ERROR:", stock_code, stock_name) + continue + + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + data.drop(data.index[:len(data) - self.analyzed_day], inplace=True) + + bs_buy_price = data["close"][len(data["close"]) - 1] + + # 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다. + ORDER_LIST = self.requestOrderList() + orderListToCancel = self.orderChecker.cancel(today, "A" + stock_code, ORDER_LIST, mins=10) + if len(orderListToCancel) > 0: + self.cancelOrderList(orderListToCancel) + + # 다음 조건이면 매수한다. + if bs_buy_price > 1000: + + if not self.orderChecker.exist(today, "A" + stock_code, hours=5): + buy_count = int(self.MAX_BUY_PRICE / bs_buy_price) + + if buy_count > 0: + + # 매수를 주문한다. + orderNum = self.requestOrder(OrderType.buy, stock_code, buy_count, bs_buy_price) + self.orderChecker.buy(today, "A" + stock_code, buy_count, bs_buy_price, orderNum) + + # slackbot에 메시지를 보냄 + self.slackBot.post_to_slack(stock_code, stock_name, "BUY", bs_buy_price, buy_count) + + # 로그 출력 + print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, stock_name, bs_buy_price, buy_count) + + time.sleep(3600) + THIS_TIME = datetime.now() + + return + + def updteTodayStock(self, db_filename, stock_code, today_str): + bsLine, data = self.labelChecker.makeCandidate(stock_code, today_str) + self.labelChecker.updateLabel(db_filename, stock_code, bsLine, data, today_str) + return + + def get_today_stock(self): + today_stock = set() + today_stock.add("311320") + today_stock.add("311390") + today_stock.add("290380") + today_stock.add("333430") + today_stock.add("200350") + today_stock.add("009410") + today_stock.add("053950") + today_stock.add("027710") + today_stock.add("246690") + today_stock.add("096530") + today_stock.add("201490") + today_stock.add("008420") + today_stock.add("302550") + today_stock.add("039240") + today_stock.add("377330") + today_stock.add("025550") + today_stock.add("006340") + today_stock.add("001440") + return today_stock + +if __name__ == "__main__": + today = datetime.today() + + PROJECT_HOME = os.getcwd() + RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources") + + hts = HTS_Stocks(RESOURCE_PATH) + hts.connect2DB("hts.db") + hts.connect2StockDB() + + today_str = today.strftime('%Y%m%d') + hts.buyRealTime(today_str) + + hts.disconnectStockDB() + hts.disconnect() + + print ("done...") diff --git a/HTS_etf.py b/HTS_etf.py index d3a02a1..7f5df10 100644 --- a/HTS_etf.py +++ b/HTS_etf.py @@ -39,7 +39,7 @@ class HTS_etf(HTS): def connect2StockDB(self): - self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) self.cursor_stock = self.conn_stock.cursor() return diff --git a/HTS_etf_long.py b/HTS_etf_long.py index a01da20..49b8c46 100644 --- a/HTS_etf_long.py +++ b/HTS_etf_long.py @@ -39,7 +39,7 @@ class HTS_etf (HTS): def connect2StockDB(self): - self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) self.cursor_stock = self.conn_stock.cursor() return diff --git a/HTS_etf_short.py b/HTS_etf_short.py index 3784876..74eee50 100644 --- a/HTS_etf_short.py +++ b/HTS_etf_short.py @@ -39,7 +39,7 @@ class HTS_etf (HTS): def connect2StockDB(self): - self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) self.cursor_stock = self.conn_stock.cursor() return diff --git a/HTS_stocks.py b/HTS_stocks.py index badee95..5654a68 100644 --- a/HTS_stocks.py +++ b/HTS_stocks.py @@ -44,7 +44,7 @@ class HTS_Stocks (HTS): def connect2StockDB(self): - self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) self.cursor_stock = self.conn_stock.cursor() return diff --git a/analyzer/SPCorrelationAnalyzer.py b/analyzer/SPCorrelationAnalyzer.py index ba3924e..36e05a0 100644 --- a/analyzer/SPCorrelationAnalyzer.py +++ b/analyzer/SPCorrelationAnalyzer.py @@ -1,4 +1,5 @@ import os +import json import sqlite3 import pandas as pd @@ -224,18 +225,25 @@ if __name__ == "__main__": spCorrelationAnalyzer = SPCorrelationAnalyzer(stockFileName) - # {"stock_code": "122630", "stock_name": "KODEX 레버리지"} - # {"stock_code": "252670", "stock_name": "KODEX 200선물인버스2X"} - # {"stock_code": "^NDX", "stock_name": "NASDAQ 100"} - # {"stock_code": "TQQQ", "stock_name": "ProShares UltraPro QQQ"} - # {"stock_code": "SQQQ", "stock_name": "ProShares UltraPro Short QQQ"} - # {"stock_code": "SOXL", "stock_name": "Direxion Daily Semiconductor Bull 3X Shares"} - # {"stock_code": "SOXS", "stock_name": "Direxion Daily Semiconductor Bear -3X Shares"} - corr_scores = spCorrelationAnalyzer.analyze(master_code='SOXS') - corr_scores_list = sorted(corr_scores.items(), key=lambda item: item[1], reverse=True) - for item in corr_scores_list: - print("%s %4.3f" % (item[0], item[1])) + inputs = [ + {"stock_code": "122630", "stock_name": "KODEX 레버리지", "corr": []}, + {"stock_code": "252670", "stock_name": "KODEX 200선물인버스2X", "corr": []}, + {"stock_code": "^NDX", "stock_name": "NASDAQ 100", "corr": []}, + {"stock_code": "TQQQ", "stock_name": "ProShares UltraPro QQQ", "corr": []}, + {"stock_code": "SQQQ", "stock_name": "ProShares UltraPro Short QQQ", "corr": []}, + {"stock_code": "SOXL", "stock_name": "Direxion Daily Semiconductor Bull 3X Shares", "corr": []}, + {"stock_code": "SOXS", "stock_name": "Direxion Daily Semiconductor Bear -3X Shares", "corr": []} + ] + for input in inputs: + corr_scores = spCorrelationAnalyzer.analyze(master_code=input["stock_code"]) + corr_scores_list = sorted(corr_scores.items(), key=lambda item: item[1], reverse=True) + for item in corr_scores_list: + input["corr"].append({item[0]: item[1]}) + print("%s,%s,%4.3f" % (input["stock_code"], item[0], item[1])) + outFileName = os.path.join(PROJECT_HOME, 'analyzer/corr.json') + with open(outFileName, 'w', encoding='utf-8') as file: + json.dump(inputs, file, indent="\t", ensure_ascii=False) print('done...')