diff --git a/Simulation.py b/Simulation.py index 16c3d31..c1ea32a 100644 --- a/Simulation.py +++ b/Simulation.py @@ -52,8 +52,7 @@ class Simulation (HTS): 'avg6': 'float', 'avg9': 'float', 'avg12': 'float', - 'avg27': 'float', - 'avg54': 'float', + 'avg20': 'float', 'fast_k': 'float', 'slow_k': 'float', 'slow_d': 'float', @@ -89,8 +88,7 @@ class Simulation (HTS): avg6 = go.Scatter(x=data['date'], y=data["avg6"], name="avg6", line_color='#089B5B') avg9 = go.Scatter(x=data['date'], y=data["avg9"], name="avg9", line_color='#ff00ff') avg12 = go.Scatter(x=data['date'], y=data["avg12"], name="avg12", line_color='#1469F4') - avg27 = go.Scatter(x=data['date'], y=data["avg27"], name="avg27", line_color='#000000') - avg54 = go.Scatter(x=data['date'], y=data["avg54"], name="avg54", line_color='#008000') + avg20 = go.Scatter(x=data['date'], y=data["avg20"], name="avg20", line_color='#000000') candle_stick = go.Candlestick(x=data['date'], open=data['open'], high=data['high'], low=data['low'], close=data['close'], increasing_line_color='red', decreasing_line_color='blue') volume_line = go.Scatter(x=data['date'], y=data["volume"], mode='lines', name='volume') @@ -106,7 +104,7 @@ class Simulation (HTS): rsi_line = go.Scatter(x=data['date'], y=data["rsi"], mode='lines', name='rsi') rsis_line = go.Scatter(x=data['date'], y=data["rsis"], mode='lines', name='rsis') - candle_data = [candle_stick, upper, lower, avg3, avg6, avg9, avg12, avg27, avg54, buy_check, sell_check] + candle_data = [candle_stick, upper, lower, avg3, avg6, avg9, avg12, avg20, buy_check, sell_check] volume_data = [volume_line] macd_data = [macd_line, macd_s_line, macd_o_line] stochastic_data = [slow_k_line, slow_d_line] @@ -184,12 +182,8 @@ if __name__ == "__main__": # to check bying stock_codes = { - "252670": [ - '20220510', '20220511', '20220512', - '20220610', '20220613', '20220614', - '20220708', '20220711', '20220712', - '20220810', '20220811', '20220812'], - #"122630": ['20220611', '20220612', '20220613', '20220614'], + "252670": ['20220822', '20220823', '20220824', '20220825', '20220826'], + #"122630": ['20220822', '20220823', '20220824', '20220825', '20220826'] } method = "rule" # "rule", "ml", "answer" diff --git a/hts/BuySellChecker.py b/hts/BuySellChecker.py index 7e7d8c0..5cdf393 100644 --- a/hts/BuySellChecker.py +++ b/hts/BuySellChecker.py @@ -183,6 +183,103 @@ class BuySellChecker: + def getBuyPriceAndWeight(self, data, i): + buy, weight = -1, -1 + slow_k = 60 + + START_TIME_INDEX = 0 + for c in range(370, len(data.index)): + if data.index[c].strftime("%H:%M:%S") == "09:01:00": + START_TIME_INDEX = c + break + + if i > START_TIME_INDEX: + # 매수 분석 + + valid = True + for c in range(i-10, i+1): + if data["avg20"][c-1] > data["avg20"][c]: + valid = False + if valid: + min_value = min(data["open"][i], data["close"][i]) + max_value = max(data["open"][i], data["close"][i]) + if min_value < data["avg20"][i] < max_value: + if data["slow_k"][i] < slow_k: + buy = min_value + weight = 1 + + if data["slow_k"][i] < slow_k: + valid = True + for c in range(i - 5, i + 1): + if data["avg20"][c] >= min(data["avg3"][c], data["avg6"][c], data["avg9"][c], data["avg12"][c]): + valid = False + break + if valid: + valid = False + for c in range(i - 20, i + 1): + if data["avg20"][c] > max(data["avg3"][c], data["avg6"][c], data["avg9"][c], data["avg12"][c]): + valid = True + break + if valid: + buy = max(int(data["open"][i]+data["close"][i])/2, min(data["open"][i], data["close"][i])) + weight = 1 + + return buy, weight + + def getSellPriceAndWeight(self, data, i): + sell, weight = -1, -1 + slow_k = 60 + + START_TIME_INDEX = 0 + for c in range(370, len(data.index)): + if data.index[c].strftime("%H:%M:%S") == "09:01:00": + START_TIME_INDEX = c + break + + if i > START_TIME_INDEX: + # 매도 분석 + + # 3분선이 10분 이상 6분선 위에 있다가 6분선 아래로 내려옴 + if i >= 381 + 10: + vaild = True + count = 0 + for c in range(i-10, i+1): + if data["avg3"][c-1] == data["avg20"][c]: + count += 1 + if data["avg3"][c-1] < data["avg20"][c]: + vaild = False + break + if vaild and count < 3: + if data["avg3"][i] < data["avg20"][i]: + if data["slow_k"][i] > slow_k: + sell = int(data["avg3"][i] - data["avg3"][i] % 5) + weight = 1 + return sell, weight + + # 12분선이 5분 이상 20분선 위에 있다가 20분선 아래로 내려옴 + if i >= 381 + 5: + vaild = True + for c in range(1, 6): + if data["avg12"][i - c] < data["avg20"][i - c]: + vaild = False + break + if vaild: + if data["avg12"][i] < data["avg20"][i] and data["avg20"][i-1] < data["avg20"][i]: + if data["slow_k"][i] > slow_k: + sell = data["close"][i] + weight = 1 + return sell, weight + + if (not (data["avg20"][i-1] > max(data["avg3"][i-1], data["avg6"][i-1], data["avg9"][i-1], data["avg12"][i-1])) and + (data["avg20"][i] > max(data["avg3"][i], data["avg6"][i], data["avg9"][i], data["avg12"][i]))): + if data["slow_k"][i] > slow_k: + sell = data["close"][i] + weight = 1 + return sell, weight + + return sell, weight + + # 곱버스에 해당함 def getBuyPriceAndWeight_252670(self, data, i): buy, weight = -1, -1 @@ -220,7 +317,6 @@ class BuySellChecker: weight = 1 return buy, weight - return buy, weight def getSellPriceAndWeight_252670(self, data, i): @@ -445,6 +541,96 @@ class BuySellChecker: vol = result["vol"] label = result["label"] + # 이동 평균 + close_df = pd.DataFrame(close) + avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist() + avg3 = [item[0] for item in avg3_list] + avg6_list = close_df.rolling(window=6).mean().fillna(close[0]).values.tolist() + avg6 = [item[0] for item in avg6_list] + avg9_list = close_df.rolling(window=9).mean().fillna(close[0]).values.tolist() + avg9 = [item[0] for item in avg9_list] + avg12_list = close_df.rolling(window=12).mean().fillna(close[0]).values.tolist() + avg12 = [item[0] for item in avg12_list] + avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() + avg20 = [item[0] for item in avg20_list] + + # 볼린져 밴드 + df = pd.DataFrame(close) + max20 = df.rolling(window=20).mean() + stddev20 = df.rolling(window=20).std() + upper_df = max20 + (stddev20 * 2) # 상단 볼린저 밴드 + lower_df = max20 - (stddev20 * 2) # 하단 볼린저 밴드 + + upper, lower = [], [] + for i in range(len(upper_df)): + if i < 10: + upper.append(upper_df.values[0][0]) + lower.append(lower_df.values[0][0]) + else: + upper.append(upper_df.values[i][0]) + lower.append(lower_df.values[i][0]) + + point_temp = result["time"] + STOCK = [] + for i in range(len(open)): + STOCK.append({'volume': vol[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i], + 'avg20': avg20[i]}) + + # stochastic + stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5) + fast_k = stochastic_df['fast_k'].values.tolist() + slow_k = stochastic_df['slow_k'].values.tolist() + slow_d = stochastic_df['slow_d'].values.tolist() + + # macd + macd_df = self.macd.apply(STOCK, short=12, long=26, t=9) + macd = macd_df['macd'].values.tolist() + macds = macd_df['macds'].values.tolist() + macdo = macd_df['macdo'].values.tolist() + + # rsi + rsi_df = self.rsi.apply(STOCK, period=30, window=5) + rsi = rsi_df['rsi'].values.tolist() + rsis = rsi_df['rsis'].values.tolist() + + # ichimokuCloud + ichimokuCloud_df = self.ichimokuCloud.apply(STOCK, c=9, b=26, l=52) + ichimokuCloud_df = ichimokuCloud_df[:len(ichimokuCloud_df) - 51] + changeLine = ichimokuCloud_df['changeLine'].values.tolist() + baseLine = ichimokuCloud_df['baseLine'].values.tolist() + leadingSpan1 = ichimokuCloud_df['leadingSpan1'].values.tolist() + leadingSpan2 = ichimokuCloud_df['leadingSpan2'].values.tolist() + + # 결과 + temp = { + "date": point_temp, + "open": open, "high": high, "low": low, "close": close, "volume": vol, + "avg3": avg3,"avg6": avg6,"avg9": avg9,"avg12": avg12, "avg20": avg20, + "upper": upper, "lower": lower, + "macd": macd, "macds": macds, "macdo": macdo, + "fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d, + "rsi": rsi, "rsis": rsis, + "changeLine": changeLine, "baseLine": baseLine, "leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2, + + "label": label + } + + data = pd.DataFrame(temp) + df_final_time = pd.DatetimeIndex(point_temp) + data.index = df_final_time + + data = data.fillna(close[0]) + return data + + def analyze1(self, result): + # 기본 캔들 정보 + open = result["open"] + close = result["close"] + high = result["high"] + low = result["low"] + vol = result["vol"] + label = result["label"] + # 캔들 정보 연산 height = [close[i] - open[i] for i in range(0, len(close))] top_tail_height = [high[i] - max(open[i], close[i]) for i in range(0, len(close))] @@ -839,12 +1025,16 @@ class BuySellChecker: # isRealTime=True, 실시간 적용 last_index = size - 1 + buy, buy_weight = self.getBuyPriceAndWeight(data, last_index) + sell, sell_weight = self.getSellPriceAndWeight(data, last_index) + """ if stock_code == "252670": sell, sell_weight = self.getSellPriceAndWeight_252670(data, last_index) buy, buy_weight = self.getBuyPriceAndWeight_252670(data, last_index) else: sell, sell_weight = self.getSellPriceAndWeight_122630(data, last_index) buy, buy_weight = self.getBuyPriceAndWeight_122630(data, last_index) + """ bsLine['buy'] = [buy] bsLine['buy_weight'] = [buy_weight] @@ -858,12 +1048,16 @@ class BuySellChecker: bsLine['sell_weight'] = [-1 for i in range(size)] for i in range(size): + buy, buy_weight = self.getBuyPriceAndWeight(data, i) + sell, sell_weight = self.getSellPriceAndWeight(data, i) + """ if stock_code == "252670": sell, sell_weight = self.getSellPriceAndWeight_252670(data, i) buy, buy_weight = self.getBuyPriceAndWeight_252670(data, i) else: sell, sell_weight = self.getSellPriceAndWeight_122630(data, i) buy, buy_weight = self.getBuyPriceAndWeight_122630(data, i) + """ bsLine['buy'][i] = buy bsLine['buy_weight'][i] = buy_weight bsLine['sell'][i] = sell diff --git a/requirements.txt b/requirements.txt index dfa9eea..193afd9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,8 @@ plotly matplotlib pandas_datareader bs4 -pywin32 +datasets +#pywin32 ipywidgets==7.0.0 #keras