diff --git a/HTS_stocks.py b/HTS_stocks.py index d054e0d..5441ef5 100644 --- a/HTS_stocks.py +++ b/HTS_stocks.py @@ -23,19 +23,39 @@ class HTS_Stocks (HTS): analyzed_day = None MAX_BUY_PRICE = None + conn = None + cursor = 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.orderChecker = OrderChecker(os.path.join(self.RESOURCE_PATH, )) self.analyzed_day = 120 self.MAX_BUY_PRICE = 100000 return + def connect2DB(self, dbfile_name): + try: + self.conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, dbfile_name)) + self.cursor = self.conn.cursor() + except: + return False + return True + + def disconnect(self): + try: + self.cursor.close() + self.conn.close() + except: + return False + return True + def getSellingPrice(self, log_time, stock_code, final_price, without_loss=False): # final_price와 diff를 받으면, 해당 가격으로 그냥 매도한다는 의미 # final_price와 diff가 None이면 장부가와 final 중 max로 팔겠다는 의미 @@ -68,30 +88,22 @@ class HTS_Stocks (HTS): def valid_company(self): valid_company = set() - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) - cursor = conn.cursor() - cursor.execute('select CODE, NAME, max(ymd) as ymd from fnguide where type != "E" group by 1 order by total_assets desc') - items = cursor.fetchall() - cursor.close() - conn.close() + self.cursor.execute('select CODE, NAME, max(ymd) as ymd from fnguide where type != "E" group by 1 order by total_assets desc') + items = self.cursor.fetchall() for item in items: valid_company.add(item[0]) return valid_company def buyRealTime(self, today, n = 200): + self.connect2DB("stock.db") print ("START...") THIS_TIME = datetime.now() valid_company = self.valid_company() - stockTableName = 'stock' - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, "stock.db")) - cursor = conn.cursor() - cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code') - items = cursor.fetchall() - cursor.close() - conn.close() + self.cursor.execute('SELECT distinct code, name FROM stock order by code') + items = self.cursor.fetchall() while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'): @@ -110,7 +122,7 @@ class HTS_Stocks (HTS): continue print(idx, stock_code, stock_name, ", CODE: ", stock_code, ", NAME: ", stock_name) - stock = self.stockStatus.getLastData(stock_code, n) + stock = self.stockStatus.fetchLastData(self.cursor, stock_code, n) try: self.getRealTime_DailyCheck(today, stock_code, stock) data = self.stockStatus.analyze(stock, self.analyzed_day) @@ -193,6 +205,7 @@ class HTS_Stocks (HTS): time.sleep(10) THIS_TIME = datetime.now() + self.disconnect() return def updteTodayStock(self, db_filename, stock_code, today_str): diff --git a/stock/analysis/StockStatus.py b/stock/analysis/StockStatus.py index 589324d..fbf7d5b 100644 --- a/stock/analysis/StockStatus.py +++ b/stock/analysis/StockStatus.py @@ -33,9 +33,9 @@ class StockStatus (HTS): return - def getDBData(self, stock_code, day, result): - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, self.dbFileName)) - cursor = conn.cursor() + def getDBData(self, cursor, stock_code, day, result): + if cursor is None: + return cursor.execute('SELECT ymd, close, open, high, low, envelope_upper, envelope_lower, envelope_middle, rsi, rsis, macd, macds, stochastic_slow_k, stochastic_slow_d FROM ' + self.tableName + ' WHERE CODE=? and ymd=? order by ymd', (stock_code, day,)) db_result = cursor.fetchall() @@ -72,9 +72,9 @@ class StockStatus (HTS): return - def isValidYMD(self, stock_code, day): - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, self.dbFileName)) - cursor = conn.cursor() + def isValidYMD(self, cursor, stock_code, day): + if cursor is None: + return cursor.execute('SELECT ymd, count(*) as cnt FROM ' + self.tableName + ' WHERE CODE=? and ymd=?', (stock_code, day,)) db_result = cursor.fetchone() @@ -82,11 +82,11 @@ class StockStatus (HTS): return True return False - def getLastData(self, stock_code, limit=350): - stockTableName = 'stock' + def fetchLastData(self, cursor, stock_code, limit=350): + if cursor is None: + return - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, self.dbFileName)) - cursor = conn.cursor() + stockTableName = 'stock' stock = {"CODE": stock_code, "NAME": "", "PRICE": []} @@ -147,10 +147,6 @@ class StockStatus (HTS): } ) - conn.commit() - cursor.close() - conn.close() - return stock def analyze (self, stock, days=120): @@ -564,78 +560,3 @@ class StockStatus (HTS): po.write_html(fig, file=fileName, auto_open=False) return - - def checkEnvelope(self, stock_codes:list=None, isRealTime=False): - if not isRealTime: - n = 200 - else: - n = 200 - - today = datetime.today().strftime('%Y%m%d') - - if stock_codes is not None: - for stock_code in stock_codes: - stock = self.getLastData(stock_code, n) - - self.getData(today, stock) - analyzed_day = 60 - data = self.analyze(stock, analyzed_day) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - data.drop(data.index[:len(data) - analyzed_day], inplace=True) - - # print logs - for i in range(len(data.index)): - print (i, data.index[i], data['macd'][i], data['slow_k'][i], data['gradients_low'][i], data['gradients_avg5'][i], data['gradients_avg20'][i], data['gradients_avg60'][i], data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity'][i], data['disparity_type'][i]) - - bsLine, data = self.buySellChecker.checkTransactionWithEnvelope(data, stock_code, isRealTime=False) - - # 그래프를 그린다. - self.draw(stock_code, today, data, bsLine) - else: - stockTableName = 'stock' - conn = sqlite3.connect(os.path.join(self.RESOURCE_PATH, self.dbFileName)) - cursor = conn.cursor() - cursor.execute('SELECT distinct code, name FROM ' + stockTableName + ' order by code') - items = cursor.fetchall() - cursor.close() - conn.close() - - if not os.path.exists(os.path.join(self.RESOURCE_PATH, 'analysis', today)): - os.mkdir(os.path.join(self.RESOURCE_PATH, 'analysis', today)) - - dailyDirName = os.path.join(self.RESOURCE_PATH, 'analysis', today, 'daily') - if os.path.exists(dailyDirName): - shutil.rmtree(dailyDirName) - os.mkdir(dailyDirName) - - analyzed_day = 120 - for idx, item in enumerate(items): - stock_code = item[0] - stock_name = item[1] - if stock_name.find('스팩') >= 0: - continue - print(idx, stock_code, stock_name, ", CODE: ", stock_code, ", NAME: ", stock_name) - - stock = self.getLastData(stock_code, n) - data = self.analyze(stock, analyzed_day) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - data.drop(data.index[:len(data) - analyzed_day], inplace=True) - - # print logs - # for i in range(len(data.index)): - # print (i, data.index[i], data['macd'][i], data['slow_k'][i], data['gradients_low'][i], data['gradients_avg5'][i], data['gradients_avg20'][i], data['gradients_avg60'][i], data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity'][i], data['disparity_type'][i]) - - bsLine, data = self.buySellChecker.checkTransactionWithEnvelope(data, stock_code, 120, isRealTime=False) - - # 그래프를 그린다. - if len(data.index) > 10 and bsLine['buy'][len(bsLine['buy'])-1] > 0: - self.writeFile(dailyDirName, stock_code, stock_name, today, data, bsLine) - - return - -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") - - dailyStatus = StockStatus(RESOURCE_PATH) - dailyStatus.checkEnvelope() \ No newline at end of file