init
This commit is contained in:
58
HTS_etf.py
58
HTS_etf.py
@@ -37,15 +37,11 @@ class HTS_etf(HTS):
|
||||
ichimokuCloud = None
|
||||
|
||||
|
||||
def __init__(self, RESOURCE_PATH, stock_code, stock_name, SELL_GAP):
|
||||
def __init__(self, RESOURCE_PATH):
|
||||
super().__init__(RESOURCE_PATH)
|
||||
|
||||
self.RESOURCE_PATH = RESOURCE_PATH
|
||||
|
||||
self.SELL_GAP = SELL_GAP
|
||||
self.stock_code = stock_code
|
||||
self.stock_name = stock_name
|
||||
self.orderChecker = OrderChecker(self.RESOURCE_PATH, self.stock_code)
|
||||
self.bot = TelegramBot()
|
||||
self.stockStatus = StockStatus(RESOURCE_PATH)
|
||||
|
||||
@@ -55,7 +51,7 @@ class HTS_etf(HTS):
|
||||
self.macd = MACD()
|
||||
self.ichimokuCloud = IchimokuCloud()
|
||||
|
||||
self.buySellChecker = BuySellChecker(self.RESOURCE_PATH, self.stock_code)
|
||||
self.buySellChecker = BuySellChecker(self.RESOURCE_PATH)
|
||||
|
||||
return
|
||||
|
||||
@@ -412,25 +408,31 @@ class HTS_etf(HTS):
|
||||
|
||||
return result
|
||||
|
||||
def buyRealTime(self, today, MAX_PRICE=30000):
|
||||
def buyRealTime(self, stocks, today, MAX_PRICE=30000):
|
||||
self.orderChecker = OrderChecker(self.RESOURCE_PATH, stock_code)
|
||||
|
||||
BUY_LIST = {'buy_count': 0, 'buy_avg': 0, 'buy_list': []}
|
||||
|
||||
print("START...")
|
||||
THIS_TIME = datetime.now()
|
||||
|
||||
LAST_DATA = self.getLastData(self.stock_code, today)
|
||||
#LAST_DATA = self.getLastData(stock_code, today)
|
||||
|
||||
while datetime.strptime(today + " 060000", '%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 + " 090100", '%Y%m%d %H%M%S'):
|
||||
self.bot.sendMsg("START... {} ({}) SLOW_K: {}".format(self.stock_code, self.stock_name, MAX_PRICE))
|
||||
self.bot.sendMsg("START... {} ({}) SLOW_K: {}".format(stock_code, stock_name, MAX_PRICE))
|
||||
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
|
||||
|
||||
for stock in stocks:
|
||||
stock_code = stock['stock_code']
|
||||
stock_name = stock['stock_name']
|
||||
|
||||
# 매도를 체크한다.
|
||||
check = self.sellStocks(self.stock_code, self.stock_name)
|
||||
check = self.sellStocks(stock_code, stock_name)
|
||||
|
||||
# jangoDic[code]['장부가'], jangoDic[code]['평가금액'], jangoDic[code]['평가손익'],
|
||||
buy_avg, amount, profit = self.getBallance(self.stock_code)
|
||||
buy_avg, amount, profit = self.getBallance(stock_code)
|
||||
if check or buy_avg == 0:
|
||||
BUY_LIST['buy_avg'] = 0
|
||||
BUY_LIST['buy_count'] = 0
|
||||
@@ -438,61 +440,55 @@ class HTS_etf(HTS):
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
try:
|
||||
# 데이터를 가지고 온다.
|
||||
result_m1 = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
except:
|
||||
print("#ERROR:", self.stock_code)
|
||||
continue
|
||||
|
||||
#result_m1 = self.getRealTime(stock_code, today, LAST_DATA)
|
||||
result_m1 =self.getRealTime(stock_code, today)
|
||||
result_tic_m1 = self.makeTickData1(result_m1, mins=1)
|
||||
data = self.analyze(result_tic_m1)
|
||||
result_tic_m30 = self.makeTickData2(result_tic_m1, mins=30)
|
||||
data_signal = self.analyze(result_tic_m30)
|
||||
|
||||
#data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
||||
|
||||
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
||||
bsLine1 = self.buySellChecker.checkTransaction1(self.stock_code, MAX_PRICE, data, data_signal, BUY_LIST, isRealTime=True)
|
||||
bsLine1 = self.buySellChecker.checkTransaction1(stock_code, MAX_PRICE, data, data_signal, BUY_LIST, isRealTime=True)
|
||||
|
||||
if 'sell_price' in bsLine1:
|
||||
sell_price = bsLine1['sell_price'][-1]
|
||||
if 0 < sell_price:
|
||||
profit_rate = 1.002
|
||||
if buy_avg * profit_rate < data['close'][-1]:
|
||||
check = self.sellStocks(self.stock_code, sell_price)
|
||||
check = self.sellStocks(stock_code, sell_price)
|
||||
if check:
|
||||
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), self.stock_code)
|
||||
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), stock_code)
|
||||
BUY_LIST['buy_avg'] = 0
|
||||
BUY_LIST['buy_count'] = 0
|
||||
BUY_LIST['buy_list'].clear()
|
||||
self.bot.sendMsg( "Profit {:.2f}, {} ({})".format(profit, self.stock_code, self.stock_name))
|
||||
self.bot.sendMsg( "Profit {:.2f}, {} ({})".format(profit, stock_code, stock_name))
|
||||
|
||||
if 'buy_price' in bsLine1:
|
||||
buy_price = bsLine1['buy_price'][-1]
|
||||
buy_count = int(bsLine1['buy_count'][-1])
|
||||
if buy_price > 0:
|
||||
# 매수를 요청 한다.
|
||||
orderNum = self.requestOrder(OrderType.buy, self.stock_code, buy_count, buy_price)
|
||||
self.orderChecker.buy(today, "A" + self.stock_code, buy_count, buy_price, orderNum)
|
||||
orderNum = self.requestOrder(OrderType.buy, stock_code, buy_count, buy_price)
|
||||
self.orderChecker.buy(today, "A" + stock_code, buy_count, buy_price, orderNum)
|
||||
|
||||
self.orderChecker.buy(datetime.today().strftime('%Y%m%d'), stock_code, buy_count, buy_price)
|
||||
self.bot.post(stock_code, stock_name, "[BUY] ", buy_price, buy_count, data['rsi'][-1], -1)
|
||||
|
||||
self.orderChecker.buy(datetime.today().strftime('%Y%m%d'), self.stock_code, buy_count, buy_price)
|
||||
self.bot.post(self.stock_code, self.stock_name, "[BUY] ", buy_price, buy_count, data['rsi'][-1], -1)
|
||||
|
||||
# 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다.
|
||||
ORDER_LIST = self.requestOrderList()
|
||||
orderListToCancel = self.orderChecker.cancel(today, "A" + self.stock_code, ORDER_LIST, mins=3)
|
||||
orderListToCancel = self.orderChecker.cancel(today, "A" + stock_code, ORDER_LIST, mins=3)
|
||||
if len(orderListToCancel) > 0:
|
||||
self.cancelOrderList(orderListToCancel)
|
||||
|
||||
|
||||
if (int(THIS_TIME.strftime("%M")) % 50 == 0 or int(THIS_TIME.strftime("%M")) % 20 == 0):
|
||||
#self.bot.alarm_live(self.stock_code, self.stock_name)
|
||||
#self.bot.alarm_live(stock_code, stock_name)
|
||||
vm = psutil.virtual_memory()
|
||||
vm_item = dict()
|
||||
vm_item['free'] = vm.available // (1024 * 1024)
|
||||
vm_item['idle'] = vm.available / vm.total * 100
|
||||
self.bot.sendMsg("Alive... {} ({}) avg: {:.2f}, close: {:.2f}, mem: {:.1f}".format(self.stock_code, self.stock_name, buy_avg, data['close'][-1], vm_item['idle']))
|
||||
self.bot.sendMsg("Alive... {} ({}) avg: {:.2f}, close: {:.2f}, mem: {:.1f}".format(stock_code, stock_name, buy_avg, data['close'][-1], vm_item['idle']))
|
||||
|
||||
time.sleep(60)
|
||||
THIS_TIME = datetime.now()
|
||||
|
||||
34
HTS_etf_all.py
Normal file
34
HTS_etf_all.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import os
|
||||
from datetime import datetime
|
||||
from HTS_etf import HTS_etf
|
||||
|
||||
if __name__ == "__main__":
|
||||
today = datetime.today()
|
||||
|
||||
PROJECT_HOME = os.getcwd()
|
||||
RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources")
|
||||
|
||||
stocks = [
|
||||
{'stock_code': '122630', 'stock_name': 'KODEX 레버리지'},
|
||||
{'stock_code': '233740', 'stock_name': 'KODEX 코스닥150레버리지'},
|
||||
{'stock_code': '251340', 'stock_name': 'KODEX 코스닥150선물인버스'},
|
||||
{'stock_code': '252670', 'stock_name': 'KODEX 200선물인버스2X'}
|
||||
]
|
||||
|
||||
hts = HTS_etf(RESOURCE_PATH)
|
||||
hts.connect2DB("hts.db")
|
||||
|
||||
today_str = today.strftime('%Y%m%d')
|
||||
|
||||
if not os.path.exists(os.path.join(RESOURCE_PATH, "log")):
|
||||
os.mkdir(os.path.join(RESOURCE_PATH, "log"))
|
||||
|
||||
MAX_PRICE = 500000
|
||||
hts.buyRealTime(stocks, today_str, MAX_PRICE=MAX_PRICE)
|
||||
|
||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||
hts.insertStockData(today, stock_code, stock_name)
|
||||
|
||||
hts.disconnect()
|
||||
hts.bot.sendMsg("done... {} ({})".format(stock_code, stock_name))
|
||||
print("done...")
|
||||
@@ -10,7 +10,7 @@ class BuySellChecker():
|
||||
PATTERNS = None
|
||||
RESOURCE_PATH = None
|
||||
|
||||
def __init__(self, RESOURCE_PATH, s):
|
||||
def __init__(self, RESOURCE_PATH):
|
||||
self.RESOURCE_PATH = RESOURCE_PATH
|
||||
return
|
||||
|
||||
@@ -98,58 +98,10 @@ class BuySellChecker():
|
||||
df_signal = data_signal.loc[df_tmp]
|
||||
si = len(df_signal) - 1
|
||||
|
||||
"""
|
||||
if isRealTime:
|
||||
macds = data['macd'][i-300:i].to_list()
|
||||
if 0 < len(macds):
|
||||
macds_max = max(macds)
|
||||
mi = i-300 + macds.index(macds_max)
|
||||
|
||||
if data['macd'][i] < macds_max and data['close'][mi] < data['close'][i]:
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
else:
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
else:
|
||||
macds = self.getMacd(ticker['ticker_code'], data['ymd'][i].strftime('%Y%m%d'), mins=1)
|
||||
if len(macds) == 0:
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
|
||||
macds_sort = sorted(macds, key=lambda x:x[0], reverse=True)
|
||||
if data['macd'][i] < macds_sort[0][1] and macds_sort[0][2] < data['close'][i]:
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
"""
|
||||
|
||||
duration = 3
|
||||
if sum(data['trend_avg'][i - duration:i]) / duration < data['trend_avg'][i]:
|
||||
# 상승 트렌드
|
||||
if data_signal['avg20'][si] < data_signal['avg5'][si]:
|
||||
"""
|
||||
# 방법 1:
|
||||
if max(data['volume_up'][i-180:i]) < data['volume_up'][i]:
|
||||
if data_signal['slow_k'][si] < 70:
|
||||
if BUY_LIST is not None and 0 < len(BUY_LIST['buy_list']) and BUY_LIST['buy_list'][-1]['buy_price'] < data['close'][i]:
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'volume_up'
|
||||
buy_ymd = data['ymd'][i]
|
||||
if data['slow_k'][si] < 30:
|
||||
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||
elif data['slow_k'][si] < 50:
|
||||
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
else:
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'volume_up'
|
||||
buy_ymd = data['ymd'][i]
|
||||
if data['slow_k'][si] < 30:
|
||||
buy_count = MAX_BUY_PRICE / (1 * data['close'][i])
|
||||
elif data['slow_k'][si] < 50:
|
||||
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE / (3 * data['close'][i])
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
"""
|
||||
|
||||
# 방법 2:
|
||||
if data['avg480'][i] < data['avg120'][i] < data['avg60'][i] < data['avg20'][i] < data['avg5'][i] < data['close'][i]:
|
||||
|
||||
29
hts/HTS.py
29
hts/HTS.py
@@ -647,25 +647,20 @@ class HTS:
|
||||
return result
|
||||
|
||||
# 주식 현재가 조회
|
||||
def getRealTime(self, stock_code, today, LAST_DATA=None):
|
||||
if LAST_DATA is not None:
|
||||
#result = copy.deepcopy(LAST_DATA)
|
||||
|
||||
result = {"check": set(), "ymd": [], "open": [], "close": [], "high": [], "low": [], "volume": [], "label": []}
|
||||
for i in range(len(LAST_DATA['ymd'])):
|
||||
result["ymd"].append(LAST_DATA['ymd'][i])
|
||||
result["open"].append(LAST_DATA['open'][i])
|
||||
result["close"].append(LAST_DATA['close'][i])
|
||||
result["high"].append(LAST_DATA['high'][i])
|
||||
result["low"].append(LAST_DATA['low'][i])
|
||||
result["volume"].append(LAST_DATA['volume'][i])
|
||||
result["label"].append(LAST_DATA['label'][i])
|
||||
else:
|
||||
def getRealTime(self, stock_code, today, LAST_DATA=None, n=7):
|
||||
result = {"check": set(), "ymd": [], "open": [], "close": [], "high": [], "low": [], "volume": [], "label": []}
|
||||
|
||||
#### real time에서 아직 저장된 것이 없기 때문에 result는 아무것도 채워지지 않는다.
|
||||
self.getDBData(stock_code, today, result)
|
||||
|
||||
days = []
|
||||
for i in range(1, 100):
|
||||
last_day = (datetime.strptime(today, '%Y%m%d') - timedelta(i)).strftime('%Y%m%d')
|
||||
isValid = self.isValidYMD(stock_code=stock_code, day=last_day)
|
||||
if isValid:
|
||||
days.append(last_day)
|
||||
if len(days) >= n:
|
||||
break
|
||||
days = sorted(days)
|
||||
for day in days:
|
||||
self.getDBData(stock_code, day, result)
|
||||
|
||||
int_given_day = int(today)
|
||||
objCpCybos = win32com.client.Dispatch("CpUtil.CpCybos")
|
||||
|
||||
Reference in New Issue
Block a user