init
This commit is contained in:
@@ -83,6 +83,7 @@ if __name__ == "__main__":
|
||||
while True:
|
||||
print("insert...", stock["stock_code"], stock["stock_name"], this_day.strftime('%Y%m%d'))
|
||||
hts.insertStockData(this_day, stock["stock_code"], stock["stock_name"])
|
||||
hts.updateDisparity(stock["stock_code"])
|
||||
this_day = this_day + timedelta(days=1)
|
||||
if this_day > stock["end_date"]:
|
||||
break
|
||||
|
||||
175
HTS_etf.py
175
HTS_etf.py
@@ -1,6 +1,7 @@
|
||||
import os
|
||||
import time
|
||||
import pandas as pd
|
||||
import psutil
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
|
||||
from hts.HTS import HTS
|
||||
@@ -389,100 +390,104 @@ class HTS_etf(HTS):
|
||||
|
||||
return result
|
||||
|
||||
def buyRealTime(self, today, MAX_PRICE=30000):
|
||||
BUY_LIST = {'buy_count': 0, 'buy_avg': 0, 'buy_list': []}
|
||||
def getDisparityLimit(self, ticker, RESOURCE_PATH):
|
||||
conn = sqlite3.connect(os.path.join(RESOURCE_PATH, 'coins.db'))
|
||||
cursor = conn.cursor()
|
||||
|
||||
print("START...")
|
||||
THIS_TIME = datetime.now()
|
||||
cursor.execute('SELECT disparity_avg5, disparity_avg20, disparity_avg60, disparity_avg120, disparity_avg240, disparity_avg480, disparity_avg1500 FROM minutely WHERE (CODE=? or CODE=?) order by ymd, hms', (ticker['stock_code'], ticker['stock_code'].replace('KRW-', ''),))
|
||||
|
||||
LAST_DATA = self.getLastData(self.stock_code, today)
|
||||
disparity = {
|
||||
'avg': {},
|
||||
"limit_top_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None},
|
||||
"limit_bottom_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None},
|
||||
"limit_top_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None},
|
||||
"limit_bottom_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}
|
||||
}
|
||||
avg = {"avg5": [], "avg20": [], "avg60": [], "avg120": [], "avg240": [], "avg480": [], "avg1500": []}
|
||||
db_result = cursor.fetchall()
|
||||
for rows in db_result:
|
||||
avg["avg5"].append(float(rows[0]))
|
||||
avg["avg20"].append(float(rows[1]))
|
||||
avg["avg60"].append(float(rows[2]))
|
||||
avg["avg120"].append(float(rows[3]))
|
||||
avg["avg240"].append(float(rows[4]))
|
||||
avg["avg480"].append(float(rows[5]))
|
||||
avg["avg1500"].append(float(rows[6]))
|
||||
|
||||
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))
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
|
||||
disparity['avg'] = avg
|
||||
disparity_1500 = sorted(list(set(avg['avg1500'])), reverse=True)
|
||||
disparity_480 = sorted(list(set(avg['avg480'])), reverse=True)
|
||||
disparity_240 = sorted(list(set(avg['avg240'])), reverse=True)
|
||||
disparity_120 = sorted(list(set(avg['avg120'])), reverse=True)
|
||||
disparity_60 = sorted(list(set(avg['avg60'])), reverse=True)
|
||||
disparity_20 = sorted(list(set(avg['avg20'])), reverse=True)
|
||||
disparity_5 = sorted(list(set(avg['avg5'])), reverse=True)
|
||||
|
||||
# 매도를 체크한다.
|
||||
check = self.sellStocks(self.stock_code, self.stock_name)
|
||||
poses = [1, 3]
|
||||
for pos in poses:
|
||||
disparity['limit_top_'+str(pos)]['avg1500'] = disparity_1500[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg1500'] = disparity_1500[len(disparity_1500)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg480'] = disparity_480[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg480'] = disparity_480[len(disparity_480)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg240'] = disparity_240[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg240'] = disparity_240[len(disparity_240)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg120'] = disparity_120[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg120'] = disparity_120[len(disparity_120)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg60'] = disparity_60[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg60'] = disparity_60[len(disparity_60)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg20'] = disparity_20[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg20'] = disparity_20[len(disparity_20)-pos]
|
||||
disparity['limit_top_'+str(pos)]['avg5'] = disparity_5[pos]
|
||||
disparity['limit_bottom_'+str(pos)]['avg5'] = disparity_5[len(disparity_5)-pos]
|
||||
|
||||
# jangoDic[code]['장부가'], jangoDic[code]['평가금액'], jangoDic[code]['평가손익'],
|
||||
buy_avg, amount, profit = self.getBallance(self.stock_code)
|
||||
if check or buy_avg == 0:
|
||||
return disparity
|
||||
|
||||
def buyRealTime(self, stock, data, data_signal, MAX_BUY_PRICE, BUY_LIST):
|
||||
|
||||
# 매도를 체크한다.
|
||||
check = self.sellStocks(stock_code=self.stock_code)
|
||||
|
||||
# jangoDic[code]['장부가'], jangoDic[code]['평가금액'], jangoDic[code]['평가손익'],
|
||||
buy_avg, amount, profit = self.getBallance(self.stock_code)
|
||||
if check or buy_avg == 0:
|
||||
BUY_LIST['buy_avg'] = 0
|
||||
BUY_LIST['buy_count'] = 0
|
||||
BUY_LIST['buy_list'].clear()
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
# 사야 할 시점과 팔아야 할 시점을 체크한다.
|
||||
bsLine1 = self.buySellChecker.checkTransaction1(self.stock_code, MAX_BUY_PRICE, data, data_signal, BUY_LIST, isRealTime=True)
|
||||
|
||||
if 'sell_price' in bsLine1:
|
||||
sell_price = bsLine1['sell_price'][-1]
|
||||
sell_count = bsLine1['sell_count'][-1]
|
||||
sell_type = bsLine1['sell_type'][-1]
|
||||
if 0 < sell_price:
|
||||
check = self.sellStocks(stock_code=self.stock_code, bs_sell_price=sell_price)
|
||||
if check:
|
||||
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), self.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))
|
||||
|
||||
time.sleep(0.1)
|
||||
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(datetime.today().strftime('%Y%m%d'), "A" + self.stock_code, buy_count, buy_price, orderNum)
|
||||
self.bot.post(self.stock_code, self.stock_name, "[BUY] ", buy_price, buy_count, data['rsi'][-1], -1)
|
||||
|
||||
try:
|
||||
# 데이터를 가지고 온다.
|
||||
result_m1 = self.getRealTime(self.stock_code, today, LAST_DATA)
|
||||
except:
|
||||
print("#ERROR:", self.stock_code)
|
||||
continue
|
||||
|
||||
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)
|
||||
|
||||
if 'sell_price' in bsLine1:
|
||||
sell_price = bsLine1['sell_price'][-1]
|
||||
sell_count = bsLine1['sell_count'][-1]
|
||||
sell_type = bsLine1['sell_type'][-1]
|
||||
if 0 < sell_price:
|
||||
profit_rate = 1.002
|
||||
if buy_avg * profit_rate < data['close'][-1]:
|
||||
if sell_type == 'slow_k' and 0 < sell_count:
|
||||
check = self.sellStocks(self.stock_code, sell_price, sell_count)
|
||||
if check:
|
||||
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), self.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))
|
||||
else:
|
||||
check = self.sellStocks(self.stock_code, sell_price)
|
||||
if check:
|
||||
self.orderChecker.sell(datetime.today().strftime('%Y%m%d'), self.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))
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
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)
|
||||
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']))
|
||||
|
||||
time.sleep(60)
|
||||
THIS_TIME = datetime.now()
|
||||
# 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다.
|
||||
ORDER_LIST = self.requestOrderList()
|
||||
orderListToCancel = self.orderChecker.cancel(datetime.today().strftime('%Y%m%d'), "A" + self.stock_code, ORDER_LIST, mins=3)
|
||||
if len(orderListToCancel) > 0:
|
||||
self.cancelOrderList(orderListToCancel)
|
||||
|
||||
return True
|
||||
@@ -1,9 +1,11 @@
|
||||
import os
|
||||
import json
|
||||
import time
|
||||
import psutil
|
||||
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")
|
||||
@@ -18,13 +20,43 @@ if __name__ == "__main__":
|
||||
hts = HTS_etf(RESOURCE_PATH)
|
||||
hts.connect2DB("hts.db")
|
||||
|
||||
today_str = today.strftime('%Y%m%d')
|
||||
today = datetime.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 = 100000
|
||||
hts.buyRealTime(stocks, today_str, MAX_PRICE=MAX_PRICE)
|
||||
print("START...")
|
||||
while datetime.strptime(today + " 060000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'):
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'):
|
||||
THIS_TIME = datetime.now()
|
||||
for stock in stocks:
|
||||
with open("config.json", "r", encoding="utf-8") as f:
|
||||
config = json.load(f)
|
||||
MAX_BUY_PRICE = config['MAX_BUY_PRICE']
|
||||
BUY_LIST_1 = config['BUY_LIST_1']
|
||||
BUY_LIST_1["disparity"] = hts.getDisparityLimit(stock, RESOURCE_PATH)
|
||||
if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < datetime.now() < datetime.strptime(today + " 090100", '%Y%m%d %H%M%S'):
|
||||
hts.bot.sendMsg("START... {} ({}) SLOW_K: {}".format(stock['stock_code'], stock['stock_name'], MAX_BUY_PRICE))
|
||||
|
||||
LAST_DATA = hts.getLastData(stock['stock_code'], today)
|
||||
result_m1 = hts.getRealTime(stock['stock_code'], today, LAST_DATA)
|
||||
result_tic_m1 = hts.makeTickData1(result_m1, mins=1)
|
||||
data = hts.analyze(result_tic_m1)
|
||||
result_tic_m30 = hts.makeTickData2(result_tic_m1, mins=30)
|
||||
data_signal = hts.analyze(result_tic_m30)
|
||||
# data.drop(data.index[:len(data) - analyzed_day], inplace=True)
|
||||
|
||||
hts.buyRealTime(stock, data, data_signal, MAX_BUY_PRICE, BUY_LIST_1)
|
||||
|
||||
if (int(THIS_TIME.strftime("%M")) % 50 == 0 or int(THIS_TIME.strftime("%M")) % 20 == 0):
|
||||
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... mem: {:.1f}".format(vm_item['idle']))
|
||||
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
db_filename = os.path.join(RESOURCE_PATH, "hts.db")
|
||||
for stock in stocks:
|
||||
|
||||
@@ -120,105 +120,104 @@ class BuySellChecker():
|
||||
df_signal = data_signal.loc[df_tmp]
|
||||
si = len(df_signal) - 1
|
||||
|
||||
"""
|
||||
duration = 5
|
||||
if duration < i:
|
||||
if sum(data['avg20'][i - duration:i])/len(data['avg20'][i - duration:i]) < data['avg20'][i]:
|
||||
min_value1 = min(data['close'][i - 1], data['close'][i - 1])
|
||||
min_value2 = min(data['close'][i - 2], data['close'][i - 2])
|
||||
min_value3 = min(data['close'][i - 3], data['close'][i - 3])
|
||||
min_sum = min_value1 + min_value2 + min_value3
|
||||
if min_sum / 3 < data['close'][i] and data['close'][i] == data['high'][i]:
|
||||
if data['avg60'][i] < data['avg20'][i] and data['avg5'][i-1] < data['avg5'][i]:
|
||||
if data['middle'][i-1] < data['middle'][i]:
|
||||
if 0 < len(BUY_LIST['buy_list']):
|
||||
if BUY_LIST['buy_list'][-1]['buy_price'] < data['close'][i]:
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'avg20_close_up'
|
||||
buy_ymd = data['ymd'][i]
|
||||
buy_cut = -1
|
||||
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 / (1.5 * data['close'][i])
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
else:
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'avg20_close_up'
|
||||
buy_ymd = data['ymd'][i]
|
||||
buy_cut = -1
|
||||
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 / (1.5 * data['close'][i])
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE / (2 * data['close'][i])
|
||||
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
"""
|
||||
|
||||
duration = 5
|
||||
check = False
|
||||
duration = 5 + 60
|
||||
if duration < i:
|
||||
if np.average(data['trend_avg'][i - duration:i]) < data['trend_avg'][i]:
|
||||
if self.is_Support(data, i-10, observation_time = 300):
|
||||
if data['open'][i] < data['close'][i]:
|
||||
if np.max(data['high'][i-2:i]) < data['close'][i]:
|
||||
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'support_300'
|
||||
buy_ymd = data['ymd'][i]
|
||||
buy_cut = data['close'][i] * 0.995
|
||||
BUY_LIST['buy_limit'] = 0
|
||||
if data['slow_k'][si] < 30:
|
||||
buy_count = MAX_BUY_PRICE*5 / (data['close'][i])
|
||||
elif data['slow_k'][si] < 50:
|
||||
buy_count = MAX_BUY_PRICE*4 / (data['close'][i])
|
||||
if np.average(data['avg480'][i - duration:i]) < data['avg480'][i]:
|
||||
if data['avg480'][i] < data['trend_avg'][i]:
|
||||
if data['avg20'][i] < data['avg480'][i] and data['avg20'][i - 1] < data['avg20'][i]:
|
||||
if len(BUY_LIST['buy_list']) == 0:
|
||||
check = True
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE*3 / (data['close'][i])
|
||||
if BUY_LIST['buy_list'][-1]['buy_price'] < data['close'][i]:
|
||||
check = True
|
||||
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
if 2800 < len(data['close'][i - 2880:i]) and np.max(data['close'][i - 2880:i]) < data['close'][i]:
|
||||
if np.max(data['rsi'][i - 30:i]) < data['rsi'][i]:
|
||||
if data['disparity_avg1500'][i] < 1.1:
|
||||
if data['close'][i] < data['trend_avg'][i]:
|
||||
buy_type = 'upward'
|
||||
check = True
|
||||
|
||||
if data['slow_k'][i] < 15:
|
||||
if data['slow_k'][i-1] < data['slow_d'][i-1] and data['slow_d'][i] < data['slow_k'][i]:
|
||||
buy_price = data['close'][i]
|
||||
buy_type = 'slow_k'
|
||||
buy_ymd = data['ymd'][i]
|
||||
buy_cut = data['close'][i] * 0.995
|
||||
BUY_LIST['buy_limit'] = 0
|
||||
buy_count = MAX_BUY_PRICE * 2 / (data['close'][i])
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
if data['disparity_avg20'][i] < BUY_LIST['disparity']['limit_bottom_3']['avg20']:
|
||||
buy_type = 'disparity_avg20'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg60'][i] < BUY_LIST['disparity']['limit_bottom_3']['avg60']:
|
||||
buy_type = 'disparity_avg60'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg480'][i] < BUY_LIST['disparity']['limit_bottom_3']['avg480']:
|
||||
buy_type = 'disparity_avg1500'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg1500'][i] < BUY_LIST['disparity']['limit_bottom_3']['avg1500']:
|
||||
buy_type = 'disparity_avg1500'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg20'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg20']:
|
||||
buy_type = 'disparity_avg20'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg60'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg60']:
|
||||
buy_type = 'disparity_avg60'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg480'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg480']:
|
||||
buy_type = 'disparity_avg1500'
|
||||
check = True
|
||||
|
||||
if data['disparity_avg1500'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg1500']:
|
||||
buy_type = 'disparity_avg1500'
|
||||
check = True
|
||||
|
||||
if check:
|
||||
buy_price = data['close'][i]
|
||||
buy_ymd = data['ymd'][i]
|
||||
if data['slow_k'][si] < 30:
|
||||
buy_count = MAX_BUY_PRICE * 2 / (data['close'][i])
|
||||
elif data['slow_k'][si] < 50:
|
||||
buy_count = MAX_BUY_PRICE * 1.5 / (data['close'][i])
|
||||
else:
|
||||
buy_count = MAX_BUY_PRICE * 1 / (data['close'][i])
|
||||
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
|
||||
return buy_ymd, buy_price, buy_count, buy_cut, buy_type
|
||||
|
||||
def getSellPriceAndWeight1(self, ticker, i, data, data_signal, BUY_LIST=None):
|
||||
sell_price, sell_count, sell_type = -1, -1, ''
|
||||
|
||||
df_tmp = data_signal['ymd'] <= data['ymd'][i]
|
||||
df_signal = data_signal.loc[df_tmp]
|
||||
si = len(df_signal) - 1
|
||||
|
||||
check = False
|
||||
if 0 < len(BUY_LIST['buy_list']):
|
||||
duration = 5
|
||||
if duration < i:
|
||||
if data['trend_avg'][i] < np.average(data['trend_avg'][i - duration:i]):
|
||||
if self.is_Resistance(data, i - 10, observation_time=300):
|
||||
sell_price = data['close'][i]
|
||||
sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list']])
|
||||
|
||||
if 75 < np.max(data_signal['rsi'][si-5:si]):
|
||||
if self.is_Resistance(data, i - 10, observation_time=300):
|
||||
sell_price = data['close'][i]
|
||||
sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list']])
|
||||
"""
|
||||
if 1.05 < data['disparity_avg20'][i]:
|
||||
check = True
|
||||
|
||||
if 1.10 < data['disparity_avg480'][i]:
|
||||
check = True
|
||||
|
||||
if 70 < data['slow_k'][i]:
|
||||
if data['slow_d'][i-1] < data['slow_k'][i-1] and data['slow_k'][i] <= data['slow_d'][i]:
|
||||
sell_price = data['close'][i]
|
||||
sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'slow_k'])
|
||||
sell_type = 'slow_k'
|
||||
if 1.15 < data['disparity_avg1500'][i]:
|
||||
check = True
|
||||
"""
|
||||
|
||||
if BUY_LIST['disparity']['limit_top_1']['avg20'] < data['disparity_avg20'][i]:
|
||||
check = True
|
||||
|
||||
if BUY_LIST['disparity']['limit_top_1']['avg480'] < data['disparity_avg480'][i]:
|
||||
check = True
|
||||
|
||||
if BUY_LIST['disparity']['limit_top_1']['avg1500'] < data['disparity_avg1500'][i]:
|
||||
check = True
|
||||
|
||||
if data['avg1500'][i - 1] < data['trend_avg'][i - 1] and data['trend_avg'][i] <= data['avg1500'][i]:
|
||||
check = True
|
||||
|
||||
if check:
|
||||
sell_price = data['close'][i]
|
||||
sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list']])
|
||||
|
||||
return sell_price, sell_count, sell_type
|
||||
|
||||
@@ -268,7 +267,7 @@ class BuySellChecker():
|
||||
sell_price, sell_count, sell_type = self.getSellPriceAndWeight1(ticker, last_index, data, data_signal, BUY_LIST)
|
||||
bsLine['sell_price'][last_index] = sell_price
|
||||
bsLine['sell_count'][last_index] = sell_count
|
||||
bsLine['sell_type'] = [sell_type]
|
||||
bsLine['sell_type'][last_index] = sell_type
|
||||
|
||||
if 0 < sell_price:
|
||||
BUY_LIST['buy_limit'] = 0
|
||||
|
||||
107
hts/HTS.py
107
hts/HTS.py
@@ -9,6 +9,7 @@ import sqlite3
|
||||
from datetime import datetime, timedelta
|
||||
from hts.OrderItem import OrderItem
|
||||
from stock.util.TelegramBot import TelegramBot
|
||||
from stock.analysis.MovingAverage import MovingAverage
|
||||
|
||||
class HTS:
|
||||
|
||||
@@ -474,7 +475,7 @@ class HTS:
|
||||
def insertStockData(self, this_day, stock_code, stock_name=''):
|
||||
|
||||
# 테이블 생성
|
||||
self.cursor.execute("CREATE TABLE IF NOT EXISTS hts (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, label INTEGER DEFAULT 0)")
|
||||
self.cursor.execute("CREATE TABLE IF NOT EXISTS hts (CODE text, NAME text, ymd text, hms text, close REAL, open REAL, high REAL, low REAL, volume REAL, disparity_avg5 REAL, disparity_avg20 REAL, disparity_avg60 REAL, disparity_avg120 REAL, disparity_avg240 REAL, disparity_avg480 REAL, disparity_avg1500 REAL)")
|
||||
|
||||
# 키 생성
|
||||
create_key = "CREATE INDEX IF NOT EXISTS hts_idx on hts(CODE, ymd, hms) "
|
||||
@@ -497,6 +498,49 @@ class HTS:
|
||||
self.conn.commit()
|
||||
return
|
||||
|
||||
def getQ(self):
|
||||
q_5 = MovingAverage(5)
|
||||
q_20 = MovingAverage(20)
|
||||
q_60 = MovingAverage(60)
|
||||
q_120 = MovingAverage(120)
|
||||
q_240 = MovingAverage(240)
|
||||
q_480 = MovingAverage(480)
|
||||
q_1500 = MovingAverage(1500)
|
||||
q = {'q_5': q_5, 'q_20': q_20, 'q_60': q_60, 'q_120': q_120, 'q_240': q_240, 'q_480': q_480, 'q_1500': q_1500}
|
||||
|
||||
return q
|
||||
|
||||
def updateDisparity(self, ticker_code):
|
||||
|
||||
self.cursor.execute('SELECT ymd, hms, close FROM hts WHERE CODE=? order by ymd, hms', (ticker_code,))
|
||||
|
||||
q = self.getQ()
|
||||
db_result = self.cursor.fetchall()
|
||||
for rows in db_result:
|
||||
ymd = rows[0]
|
||||
hms = rows[1]
|
||||
close = rows[2]
|
||||
|
||||
q['q_5'].enqueue(close)
|
||||
q['q_20'].enqueue(close)
|
||||
q['q_60'].enqueue(close)
|
||||
q['q_120'].enqueue(close)
|
||||
q['q_240'].enqueue(close)
|
||||
q['q_480'].enqueue(close)
|
||||
q['q_1500'].enqueue(close)
|
||||
|
||||
disparity_avg5 = close / q['q_5'].avg()
|
||||
disparity_avg20 = close / q['q_20'].avg()
|
||||
disparity_avg60 = close / q['q_60'].avg()
|
||||
disparity_avg120 = close / q['q_120'].avg()
|
||||
disparity_avg240 = close / q['q_240'].avg()
|
||||
disparity_avg480 = close / q['q_480'].avg()
|
||||
disparity_avg1500 = close / q['q_1500'].avg()
|
||||
|
||||
self.cursor.execute( "update hts set disparity_avg5=?, disparity_avg20=?, disparity_avg60=?, disparity_avg120=?, disparity_avg240=?, disparity_avg480=?, disparity_avg1500=? where CODE=? and ymd=? and hms=?", (disparity_avg5, disparity_avg20, disparity_avg60, disparity_avg120, disparity_avg240, disparity_avg480, disparity_avg1500, ticker_code, ymd, hms, ))
|
||||
self.conn.commit()
|
||||
|
||||
return
|
||||
|
||||
def write(self, day, result):
|
||||
#날짜,시간,시가,고가,저가,종가,거래량
|
||||
@@ -516,67 +560,6 @@ class HTS:
|
||||
outFp.close()
|
||||
return
|
||||
|
||||
def getCSV(self, fileName, result):
|
||||
with open(fileName, 'r', encoding='utf-8') as infp:
|
||||
reader = csv.reader(infp)
|
||||
next(reader)
|
||||
|
||||
for rows in reader:
|
||||
days = rows[0] # hts.날짜
|
||||
ymd = rows[1] # hts.시간
|
||||
open_v = rows[2] # hts.시가
|
||||
high = rows[3] # hts.고가
|
||||
low = rows[4] # hts.저가
|
||||
close = rows[5] # hts.종가
|
||||
vol = rows[6] # hts.거래량
|
||||
|
||||
temp = datetime.strptime(str(days) + " " + str(ymd).zfill(4) + "00", '%Y%m%d %H%M%S')
|
||||
#if temp < start_time:
|
||||
# continue
|
||||
|
||||
result["ymd"].append(temp)
|
||||
result["open"].append(int(open_v))
|
||||
result["close"].append(int(close))
|
||||
result["high"].append(int(high))
|
||||
result["low"].append(int(low))
|
||||
result["volume"].append(int(volume))
|
||||
return
|
||||
|
||||
def updateLabel(self, stock_code, bsLine, data, ymd):
|
||||
|
||||
self.cursor.execute('Update hts set label=? WHERE CODE=? and ymd=?', (0, stock_code, ymd,))
|
||||
|
||||
for i in range(len(bsLine["buy"])):
|
||||
if bsLine["buy"][i] > 0:
|
||||
ymd = data['date'][i].strftime('%Y%m%d')
|
||||
hms = data['date'][i].strftime('%H%M')
|
||||
self.cursor.execute('Update hts set label=? WHERE CODE=? and ymd=? and hms=?', (2, stock_code, ymd, hms))
|
||||
|
||||
for i in range(len(bsLine["sell"])):
|
||||
if bsLine["sell"][i] > 0:
|
||||
ymd = data['date'][i].strftime('%Y%m%d')
|
||||
hms = data['date'][i].strftime('%H%M')
|
||||
self.cursor.execute('Update hts set label=? WHERE CODE=? and ymd=? and hms=?', (1, stock_code, ymd, hms))
|
||||
self.conn.commit()
|
||||
|
||||
print("update...", stock_code, ymd)
|
||||
return
|
||||
|
||||
def clearLabel(self, stock_code, ymd):
|
||||
|
||||
self.cursor.execute('update hts set label=? WHERE CODE=? and ymd=? ', (0, stock_code, ymd,))
|
||||
self.conn.commit()
|
||||
print("update...", stock_code, ymd)
|
||||
return
|
||||
|
||||
def makeLabel(self, stock_code, ymd, hms, label):
|
||||
|
||||
self.cursor.execute('Update hts set label=? WHERE CODE=? and ymd=? and hms=?', (label, stock_code, ymd, hms,))
|
||||
self.conn.commit()
|
||||
|
||||
print("update...", stock_code, ymd, hms, label)
|
||||
return
|
||||
|
||||
def getYMD(self, stock_code):
|
||||
|
||||
result = []
|
||||
|
||||
Reference in New Issue
Block a user