diff --git a/hts/HTS.py b/hts/HTS.py index fbaeb9f..32cb86c 100644 --- a/hts/HTS.py +++ b/hts/HTS.py @@ -1,10 +1,10 @@ -import win32com.client +#import win32com.client import time import os from datetime import datetime, timedelta import pandas as pd from enum import Enum -#import plotly.graph_objects as go +import plotly.graph_objects as go from stockpredictor.analysis.Common import Common # enum 주문 상태 세팅용 @@ -519,13 +519,13 @@ class HTS: close_df = pd.DataFrame(close) avg5_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist() avg5 = [item[0] for item in avg5_list] - avg20_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() + avg20_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() avg20 = [item[0] for item in avg20_list] - avg60_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() + avg60_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() avg60 = [item[0] for item in avg60_list] - avg120_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() + avg120_list = close_df.rolling(window=40).mean().fillna(close[0]).values.tolist() avg120 = [item[0] for item in avg120_list] - avg240_list = close_df.rolling(window=40).mean().fillna(close[0]).values.tolist() + avg240_list = close_df.rolling(window=80).mean().fillna(close[0]).values.tolist() avg240 = [item[0] for item in avg240_list] upper, lower = [], [] @@ -605,6 +605,38 @@ class HTS: if temp_status != "": status.add(temp_status) + # 돌파 체크 + temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "20") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "60") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "120") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "5", "240") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "60") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "120") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "20", "240") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "120") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "60", "240") + if temp_status != "": + status.add(temp_status) + temp_status = self.common.check_Dolpa(STOCK, last_index, "120", "240") + if temp_status != "": + status.add(temp_status) + # 20일선 돌파 temp_status = self.common.check_Dolpa_Jiji(STOCK, last_index, '20') if temp_status != "": @@ -733,7 +765,7 @@ class HTS: size = len(data["Close"]) STOCK = [] for i in range(size): - STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i]}) + STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i], 'avg240': data["avg240"][i]}) bsLine = {} bsLine['buy'] = [-1 for i in range(size)] @@ -742,16 +774,26 @@ class HTS: i = size - 1 status = self.checkStatus(STOCK, i) count_1 = 0 - if "arrange_" in status: count_1 += 1 + # if "GOLDEN#2_" in status: count_1 += 1 + # if "arrange_" in status: count_1 += 1 + # if "UMYANG_" in status: count_1 += 1 + # if "5-20_" in status: count_1 += 1 + if "5_20_" in status: count_1 += 1 + if "5_60_" in status: count_1 += 1 + if "5_120_" in status: count_1 += 1 + if "5_240_" in status: count_1 += 1 + if "20_60_" in status: count_1 += 1 + if "20_120_" in status: count_1 += 1 + if "20_240_" in status: count_1 += 1 + if "60_120_" in status: count_1 += 1 + if "60_240_" in status: count_1 += 1 + if "120_240_" in status: count_1 += 1 if "arrange_" in status and "HIGHERUMBONG_" in status: count_1 += 1 if "20_" in status: count_1 += 1 if "60_" in status: count_1 += 1 if "120_" in status: count_1 += 1 if "240_" in status: count_1 += 1 - if "5-20_" in status: count_1 += 1 - if "GOLDEN#2_" in status: count_1 += 1 if "GOLDEN#3_" in status: count_1 += 1 - if "UMYANG_" in status: count_1 += 1 if "DOJI_" in status: count_1 += 1 if "DRAGONEFLY_" in status: count_1 += 1 if "HAMMER_" in status: count_1 += 1 @@ -782,7 +824,7 @@ class HTS: size = len(data["Close"]) STOCK = [] for i in range(size): - STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i]}) + STOCK.append({'volume': data['Volume'][i], 'close': data["Close"][i], 'open': data["Open"][i], 'high': data["High"][i], 'low': data["Low"][i], 'avg5': data["avg5"][i], 'avg20': data["avg20"][i], 'avg60': data["avg60"][i], 'avg120': data["avg120"][i], 'avg240': data["avg240"][i]}) bsLine = {} bsLine['buy'] = [-1 for i in range(len(lower))] @@ -791,16 +833,26 @@ class HTS: for i in range(5, size-5): status = self.checkStatus(STOCK, i) count_1 = 0 - if "arrange_" in status: count_1 += 1 + #if "GOLDEN#2_" in status: count_1 += 1 + #if "arrange_" in status: count_1 += 1 + #if "UMYANG_" in status: count_1 += 1 + #if "5-20_" in status: count_1 += 1 + if "5_20_" in status: count_1 += 1 + if "5_60_" in status: count_1 += 1 + if "5_120_" in status: count_1 += 1 + if "5_240_" in status: count_1 += 1 + if "20_60_" in status: count_1 += 1 + if "20_120_" in status: count_1 += 1 + if "20_240_" in status: count_1 += 1 + if "60_120_" in status: count_1 += 1 + if "60_240_" in status: count_1 += 1 + if "120_240_" in status: count_1 += 1 if "arrange_" in status and "HIGHERUMBONG_" in status: count_1 += 1 if "20_" in status: count_1 += 1 if "60_" in status: count_1 += 1 if "120_" in status: count_1 += 1 if "240_" in status: count_1 += 1 - if "5-20_" in status: count_1 += 1 - if "GOLDEN#2_" in status: count_1 += 1 if "GOLDEN#3_" in status: count_1 += 1 - if "UMYANG_" in status: count_1 += 1 if "DOJI_" in status: count_1 += 1 if "DRAGONEFLY_" in status: count_1 += 1 if "HAMMER_" in status: count_1 += 1 @@ -857,7 +909,7 @@ class HTS: def buyRealTime(self, stock_code, given_day): PREVIOUS_PRICE = 0 - BUY_COUNT = 100 + BUY_COUNT = 200 TOTAL_BUY_AMT = 0 logFp = open(given_day+".log", "w") @@ -894,23 +946,23 @@ class HTS: if bs_buy_price > 0: if PREVIOUS_PRICE > 0: if PREVIOUS_PRICE > bs_buy_price: - if BUY_COUNT > 140: + if BUY_COUNT > 240: + BUY_COUNT = 240 + if BUY_COUNT <= 140: BUY_COUNT = 140 - if BUY_COUNT <= 40: - BUY_COUNT = 40 BUY_COUNT += 10 elif PREVIOUS_PRICE < bs_buy_price: - if BUY_COUNT > 160: + if BUY_COUNT > 250: + BUY_COUNT = 260 + if BUY_COUNT <= 150: BUY_COUNT = 160 - if BUY_COUNT <= 60: - BUY_COUNT = 60 BUY_COUNT -= 10 PREVIOUS_PRICE = bs_buy_price # 매수 주문 # 현재까지 매입금액이 7백만원 이하일 때만 매수를 한다. - if TOTAL_BUY_AMT < 2000000: + if TOTAL_BUY_AMT < 5000000: self.requestOrder("2", stock_code, BUY_COUNT , bs_buy_price) ## 매도 주문 (아래 잔고를 체크해서 매도를 호출하는 것으로 시도한다.) @@ -929,25 +981,29 @@ class HTS: logFp.write("%s,%s,\n" % ("NONE", second)) logFp.flush() - # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. - jangoDic = self.requstJango() - if jangoDic and len(jangoDic.keys()) > 0: - for code in jangoDic: - TOTAL_BUY_AMT = jangoDic[code]['매입금액'] - if jangoDic[code]['매도가능'] > 0: - # 장부가 가격의 마지막 자리를 0으로 만든다. (2090 -> 2090, 2092 -> 2090, 2098 -> 2090) - sell_price = int(jangoDic[code]['장부가'] / 10) * 10 - # 장부가의 마지막 자리수를 가져온다. - last_number = int(jangoDic[code]['장부가']) % 10 - if last_number in [0, 1, 2]: - # 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5) - elif last_number in [3, 4, 5, 6]: - # 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10) - else: - # 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도) - self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15) + + # 60일 선이 꺾여서 하락 중일 경우만 바로 매도를 한다. + size = len(data["avg60"]) + if data["avg60"][size-2] > data["avg60"][size-1]: + # 만약 잔고가 있으면 장부가보다 5원 높게 매도한다. + jangoDic = self.requstJango() + if jangoDic and len(jangoDic.keys()) > 0: + for code in jangoDic: + TOTAL_BUY_AMT = jangoDic[code]['매입금액'] + if jangoDic[code]['매도가능'] > 0: + # 장부가 가격의 마지막 자리를 0으로 만든다. (2090 -> 2090, 2092 -> 2090, 2098 -> 2090) + sell_price = int(jangoDic[code]['장부가'] / 10) * 10 + # 장부가의 마지막 자리수를 가져온다. + last_number = int(jangoDic[code]['장부가']) % 10 + if last_number in [0, 1, 2]: + # 장부가의 마지막 자리수가 0,1,2 라면 (2090, 2091, 2092 -> 2095 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 5) + elif last_number in [3, 4, 5, 6]: + # 장부가의 마지막 자리수가 3,4,5,6 라면 (2093, 2094, 2095, 2096 -> 2100 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 10) + else: + # 장부가의 마지막 자리수가 7,8,9 라면 (2097, 2098, 2099 -> 2105 에 매도) + self.requestOrder("1", stock_code, jangoDic[code]['매도가능'], sell_price + 15) time.sleep(0.9) @@ -962,20 +1018,20 @@ if __name__ == "__main__": RESOURCE_DIR = PROJECT_HOME + "/resources/analysis/"+today.strftime("%Y%m%d") stock_codes = ["252670", "122630"] - given_days = ['20210901','20210902','20210903','20210906','20210907','20210908','20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930','20211001'] + stock_codes = ["252670"] + given_days = ['20210901','20210902','20210903','20210906','20210907','20210908','20210909','20210910','20210913','20210914','20210915','20210916','20210917','20210923','20210924','20210927','20210928','20210929','20210930','20211001', '20211005'] hts = HTS() #hts.all_stocks() #hts.getChartData(stock_codes) #hts.currentStock(stock_codes) - #for given_day in given_days: + for given_day in given_days: #hts.writeStockData(stock_codes, given_day) - #for stock_code in stock_codes: - #hts.simulate(stock_code, given_day) + for stock_code in stock_codes: + hts.simulate(stock_code, given_day) - given_day = datetime.today().strftime('%Y%m%d') - #hts.writeStockData(stock_codes, given_day) - hts.buyRealTime(stock_codes[0], given_day) + #given_day = datetime.today().strftime('%Y%m%d') + #hts.buyRealTime(stock_codes[0], given_day) print ("done...") diff --git a/stockpredictor/analysis/Common.py b/stockpredictor/analysis/Common.py index 3eeaabd..5755d19 100644 --- a/stockpredictor/analysis/Common.py +++ b/stockpredictor/analysis/Common.py @@ -420,6 +420,13 @@ class Common: return "STOCHASTIC#2_" return "" + def check_Dolpa(self, stock, i, avg1, avg2): + upper_index = 0 + if len(stock) > 2: + if stock[i-1]["avg"+avg1] < stock[i-1]["avg"+avg2] and stock[i]["avg"+avg1] > stock[i]["avg"+avg2]: + return avg1+"_"+avg2+"_" + return "" + def check_Dolpa_Jiji(self, stock, i, day='20'): upper_index = 0 if len(stock) > 5: