From 9f908fc04ae45dbf0d4246b8782d1db651157cf6 Mon Sep 17 00:00:00 2001 From: dsyoon Date: Fri, 13 Oct 2023 00:14:54 +0900 Subject: [PATCH] init --- Simulation.py | 52 ++++++++++---------- hts/BuySellChecker.py | 109 ++++++++++++++++++++++-------------------- 2 files changed, 83 insertions(+), 78 deletions(-) diff --git a/Simulation.py b/Simulation.py index aead07e..e903bff 100644 --- a/Simulation.py +++ b/Simulation.py @@ -192,39 +192,37 @@ class Simulation (HTS): return result def simulate(self, stock_codes:dict=None, analyzed_day=1000): - if stock_codes is not None: - for stock_code in stock_codes: - for given_day in stock_codes[stock_code]: - LAST_DATA = self.stock2Vector.getLastData(stock_code, given_day) - result = self.stock2Vector.getRealTime(stock_code, given_day, LAST_DATA) - #result_5 = self.makeTickData(result, mins=5) - #result_30 = self.makeTickData(result, mins=30) + for stock_code in stock_codes: + for given_day in stock_codes[stock_code]: + LAST_DATA = self.stock2Vector.getLastData(stock_code, given_day) + # 1분봉 + result = self.stock2Vector.getRealTime(stock_code, given_day, LAST_DATA) + # 5분봉 + #result = self.makeTickData(result, mins=5) + # 30분봉 + #result = self.makeTickData(result, mins=30) - data = self.buySellChecker.analyze(result) - data.drop(data.index[:len(data) - analyzed_day], inplace=True) + data = self.buySellChecker.analyze(result) + data.drop(data.index[:len(data) - analyzed_day], inplace=True) - # 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. - #data_5 = self.buySellChecker.analyze(result_5) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - #data_5.drop(data_5.index[:len(data_5) - analyzed_day], inplace=True) + # 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. + #data_5 = self.buySellChecker.analyze(result_5) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + #data_5.drop(data_5.index[:len(data_5) - analyzed_day], inplace=True) - #data_30 = self.buySellChecker.analyze(result_30) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - #data_30.drop(data_30.index[:len(data_30) - analyzed_day], inplace=True) + #data_30 = self.buySellChecker.analyze(result_30) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + #data_30.drop(data_30.index[:len(data_30) - analyzed_day], inplace=True) - # 사야 할 시점과 팔아야 할 시점을 체크한다. - #bsLine = self.buySellChecker.checkTransaction(stock_code, data, data_5, data_30, isRealTime=False) + # 사야 할 시점과 팔아야 할 시점을 체크한다. + #bsLine = self.buySellChecker.checkTransaction(stock_code, data, data_5, data_30, isRealTime=False) - # 어제 데이터는 지운다. - #data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])] - bsLine = self.buySellChecker.checkTransaction(stock_code, data, None, None, isRealTime=False) - - # 그래프를 그린다. - self.draw(stock_code, given_day, data, bsLine) - else: - stockStatus = StockStatus(self.RESOURCE_PATH) - stockStatus.checkEnvelope() + # 어제 데이터는 지운다. + #data = data.loc[pd.DatetimeIndex(data.index).day == int(given_day[6:])] + bsLine = self.buySellChecker.checkTransaction(stock_code, data, None, None, isRealTime=False) + # 그래프를 그린다. + self.draw(stock_code, given_day, data, bsLine) return if __name__ == "__main__": diff --git a/hts/BuySellChecker.py b/hts/BuySellChecker.py index 5acbed8..b733e66 100644 --- a/hts/BuySellChecker.py +++ b/hts/BuySellChecker.py @@ -216,20 +216,68 @@ class BuySellChecker: return buy, weight + + + def getBuyPriceAndWeight(self, i, data): + buy, weight = -1, -1 + + # 1) 스토캐스틱 과매도 + slow_k_buy = False + for idx in range(i, i-10, -1): + if data['slow_k'][idx] < 20: + slow_k_buy = True + break + + # 2) macd 교차 신호 + macd_buy = False + if slow_k_buy: + for idx in range(i, i-10, -1): + if data['macd'][idx - 1] < 0 and data['macds'][idx - 1] < 0 and data['macd'][idx] < 0 and data['macds'][idx] < 0: + if data['macd'][idx-1] < data['macds'][idx-1] and data['macd'][idx] > data['macds'][idx]: + macd_buy = True + break + + # 3) RSI 지수가 50위로 올라갈 때 + if macd_buy: + if data['rsi'][i-1] < 40 and data['rsi'][i] > 40: + buy, weight = data['close'][i] , 1 + + + min_macd = min(data['macd']) + if i > 30 and data['macd'][i] < min_macd + (-min_macd * 0.5): + buy, weight = data['close'][i], 1 + + return buy, weight + + def getSellPriceAndWeight(self, i, data): sell, weight = -1, -1 + # 1) 스토캐스틱 과매수 + slow_k_sell = False + for idx in range(i, i-10, -1): + if data['slow_k'][idx] > 80: + slow_k_sell = True + break - if 90 < data['slow_k'][i] and data['slow_k'][i] < data['slow_k'][i-1] and data['slow_k'][i] < data['slow_d'][i]: - sell = data['close'][i] - weight = 100 - if 95 < data['slow_k'][i]: - sell = data['close'][i] - weight = 100 + # 2) macd 교차 신호 + macd_sell = False + if slow_k_sell: + for idx in range(i, i-10, -1): + if data['macd'][idx - 1] > 0 and data['macds'][idx - 1] > 0 and data['macd'][idx] > 0 and data['macds'][idx] > 0: + if data['macd'][idx-1] > data['macds'][idx-1] and data['macd'][idx] < data['macds'][idx]: + macd_sell = True + break + + # 3) RSI 지수가 50위로 올라갈 때 + if macd_sell: + if data['rsi'][i-1] > 60 and data['rsi'][i] < 60: + sell, weight = data['close'][i], 1 return sell, weight + def analyze(self, result): # 기본 캔들 정보 open = result["open"] @@ -348,25 +396,11 @@ class BuySellChecker: # isRealTime=True, 실시간 적용 last_index = size - 1 - if stock_code == "252670": - buy, buy_weight = self.getBuyPriceAndWeight_252670(last_index, data) - sell, sell_weight = self.getSellPriceAndWeight(last_index, data) - else: - buy, buy_weight = self.getBuyPriceAndWeight_122630(last_index, data) - sell, sell_weight = self.getSellPriceAndWeight(last_index, data) + buy, buy_weight = self.getBuyPriceAndWeight_252670(last_index, data) + sell, sell_weight = self.getSellPriceAndWeight(last_index, data) if data.index[last_index].strftime('%H:%M:%S') > datetime.strptime(datetime.today().strftime("%Y-%m-%d 15:10:00"), "%Y-%m-%d %H:%M:%S").strftime('%H:%M:%S'): buy, buy_weight = -1, -1 - if sell > 0: - if 'last_buy' in bsLine: - if bsLine['last'] == 'buy': - if sell - bsLine['last_buy'] < 0.007: - sell, weight = -1, -1 - else: - sell, weight = -1, -1 - if 'last' in bsLine and bsLine['last'] != 'buy': - sell, weight = -1, -1 - bsLine['buy'] = [buy] bsLine['buy_weight'] = [buy_weight] bsLine['sell'] = [sell] @@ -378,44 +412,17 @@ class BuySellChecker: bsLine['buy_weight'] = [-1 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1 for i in range(size)] - bsLine['last'] = '' - bsLine['last_buy'] = -1 - bsLine['buy_count'] = 0 for last_index in range(size): - if stock_code == "252670": - buy, buy_weight = self.getBuyPriceAndWeight_252670(last_index, data) - sell, sell_weight = self.getSellPriceAndWeight(last_index, data) - else: - buy, buy_weight = self.getBuyPriceAndWeight_122630(last_index, data) - sell, sell_weight = self.getSellPriceAndWeight(last_index, data) - if data.index[last_index].strftime('%H:%M:%S') > datetime.strptime(datetime.today().strftime("%Y-%m-%d 15:10:00"), "%Y-%m-%d %H:%M:%S").strftime('%H:%M:%S'): - buy, buy_weight = -1, -1 - if sell > 0: - if 'last_buy' in bsLine: - if bsLine['last'] == 'buy': - if sell - bsLine['last_buy'] < 0.007: - sell, weight = -1, -1 - else: - sell, weight = -1, -1 - if 'last' in bsLine and bsLine['last'] != 'buy': - sell, weight = -1, -1 + buy, buy_weight = self.getBuyPriceAndWeight(last_index, data) + sell, sell_weight = self.getSellPriceAndWeight(last_index, data) bsLine['buy'][last_index] = buy bsLine['buy_weight'][last_index] = buy_weight bsLine['sell'][last_index] = sell bsLine['sell_weight'][last_index] = sell_weight - if buy > 0: - bsLine['last'] = 'buy' - bsLine['last_buy'] = buy - bsLine['buy_count'] += 1 - if sell > 0: - bsLine['last'] = 'sell' - bsLine['last_buy'] = -1 - bsLine['buy_count'] = 0 - return bsLine def checkTransactionML(self, data, stock_code, predY, isRealTime=True):