import pandas as pd from stock.analysis.Common import Common from stock.analysis.Stochastic import Stochastic from stock.analysis.RSI import RSI from stock.analysis.MACD import MACD from stock.analysis.IchimokuCloud import IchimokuCloud class BuySellChecker: common = None stochastic = None rsi = None macd = None ichimokuCloud = None BUY_COUNT = None def __init__(self): self.common = Common() self.stochastic = Stochastic() self.rsi = RSI() self.macd = MACD() self.ichimokuCloud = IchimokuCloud() self.BUY_COUNT = 0 return def getBuyPriceAndWeight(self, i, data): buy, weight, type = -1, -1, "" """ # 매수전략 #1: 다이버전스 if data['macd'][i] < 0 and data['open'][i] < data['close'][i]: if 0 < len(data['rsi'].tolist()[i - 10:i - 5]): if min(data['rsi'].tolist()[i - 10:i - 5]) < data['rsi'][i - 1]: if data['low'][i - 1] < min(data['low'].tolist()[i - 10:i - 5]): weight = 1 buy = data['close'][i] type = 'Divergence' """ high_barrier = 70 low_barrier = 30 Buy_Price=[] Sell_Price=[] number=[] temp01 = [] temp01_id = [] temp02 = [] temp01_id = [] temp01_min_price = [] temp02_min_price = [] temp01_min_rsi = [] temp02_min_rsi = [] n_id=[] i_id=[] flag=1 n = 0 # https://superhky.tistory.com/441 find = False for c in range(i-40, i-1): if data['rsi'][i-1] > low_barrier and data['rsi'][i] < low_barrier: for k in range(c, i): if data['rsi'][k-1] < low_barrier and data['rsi'][k] > low_barrier: temp01 = data['rsi'].iloc[c:k] temp01_id = temp01.argmin() + c temp01_min_rsi = data['rsi'][temp01_id] temp01_min_price = data['close'][temp01_id] for m in range(k, i): if data['rsi'][m-1] < low_barrier and data['rsi'][m] < low_barrier: for n in range(m, i): if data['rsi]'][n-1] < low_barrier and data['rsi'][n] < low_barrier: temp02 = data['rsi'].iloc[m:n] temp02_id = temp02.argmin() + m temp02_min_rsi = data['rsi'][temp02_id] temp02_min_price = data['close'][temp02_id] if temp01_min_rsi < temp02_min_rsi and temp01_min_price > temp02_min_price and flag == 1: if c == i-1: weight = 1 buy = data['close'][i] type = 'Divergence' find = True break if find: break if find: break if find: break """ # 매수전략 #3: stochastic + rsi + macd check = False if data['slow_k'][i - 1] < data['slow_k'][i] and data['slow_d'][i] < data['slow_k'][i]: # 과매도 체크 index = -1 for c in range(i - 40, i): if data['slow_k'][i] < 20: index = c check = True if check: # 과매도 후 과매수 였는지 체크 check = False for d in range(index, i): if 80 < data['slow_k'][d]: check = True break if not check: # 과매도 후 과매수가 아니라면 if data['rsi'][i - 1] < 50 and 50 < data['rsi'][i]: if data['macds'][i] < data['macd'][i] < 0: weight = 1 buy = data['close'][i] type = 'S+R+M' """ return buy, weight, type def getSellPriceAndWeight(self, i, data): sell, weight, type = -1, -1, "" max_value = max(data['macd'].tolist()) * 0.8 if (max_value < data['macd'][i] or 1.9 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): #if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]: weight = 1 sell = data['close'][i] type = 'method1' # 매수전략 #2: RSI 과매수에서 데드크로스 if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]): if 70 < data['rsi'][i]: weight = 1 sell = data['close'][i] type = 'method2' return sell, weight, type def checkTransaction(self, data, isRealTime=True): # 어제 오늘 데이터로 분석 bsLine = {} if data is not None and 'close' in data.columns: size = len(data["close"]) if isRealTime: # isRealTime=True, 실시간 적용 last_index = size - 1 buy, buy_weight, buy_type = self.getBuyPriceAndWeight(last_index, data) sell, sell_weight, sell_type = self.getSellPriceAndWeight(last_index, data) bsLine['buy'] = [buy] bsLine['buy_weight'] = [buy_weight] bsLine['buy_type'] = [buy_type] bsLine['sell'] = [sell] bsLine['sell_weight'] = [sell_weight] bsLine['sell_type'] = [sell_type] else: # Type=False, 시뮬레이션 적용 bsLine['buy'] = [-1 for i in range(size)] bsLine['buy_weight'] = [-1 for i in range(size)] bsLine['buy_type'] = ['' for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1 for i in range(size)] bsLine['sell_type'] = ['' for i in range(size)] for last_index in range(size): buy, buy_weight, buy_type = self.getBuyPriceAndWeight(last_index, data) sell, sell_weight, sell_type = self.getSellPriceAndWeight(last_index, data) bsLine['buy'][last_index] = buy bsLine['buy_weight'][last_index] = buy_weight bsLine['buy_type'][last_index] = buy_type bsLine['sell'][last_index] = sell bsLine['sell_weight'][last_index] = sell_weight bsLine['sell_type'][last_index] = sell_type else: bsLine['buy'] = [-1] bsLine['buy_weight'] = [-1] bsLine['buy_type'] = [''] bsLine['sell'] = [-1] bsLine['sell_weight'] = [-1] bsLine['sell_type'] = [''] return bsLine def analyze(self, result): # 기본 캔들 정보 open = result["open"] close = result["close"] high = result["high"] low = result["low"] vol = result["vol"] # 이동 평균 close_df = pd.DataFrame(close) avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() avg5 = [item[0] for item in avg5_list] avg20_list = close_df.rolling(window=20).mean().fillna(close[0]).values.tolist() avg20 = [item[0] for item in avg20_list] avg30_list = close_df.rolling(window=30).mean().fillna(close[0]).values.tolist() avg30 = [item[0] for item in avg30_list] avg60_list = close_df.rolling(window=60).mean().fillna(close[0]).values.tolist() avg60 = [item[0] for item in avg60_list] avg120_list = close_df.rolling(window=120).mean().fillna(close[0]).values.tolist() avg120 = [item[0] for item in avg120_list] avg200_list = close_df.rolling(window=200).mean().fillna(close[0]).values.tolist() avg200 = [item[0] for item in avg200_list] open_df = pd.DataFrame(close) disparity_avg5_list = (open_df / close_df.rolling(window=5).mean()).values.tolist() disparity_avg5 = [item[0] for item in disparity_avg5_list] disparity_avg20_list = (open_df / close_df.rolling(window=20).mean()).values.tolist() disparity_avg20 = [item[0] for item in disparity_avg20_list] disparity_avg30_list = (open_df / close_df.rolling(window=30).mean()).values.tolist() disparity_avg30 = [item[0] for item in disparity_avg30_list] disparity_avg60_list = (open_df / close_df.rolling(window=60).mean()).values.tolist() disparity_avg60 = [item[0] for item in disparity_avg60_list] disparity_avg120_list = (open_df / close_df.rolling(window=120).mean()).values.tolist() disparity_avg120 = [item[0] for item in disparity_avg120_list] disparity_avg200_list = (open_df / close_df.rolling(window=200).mean()).values.tolist() disparity_avg200 = [item[0] for item in disparity_avg200_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], 'avg5': avg5[i], 'avg20': avg20[i], 'avg30': avg30[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg200': avg200[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_df = self.macd.apply(STOCK, short=5, long=20, t=5) 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() laggingSpan = ichimokuCloud_df['laggingSpan'].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, "avg5": avg5, "avg20": avg20, "avg30": avg30, "avg60": avg60, "avg120": avg120, "avg200": avg200, "disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20, "disparity_avg30": disparity_avg30, "disparity_avg60": disparity_avg60, "disparity_avg120": disparity_avg120, "disparity_avg200": disparity_avg200, "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, "laggingSpan": laggingSpan, "leadingSpan1": leadingSpan1, "leadingSpan2": leadingSpan2, } data = pd.DataFrame(temp) df_final_time = pd.DatetimeIndex(point_temp) data.index = df_final_time data = data.fillna(-1) return data