diff --git a/HTS_stocks.py b/HTS_stocks.py index 0de42ff..9984ab2 100644 --- a/HTS_stocks.py +++ b/HTS_stocks.py @@ -3,7 +3,7 @@ import os import time import math import sqlite3 -from datetime import datetime +from datetime import datetime, timedelta from hts.HTS import HTS from hts.OrderType import OrderType @@ -34,7 +34,7 @@ class HTS_Stocks (HTS): self.RESOURCE_PATH = RESOURCE_PATH self.stockStatus = StockStatus(RESOURCE_PATH) - self.buySellChecker = BuySellChecker() + self.buySellChecker = BuySellChecker(RESOURCE_PATH) self.orderChecker = OrderChecker(self.RESOURCE_PATH, "STOCK") self.analyzed_day = 120 @@ -44,7 +44,7 @@ class HTS_Stocks (HTS): def connect2StockDB(self): - self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "resources/stock.db")) + self.conn_stock = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) self.cursor_stock = self.conn_stock.cursor() return @@ -55,84 +55,79 @@ class HTS_Stocks (HTS): 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 sellStocks(self, stock_code, golden=True): + check = False + jangoDic = self.requstJango() + if jangoDic and len(jangoDic.keys()) > 0: + for code in jangoDic: + if stock_code is not None: + if code == "A" + stock_code: + if jangoDic[code]['매도가능'] > 0: + if golden: + if 7.0 < jangoDic[code]['평가손익']: + self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가']) + self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name)) + check = True + else: + if 1.0 < jangoDic[code]['평가손익']: + self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가']) + self.bot.sendMsg("Profit {:.2f}, {} ({})".format(jangoDic[code]['평가손익'], stock_code, stock_name)) + check = True + return check 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) + if len(today_stock) < 1: + return 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() + if len(today_stock) < 1: + return - 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 + buy_stock = [] + for idx, stock_code in enumerate(today_stock): 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) + self.getRealTime_DailyCheck(today, stock_code, stock) + data = self.stockStatus.analyze(stock, self.analyzed_day) - bs_buy_price = data["close"][len(data["close"]) - 1] + # 매수 + if data['avg60'] < data['avg20'] < data['avg5']: + bs_buy_price = 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) + buy_count = int(150000 / bs_buy_price) - # 다음 조건이면 매수한다. - if bs_buy_price > 1000: + # 매수를 주문한다. + 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) - if not self.orderChecker.exist(today, "A" + stock_code, hours=5): - buy_count = int(self.MAX_BUY_PRICE / bs_buy_price) + # bot에 메시지를 보냄 + self.bot.post(stock_code, '', "BUY", bs_buy_price, buy_count) - if buy_count > 0: + buy_stock.append( stock_code ) - # 매수를 주문한다. - 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) + # 로그 출력 + print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, '', bs_buy_price, buy_count) - # bot에 메시지를 보냄 - self.bot.post(stock_code, stock_name, "BUY", bs_buy_price, buy_count) + # 매도 + if not data['avg60'] < data['avg20'] < data['avg5']: + self.sellStocks(stock_code, True) + else: + self.sellStocks(stock_code, False) - # 로그 출력 - print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, stock_name, bs_buy_price, buy_count) + # 매수 후 제거 + for stock_code in buy_stock: + today_stock.remove(stock_code) time.sleep(3600) THIS_TIME = datetime.now() @@ -146,25 +141,20 @@ class HTS_Stocks (HTS): 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 + file_list = os.listdir(os.path.join(self.RESOURCE_PATH, 'analysis', '종목선택')) + for filename in file_list: + # '20240130_2_daily_최적_타이밍_후보__1162_넥스틸_092790.html' + #pattern = '([0-9]+)_[1-9]_daily_최적_타이밍_후보__[0-9]+_([ㄱ-ㅎ가-힣a-zA-Z0-9]+)_([0-9]+)\.html' + pattern = '([0-9]+)_[1-9]_daily_최적_타이밍_후보__[0-9]+_.*_([0-9]+)\.html' + info = re.search(pattern, filename) + if info is None: + continue + + date_str = datetime.strptime(info.group(1), "%Y%m%d").strftime("%Y%m%d") + if date_str == datetime.today().strftime("%Y%m%d") or date_str == (datetime.today() - timedelta(days=1)).strftime("%Y%m%d"): + today_stock.add(info.group(2)) + + return list(today_stock) if __name__ == "__main__": today = datetime.today()