Files
DeepStock/HTS_stocks.py
dsyoon ef764cd023 init
2024-02-01 12:55:44 +09:00

183 lines
6.8 KiB
Python

import re
import os
import time
import psutil
import sqlite3
from datetime import datetime, timedelta
from hts.HTS import HTS
from hts.OrderType import OrderType
from hts.BuySellChecker import BuySellChecker
from hts.OrderChecker import OrderChecker
from stock.util.TelegramBot import TelegramBot
from stock.analysis.StockStatus import StockStatus
class HTS_Stocks (HTS):
RESOURCE_PATH = None
orderChecker = None
buySellChecker = None
labelChecker = None
bot = 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.bot = TelegramBot()
self.RESOURCE_PATH = RESOURCE_PATH
self.stockStatus = StockStatus(RESOURCE_PATH)
self.buySellChecker = BuySellChecker(RESOURCE_PATH)
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, "stock.db"))
self.cursor_stock = self.conn_stock.cursor()
return
def disconnectStockDB(self):
self.cursor_stock.close()
self.conn_stock.close()
return
def sellStocks(self, stock_code=None):
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 3.0 < jangoDic[code]['평가손익']:
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
self.bot.sendMsg("Profit {} ({}): {:.2f} ({:.2f}%)".format(jangoDic[code]['종목명'], jangoDic[code]['종목코드'], (jangoDic[code]['현재가']-jangoDic[code]['장부가'])*jangoDic[code]['잔고수량'], jangoDic[code]['평가손익']))
check = True
else:
if 10.0 < jangoDic[code]['평가손익']:
self.requestOrder(OrderType.sell, code[1:], jangoDic[code]['매도가능'], jangoDic[code]['현재가'])
self.bot.sendMsg("Profit {} ({}): {:.2f} ({:.2f}%)".format(jangoDic[code]['종목명'], jangoDic[code]['종목코드'], (jangoDic[code]['현재가']-jangoDic[code]['장부가'])*jangoDic[code]['잔고수량'], jangoDic[code]['평가손익']))
check = True
return check
def buyRealTime(self, today, n = 200):
print ("START...")
THIS_TIME = datetime.now()
today_stock = self.get_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 + " 080000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
if len(today_stock) < 1:
self.sellStocks()
time.sleep(600)
continue
buy_stock = []
for idx, stock_code in enumerate(today_stock):
time.sleep(0.1)
stock = self.stockStatus.fetchLastData(self.cursor_stock, stock_code, n)
self.getRealTime_DailyCheck(today, stock_code, stock)
data = self.stockStatus.analyze(stock, self.analyzed_day)
# 매도
if not data['avg60'][-1] < data['avg20'][-1] < data['avg5'][-1]:
self.sellStocks(stock_code)
# 매수
bs_buy_price = data["close"][-1]
if 150000 < bs_buy_price:
buy_count = 1
else:
buy_count = 150000 // bs_buy_price
# 매수를 주문한다.
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)
# bot에 메시지를 보냄
self.bot.sendMsg('BUY {} {} ({})'.format(stock_code, bs_buy_price, buy_count))
buy_stock.append( stock_code )
# 로그 출력
print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, '', bs_buy_price, buy_count)
# 매수 후 제거
for stock_code in buy_stock:
today_stock.remove(stock_code)
if int(THIS_TIME.strftime("%M")) in (10, 40):
vm = psutil.virtual_memory()
vm_item = dict()
vm_item['free'] = vm.available // (1024 * 1024)
vm_item['idle'] = vm.available / vm.total * 100
hts.bot.sendMsg("Alive... close: {}, mem: {:.1f}".format(str(close_data), vm_item['idle']))
time.sleep(600)
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()
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_final_candidate__[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()
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...")