diff --git a/Simulation.py b/Simulation.py index 5840db6..5e79b59 100644 --- a/Simulation.py +++ b/Simulation.py @@ -122,9 +122,9 @@ class Simulation (HTS): rsi_line = go.Scatter(x=data['date'], y=data["rsi"], line=dict(color='red', width=2), name='rsi') rsis_line = go.Scatter(x=data['date'], y=data["rsis"], line=dict(dash='dashdot', color='black', width=2), name='rsis') - #candle_data = [candle_stick, upper, lower, avg5, avg20, avg30, avg60, avg120, avg200, buy_check, sell_check, laggingSpan, changeLine, baseLine] + candle_data = [candle_stick, upper, lower, avg5, avg20, avg30, avg60, avg120, avg200, buy_check, sell_check, laggingSpan, changeLine, baseLine] candle_data = [candle_stick, avg5, avg20, avg30, avg60, avg200, buy_check, sell_check] - #candle_data = [candle_stick, buy_check, sell_check] + candle_data = [candle_stick, avg200, buy_check, sell_check] volume_data = [volume_line] disparity_data = [disparity_avg5, disparity_avg20, disparity_avg30, disparity_avg60, disparity_avg120, disparity_avg200] macd_data = [macd_line, macd_s_line, macd_o_line] @@ -140,20 +140,20 @@ class Simulation (HTS): fig = subplots.make_subplots( rows=6, cols=1, - subplot_titles=("MACD", "스토캐스틱", "RSI", "거래량", "이격도", '캔들'), + subplot_titles=("거래량", "이격도", "스토캐스틱", "RSI", "MACD", '캔들'), #specs=[[{}], [{}], [{}], [{}], [{}], [{}]], shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.01, row_heights=[200, 200, 200, 200, 200, 700] ) - for trace in macd_data: - fig.append_trace(trace, 1, 1) - for trace in stochastic_data: - fig.append_trace(trace, 2, 1) - for trace in rsi_data: - fig.append_trace(trace, 3, 1) for trace in volume_data: - fig.append_trace(trace, 4, 1) + fig.append_trace(trace, 1, 1) for trace in disparity_data: + fig.append_trace(trace, 2, 1) + for trace in stochastic_data: + fig.append_trace(trace, 3, 1) + for trace in rsi_data: + fig.append_trace(trace, 4, 1) + for trace in macd_data: fig.append_trace(trace, 5, 1) for trace in candle_data: fig.append_trace(trace, 6, 1) @@ -240,8 +240,12 @@ if __name__ == "__main__": # to check bying stock_codes = { - "252670": ['20220906'], + #"252670": ['20210924'], + #"252670": ['20210901','20210902','20210903','20210906'], + #"252670": ['20210901', '20210902', '20210903', '20210906', '20210907', '20210908', '20210909', '20210910', '20210913', '20210914', '20210915', '20210916', '20210917', '20210923', '20210924', '20210927', '20210928', '20210929', '20210930', '20211001', '20211005'], #"122630": ['20220901', '20220902', '20220905', '20220906'] + #"122630": ['20210916'], + "122630": ['20210901', '20210902', '20210903', '20210906', '20210907', '20210908', '20210909', '20210910', '20210913', '20210914', '20210915', '20210916', '20210917', '20210923', '20210924', '20210927', '20210928', '20210929', '20210930', '20211001', '20211005'], } #simulation.simulate(stock_codes) simulation.simulate(stock_codes) diff --git a/hts/BuySellChecker.py b/hts/BuySellChecker.py index 3235f33..6c040f3 100644 --- a/hts/BuySellChecker.py +++ b/hts/BuySellChecker.py @@ -110,92 +110,121 @@ class BuySellChecker: return -1 return 0 - def getBuyPriceAndWeight(self, stock_code, i, data, data_5=None, data_30=None): + def isAvg200UP(self, data, idx, until=10, limit=0.9): + even, up, down = 0, 0, 0 + for i in range(idx, idx - (until + 1), -1): + if data['avg200'][i] < data['close'][i]: + up += 1 + if data['avg200'][i] > data['close'][i]: + down += 1 + else: + even += 1 + if up * (1 - limit) > down: + return True + return False + + + def getBuyPriceAndWeight_252670(self, i, data): buy, weight = -1, -1 - if data_5 is not None and data_30 is not None: - if len(data_5['slow_k']) <= i or len(data_30['slow_k']) <= i: - return buy, weight - - if data_5['slow_k'][i] < 20: - if data_5['slow_k'][i - 1] < data_5['slow_d'][i - 1] and data_5['slow_d'][i] < data_5['slow_k'][i]: - buy = data['low'][i] - weight = 0.3 - - if data_30['slow_k'][i] < 30 and data_5['slow_k'][i] < 30: - if data_5['slow_k'][i - 1] < data_5['slow_d'][i - 1] and data_5['slow_d'][i] < data_30['slow_k'][i]: + if i > 50: + up, down = 0, 0 + for idx in range(i, i - (300 + 1), -1): + if data['avg200'][idx-1] < data['avg200'][idx]: + up += 1 + if data['avg200'][idx-1] > data['avg200'][idx]: + down += 1 + if up < down: + if max(data['avg200'][i-20:i])+0.05 < data['avg200'][i]: buy = data['close'][i] weight = 0.3 - if data_30['slow_k'][i] < 30: - if data_5['slow_k'][i] < 30: - if data_5['avg5'][i] < data_5['close'][i]: - buy = data['close'][i] - weight = 0.2 + up, down = 0, 0 + for idx in range(i, i - (10 + 1), -1): + if data['close'][idx-1] < data['close'][idx]: + up += 1 + elif data['close'][idx - 1] > data['close'][idx]: + down += 1 + if down < up: + buy, weight = -1, -1 - if data_5['slow_k'][i - 1] < data_5['slow_d'][i - 1] and data_5['slow_d'][i] < data_30['slow_k'][i]: - buy = data['close'][i] - weight = 0.3 - else: - if data['close'][i-1] < data['avg200'][i-1] and data['avg200'][i] < data['close'][i]: - if not self.common.checkUpward(data['avg200'], i): - if data['avg60'][i] 200: + if ( + ( + min(data['avg200'][i-53: i-48]) > min(data['avg200'][i-48: i-43]) > + min(data['avg200'][i-43: i-38]) > min(data['avg200'][i-38: i-33]) > + min(data['avg200'][i-33: i-28]) > min(data['avg200'][i-28: i-23]) > + min(data['avg200'][i-23: i-18]) > min(data['avg200'][i-18: i-13]) > + min(data['avg200'][i-13: i-8]) > min(data['avg200'][i-8: i-3]) > + data['avg200'][i-3] + ) and + data['avg200'][i-3] < min(data['avg200'][i-2:i]) + ): + if data['close'][i] < data['close'][i-30]: + buy = data['close'][i] + weight = 0.2 + + if ( + ( + min(data['avg200'][i-103: i-93]) >= min(data['avg200'][i-93: i-83]) >= + min(data['avg200'][i-83: i-73]) >= min(data['avg200'][i-73: i-63]) >= + min(data['avg200'][i-63: i-53]) >= min(data['avg200'][i-53: i-43]) >= + min(data['avg200'][i-43: i-33]) >= min(data['avg200'][i-33: i-23]) > + min(data['avg200'][i-23: i-13]) > min(data['avg200'][i-13: i-3]) > + data['avg200'][i-3] + ) and + ( + max(data['avg200'][i - 103: i - 93]) - min(data['avg200'][i - 93: i - 83]) > + max(data['avg200'][i - 83: i - 73]) - min(data['avg200'][i - 73: i - 63]) > + max(data['avg200'][i - 63: i - 53]) - min(data['avg200'][i - 53: i - 43]) > + max(data['avg200'][i - 43: i - 33]) - min(data['avg200'][i - 33: i - 23]) > + max(data['avg200'][i - 23: i - 13]) - min(data['avg200'][i - 13: i - 3]) + ) and + data['avg200'][i-3] < min(data['avg200'][i-2:i]) + ): + if 25 < max(data['macd'][i-50: i-20]) and data['close'][i] < data['close'][i - 30]: + if data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_k'][i] < 50 and data['macd'][i-1] < data['macd'][i]: + buy = data['close'][i] + weight = 0.2 + + if 25 < max(data['macd'][i-50: i-20]) and min(data['macd'][i-20: i]) < -30 and 0 < data['macd'][i] < 3: + if data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_k'][i] < 50 and data['macd'][i-1] < data['macd'][i]: + buy = data['close'][i]+5 + weight = 0.2 + + if 25 < max(data['macd'][i-50: i-20]) and data['macd'][i] < -20 and data['macd'][i-1] < data['macd'][i]: + if data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_k'][i] < 50 and data['macd'][i-1] < data['macd'][i]: + buy = data['close'][i]+5 + weight = 0.2 + + if 0.00988 < data['disparity_avg5'][i] - data['disparity_avg200'][i]: + if 25 < max(data['macd'][i-50: i-20]) and data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_k'][i] < 50 and data['macd'][i-1] < data['macd'][i]: + buy = data['close'][i] + 10 + weight = 0.2 + return buy, weight + + + def getSellPriceAndWeight(self, i, data): sell, weight = -1, -1 - if data_5 is not None and data_30 is not None: - if len(data_5['slow_k']) <= i or len(data_30['slow_k']) <= i: - return sell, weight - if data_30['slow_k'][i] > 90: - if (data_5['slow_d'][i-1] < data_5['slow_k'][i-1] and data_5['slow_k'][i] < data_5['slow_d'][i]): - sell = data['close'][i] - weight = 100 - - if data_5['slow_k'][i] > 95 and data_5['slow_k'][i] < data_5['slow_d'][i]: - sell = data['close'][i] - weight = 100 - - if data_30['slow_k'][i] > 98 and data_5['slow_k'][i] > 98: - sell = data['close'][i] - weight = 100 - else: - if (5 < max(data['avg5'][i], data['avg20'][i], data['avg60'][i], data['avg200'][i]) - min(data['avg5'][i], data['avg20'][i], data['avg60'][i], data['avg200'][i])): - if data['avg200'][i-1] < data['avg200'][i] and (data['avg30'][i-1] > data['avg30'][i] or data['close'][i] < data['avg30'][i]): - sell = data['close'][i] - weight = 100 - - if data['avg30'][i-1] < data['close'][i-1] and data['close'][i] < data['avg30'][i]: - sell = data['close'][i] - weight = 100 - - if stock_code == '252670': - diff = 15 - else: - diff = 50 - if diff < max(data['high'][i-5],data['high'][i-4],data['high'][i-3],data['high'][i-2],data['high'][i-1]) - data['low'][i]: - sell = data['close'][i] - weight = 100 + 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 return sell, weight @@ -316,8 +345,13 @@ class BuySellChecker: # isRealTime=True, 실시간 적용 last_index = size - 1 - buy, buy_weight = self.getBuyPriceAndWeight(stock_code, last_index, data, data_5, data_30) - sell, sell_weight = self.getSellPriceAndWeight(stock_code, last_index, data, data_5, data_30) + 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 sell > 0 and 'last_buy' in bsLine[stock_code]: if bsLine[stock_code]['last'] == 'buy': if sell - bsLine[stock_code]['last_buy'] < 0.007: @@ -341,11 +375,18 @@ class BuySellChecker: bsLine[stock_code]['buy_weight'] = [-1 for i in range(size)] bsLine[stock_code]['sell'] = [-1 for i in range(size)] bsLine[stock_code]['sell_weight'] = [-1 for i in range(size)] + bsLine[stock_code]['last'] = '' + bsLine[stock_code]['last_buy'] = -1 + bsLine[stock_code]['buy_count'] = 0 for last_index in range(size): - buy, buy_weight = self.getBuyPriceAndWeight(stock_code, last_index, data, data_5, data_30) - sell, sell_weight = self.getSellPriceAndWeight(stock_code, last_index, data, data_5, data_30) - if data.index[last_index].strftime('%H:%M:%S') > datetime.strptime(datetime.today().strftime("%Y-%m-%d 15:00:00"), "%Y-%m-%d %H:%M:%S").strftime('%H:%M:%S'): + 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: @@ -357,21 +398,25 @@ class BuySellChecker: sell, weight = -1, -1 if 'last' in bsLine[stock_code] and bsLine[stock_code]['last'] != 'buy': sell, weight = -1, -1 - 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'): - if 'last' in bsLine[stock_code] and bsLine[stock_code]['last'] == 'buy': - sell, weight = data['close'][last_index], -1 - bsLine[stock_code]['last'] = '' - bsLine[stock_code]['last_buy'] = -1 + #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'): + # if 'last' in bsLine[stock_code] and bsLine[stock_code]['last'] == 'buy': + # sell, weight = data['close'][last_index], -1 + # bsLine[stock_code]['last'] = '' + # bsLine[stock_code]['last_buy'] = -1 bsLine[stock_code]['buy'][last_index] = buy bsLine[stock_code]['buy_weight'][last_index] = buy_weight bsLine[stock_code]['sell'][last_index] = sell bsLine[stock_code]['sell_weight'][last_index] = sell_weight + if buy > 0: bsLine[stock_code]['last'] = 'buy' bsLine[stock_code]['last_buy'] = buy + bsLine[stock_code]['buy_count'] += 1 if sell > 0: bsLine[stock_code]['last'] = 'sell' + bsLine[stock_code]['last_buy'] = -1 + bsLine[stock_code]['buy_count'] = 0 return bsLine diff --git a/stock/analysis/Common.py b/stock/analysis/Common.py index 5e8db52..6f95a73 100644 --- a/stock/analysis/Common.py +++ b/stock/analysis/Common.py @@ -4,26 +4,21 @@ from stock.analysis.MovingAverage import MovingAverage class Common: # 상향 - def checkUpward(self, data, idx): + def getDirection(self, data, idx, until=10): up, down = 0, 0 - for i in range(idx, idx-11, -1): - if data[i-1] < data[i]: + for i in range(idx, idx-(until+1), -1): + if data[i - 1] < data[i]: up += 1 - else: + if data[i - 1] > data[i]: down += 1 - if up > down: - return True - return False - # 하향 - def checkDownward(self, type, data): - check = True - for i in range(len(data)-1): - # 만약 이전이 이후보다 작다면, 하락이 아님 - if data[i][type] < data[i+1][type]: - check = False - break - return check + if down < up: + if data[idx - 3] < data[idx]: + return 'UP' + elif up < down: + if data[idx - 3] > data[idx]: + return 'DOWN' + return 'EVEN' # 상향 돌파 def checkUpwardBreakthrough(self, type1, type2, data):