import pandas as pd from datetime import datetime 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 isYangbong(self, data, i): if data['close'][i] > data['open'][i]: return True else: if data['low'][i] < data['close'][i] == data['open'][i] == data['high'][i]: return True if data['low'][i] < data['open'][i] == data['close'][i] < data['high'][i]: return True return False def isUmbong(self, data, i): if data['close'][i] < data['open'][i]: return True else: if data['low'][i] == data['close'][i] == data['open'][i] < data['high'][i]: return True if data['low'][i] < data['open'][i] == data['close'][i] < data['high'][i]: return True return False # 지난 1시간 30분 동안 12분 선이 20분 선위에 20분 이상 있었는지 체크 def check_12_over_20_for_30(self, data, i, default=90): if i - default < 381: return False check_12_over_20_for_30 = False for c in range(i - default, i - 20): if data['avg20'][c] < data['avg20'][i]: value = [1 if data['avg20'][d] < data['avg12'][d] else 0 for d in range(c, c + 20)] if len(value) == 20 and sum(value) == 20: check_12_over_20_for_30 = True break return check_12_over_20_for_30 # 지난 1시간 동안 3, 6, 9, 12분 선이 10분 이상 20분 선 아래 있었는지 체크 def check_under_20_for_10(self, data, i, within=60, during=10): if i - within < 381: return False check_under_20_for_10 = False for c in range(i - within, i - during): value = [ 1 if max(data['avg3'][d], data['avg6'][d], data['avg9'][d], data['avg12'][d]) < data['avg20'][d] else 0 for d in range(c, c + during)] if len(value) == during and sum(value) == during: check_under_20_for_10 = True break return check_under_20_for_10 def max_min_avg(self, data, i): return max(data['avg3'][i], data['avg6'][i], data['avg9'][i], data['avg12'][i], data['avg20'][i]) - min( data['avg3'][i], data['avg6'][i], data['avg9'][i], data['avg12'][i], data['avg20'][i]) def check_inverse_arrangement_before(self, data, i, within=30, during=5): if i - within < 381: return False inverse_arrangement = False for c in range(i - within, i - during): value = [ 1 if data['avg3'][d] < data['avg6'][d] < data['avg9'][d] < data['avg12'][d] < data['avg20'][d] else 0 for d in range(c, c + during)] if len(value) == during and sum(value) == during - 1: inverse_arrangement = True break return inverse_arrangement def checkUpDirection(self, data, i): # 0: 무추세, -1: 하락 추세, 1: 상승 추세 close = data['close'][i] # up_count = sum([1 if data['high'][c] < close else 0 for c in range(i-20, i)]) # down_count = sum([1 if close < data['low'][c] else 0 for c in range(i - 20, i)]) lagging_change = sum([1 if data['laggingSpan'][c] < data['changeLine'][c] else 0 for c in range(i - 20, i)]) change_lagging = sum([1 if data['laggingSpan'][c] > data['changeLine'][c] else 0 for c in range(i - 20, i)]) if lagging_change > 10: return 1 if change_lagging == 20: return -1 return 0 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_122630(self, i, data): buy, weight = -1, -1 if 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 getBuyPriceAndWeight_252670(self, i, data): buy, weight = -1, -1 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 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['close'][i] < data['avg200'][i] or data['avg200'][i] + 10 < data['close'][i]: buy, weight = -1, -1 if 2 < data['macd'][i]: buy, weight = -1, -1 return buy, weight def getSellPriceAndWeight(self, i, data): sell, weight = -1, -1 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 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 = 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 def checkTransaction(self, stock_code, data, data_5=None, data_30=None, isRealTime=True): # 어제 오늘 데이터로 분석 bsLine = {stock_code: {}} size = len(data["close"]) if isRealTime: # 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) 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: sell, weight = -1, -1 if 'last' in bsLine[stock_code] and bsLine[stock_code]['last'] != 'buy': sell, weight = -1, -1 bsLine[stock_code]['buy'] = [buy] bsLine[stock_code]['buy_weight'] = [buy_weight] bsLine[stock_code]['sell'] = [sell] bsLine[stock_code]['sell_weight'] = [sell_weight] if buy > 0: bsLine[stock_code]['last'] = 'buy' bsLine[stock_code]['last_buy'] = buy if sell > 0: bsLine[stock_code]['last'] = 'sell' else: # Type=False, 시뮬레이션 적용 bsLine[stock_code]['buy'] = [-1 for i in range(size)] 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): 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[stock_code]: if bsLine[stock_code]['last'] == 'buy': if sell - bsLine[stock_code]['last_buy'] < 0.007: sell, weight = -1, -1 else: 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 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 def checkTransactionML(self, data, stock_code, predY, isRealTime=True): # 4일치 중에서 앞에 2일은 제거한다. date = data['date'].dt.date.unique().tolist() data = data[data['date'].dt.date != date[0]] data = data[data['date'].dt.date != date[1]] # 어제 오늘 데이터로 분석 bsLine = {} size = len(data["close"]) if isRealTime: # isRealTime=True, 실시간 적용 last_index = size - 1 # Type=False, 시뮬레이션 적용 bsLine['buy'] = [-1 for i in range(size)] 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)] sell, sell_weight, buy, buy_weight = -1, -1, -1, -1 if predY[last_index] == 1: sell = int((data["open"][last_index] + data["close"][last_index]) / 2) sell_weight = 1 elif predY[last_index] == 2: buy = int((data["open"][last_index] + data["close"][last_index]) / 2) buy_weight = 1 bsLine['buy'] = [buy] bsLine['buy_weight'] = [buy_weight] bsLine['sell'] = [sell] bsLine['sell_weight'] = [sell_weight] else: # Type=False, 시뮬레이션 적용 bsLine['buy'] = [-1 for i in range(size)] 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)] for i in range(size): if predY[i] == 1: bsLine['sell'][i] = int((data["open"][i] + data["close"][i]) / 2) bsLine['sell_weight'][i] = 1 elif predY[i] == 2: bsLine['buy'][i] = int((data["open"][i] + data["close"][i]) / 2) bsLine['buy_weight'][i] = 1 return bsLine, data # middle line에 맞다은 적 없이, low line에 붙었거나 아래에 있었던 캔들의 높은 가격을 얻어옴 def getPrice_UnderLowWithoutMiddle(self, last_index, data): if data['high'][last_index] < data['envelope_middle'][last_index]: for i in range(last_index - 1, 0, -1): if data['high'][i] > data['envelope_middle'][i]: return -1, -1 if data['low'][i] < data['envelope_lower'][i]: return i, max(data['open'][i], data['close'][i]) return -1, -1 def getBuyPriceAndWeight_Envelope(self, i, data): buy, weight = -1, -1 """ # middle line에 맞다은 적 없이, low line에 붙었거나 아래에 있었던 캔들의 높은 가격을 얻어옴 index, price = self.getPrice_UnderLowWithoutMiddle(i, data) if price > -1: # 해당 가격보다 높은 가격이면 매수한다 if price < data['close'][i]: buy = data['close'][i] weight = 10 """ if i > 100: if -0.004 < data['gradient1'][i] < 0.001: # if data['high'][i] < data['envelope_middle'][i]: if data['slow_k'][i] < 20: buy = data['close'][i] weight = 10 """ if i > 100: if min(data['gradient1'][i-5:i]) < -0.009 and -0.009 < data['gradient1'][i]: if data['high'][i] < data['envelope_middle'][i]: buy = data['close'][i] weight = 10 """ return buy, weight def getSellPriceAndWeight_Envelope(self, data, i): sell, weight, type = -1, -1, -1 if data.index[i].strftime("%Y.%m.%d") == "2022.12.01": print(1) # upper lined에서 처리 if data['close'][i - 1] < data['envelope_upper'][i - 1] and data['envelope_upper'][i] < data['close'][i]: if data['slow_d'][i - 1] <= data['slow_k'][i - 1] and data['slow_k'][i] <= data['slow_d'][i]: sell = data["close"][i] weight = 1 type = 1 if data['envelope_upper'][i - 1] < data['close'][i - 1] and data['envelope_upper'][i] < data['close'][i]: if data['slow_d'][i - 1] <= data['slow_k'][i - 1] and data['slow_k'][i] <= data['slow_d'][i]: sell = data["close"][i] weight = 1 type = 2 if data['envelope_upper'][i - 1] < data['close'][i - 1] and data['envelope_upper'][i] < data['close'][i]: if data['slow_d'][i - 1] + 2 <= data['slow_k'][i - 1] and data['slow_d'][i] + 1 == data['slow_k'][i]: sell = data["close"][i] weight = 1 type = 3 if data['envelope_upper'][i] < data['high'][i] and data['open'][i] < data['close'][i]: if data['close'][i] - data['open'][i] < data['high'][i] - data['close'][i]: sell = data["close"][i] weight = 1 type = 4 return sell, weight, type # 팔아야 할 시점을 체크하기 위함 # 이전에 산 가격보다 지금 5원이상 떨어졌다면 매도 한다. def checkBelow5WonFromPreviousBuyPrice(self, last_index, data, price): for i in range(last_index - 1, 0, -1): if data['sell'][i] != -1: return False if data['buy'][i] != -1: if data['buy'][i] - price > 5: return True return def checkWithEnvelope_252670(self, data, isRealTime=False): bsLine = {} size = len(data["close"]) bsLine['buy'] = [-1 for i in range(size)] bsLine['buy_weight'] = [-1.0 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1.0 for i in range(size)] for i in range(size): if isRealTime: if i < size - 1: continue """ # 이전에 산 가격보다 지금 5원이상 떨어졌다면 매도 한다. price = data['close'][i] if data['close'][i] >= data['open'][i] else data['open'][i] if self.checkBelow5WonFromPreviousBuyPrice(i, data, price): data['sell'][i] = price bsLine['sell'][i] = price bsLine['sell_weight'][i] = 50 return bsLine, data """ """ # middle line에 맞다은 적 없이, low line에 붙었거나 아래에 있었던 캔들의 높은 가격을 얻어옴 buy, buy_weight = self.getBuyPriceAndWeight_Envelope(i, data) data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = buy_weight return bsLine, data """ if 0 < data['gradients_avg60'][i] < 0.001: if data['high'][i] < data['envelope_middle'][i]: if -0.015 < data['gradients_avg5'][i] and -0.007 < data['gradients_avg20'][i]: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 20.0 if i > 10: if ( data['gradients_avg60'][i - 10] > 0 and data['gradients_avg60'][i - 9] > 0 and data['gradients_avg60'][i - 8] > 0 and data['gradients_avg60'][i - 7] > 0 and data['gradients_avg60'][i - 6] > 0 and data['gradients_avg60'][i - 5] > 0 and data['gradients_avg60'][i - 4] > 0 and data['gradients_avg60'][i - 3] > 0 and data['gradients_avg60'][i - 2] > 0 and data['gradients_avg60'][i - 1] > 0 and data['gradients_avg60'][i] < 0 ): if data['disparity'][i] < 3: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 20.0 if data['disparity_avg60'][i] < 65: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 15.0 if data['slow_k'][i] < 3: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 10.0 if not (data['avg120'][i - 1] < data['avg60'][i - 1] < data['avg20'][i - 1] < data['avg5'][i - 1]) and (data['avg120'][i] < data['avg60'][i] < data['avg20'][i] < data['avg5'][i]): buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 20.0 return bsLine, data def checkWithEnvelope_122630(self, data, isRealTime=False): bsLine = {} size = len(data["close"]) bsLine['buy'] = [-1 for i in range(size)] bsLine['buy_weight'] = [-1.0 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1.0 for i in range(size)] for i in range(size): if isRealTime: if i < size - 1: continue if i > 10: if data['disparity_avg60'][i] < 60: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 20.0 if data['macd'][i] < -1000: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 20.0 if data['slow_k'][i] < 7: if data['slow_d'][i] < data['slow_k'][i]: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 10.0 if not (data['avg120'][i - 1] < data['avg60'][i - 1] < data['avg20'][i - 1] < data['avg5'][i - 1]) and (data['avg120'][i] < data['avg60'][i] < data['avg20'][i] < data['avg5'][i]): buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 25.0 return bsLine, data def notBuy(self, data, i): if i > 5: check = True for l in range(i - 4, i + 1): if ( data['gradients_avg60'][l - 1] > data['gradients_avg60'][l] or data['gradients_avg20'][l - 1] > data['gradients_avg20'][l] or data['gradients_low'][l - 1] > data['gradients_low'][l] ): check = False break if not check: return False return True def checkWithEnvelope(self, data, analyzed_day=120, isRealTime=False): bsLine = {} size = len(data["close"]) bsLine['buy'] = [-1 for i in range(size)] bsLine['buy_weight'] = [-1.0 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1.0 for i in range(size)] gap_interval = analyzed_day gap_state = False for i in range(size): if isRealTime: if i < size - 1: continue if i > 10: # 만약 전일 저가와 오늘 종의 차이가 1만원이 넘으면 향후 60일은 분석하지 않는다. if data['high'][i] < int(data['low'][i - 1] * 0.7): gap_state = True gap_interval -= 1 continue if gap_state: if gap_interval <= 0: gap_state = False gap_interval = 60 else: gap_interval -= 1 continue if data['disparity'][i] < 2: check = True for l in range(i - 3, i): if ( data['gradients_avg60'][l - 1] > data['gradients_avg60'][l] or data['gradients_avg20'][l - 1] > data['gradients_avg20'][l] or data['gradients_low'][l - 1] > data['gradients_low'][l] or data['disparity_avg5'][l - 1] > data['disparity_avg5'][l] or data['disparity'][l - 1] < data['disparity'][l] ): check = False break if check and 99 < sum(data['disparity_avg5'][i - 4:i + 1]) / 5 < 100 and 99 < sum(data['disparity_avg60'][i - 4:i + 1]) / 5 < 100: if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 3.0 check = True for l in range(i - 2, i): if (data['gradients_avg60'][l - 1] > data['gradients_avg60'][l] or data['gradients_low'][l - 1] > data['gradients_low'][l]): check = False break if ( check and -0.0011 < data['gradients_low'][i] < 0 and -0.007 < data['gradients_avg5'][i] < 0.001 and -0.0012 < data['gradients_avg60'][i] < 0 and 98.90 < data['disparity_avg5'][i] < 101 ): if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 check = True for l in range(i - 6, i): if ( data['gradients_avg60'][l - 1] < data['gradients_avg60'][l] or data['gradients_avg20'][l - 1] < data['gradients_avg20'][l] or data['gradients_low'][l - 1] < data['gradients_low'][l] or -0.039 < data['gradients_low'][l - 1] < -0.35 or -0.05 < data['gradients_avg20'][l - 1] < -0.30 or -0.40 < data['gradients_avg60'][l - 1] < -0.30 ): check = False break if check and 99 < min(data['disparity_avg5'][i - 6:i]) < max(data['disparity_avg5'][i - 6:i]) < 101: if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 """ check = True for l in range(i - 3, i): if ( data['gradients_low'][l - 1] < data['gradients_low'][l] or data['gradients_avg60'][l - 1] < data['gradients_avg60'][l] or data['gradients_avg20'][l - 1] < data['gradients_avg20'][l] or 0.01 < data['gradients_low'][l - 1] < 0.21 or -0.09 < data['gradients_avg20'][l - 1] < -0.002 or 0.01 < data['gradients_avg60'][l - 1] < 0.021 ): check = False break if check: if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 """ if (data['disparity'][i] < 5 and 99.0 < data['disparity_avg60'][i] < 99.1 and -0.009 < data['gradients_avg60'][i] < -0.008 and 0.015 < data['gradients_avg20'][i] < 0.016 and -0.006 < data['gradients_avg5'][i] < -0.005 and -0.009 < data['gradients_low'][i] < -0.008): check = True for l in range(i - 5, i): if ( data['gradients_avg60'][l - 1] > data['gradients_avg60'][l] or data['gradients_low'][l - 1] > data['gradients_low'][l] or data['disparity'][l - 1] < data['disparity'][l] ): check = False break if check: if data['slow_k'][i] < 10: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 if data['macd'][i] < -4000: if data['macd'][i - 1] < data['macd'][i]: if not self.notBuy(data, i) and data['slow_k'][i] < 30: if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 # macd 이전에 없던 바닥인 경우 상승할 찰나 매수 if data['macds'][i - 1] < min(data['macds'][:i - 1]): if data['macds'][i - 1] < data['macds'][i]: if not self.notBuy(data, i) and data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 if ( 98 < data['disparity_avg5'][i] < 100 and data['disparity_avg20'][i] < 93.5 and data['disparity_avg60'][i] < 89 and -0.014 < data['gradients_avg60'][i] < -0.013 and -0.03 < data['gradients_avg20'][ i] < -0.02 and -0.014 < data['gradients_low'][i] < -0.013 and data['slow_k'][i] < 11 ): if not self.notBuy(data, i): if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 5.0 if data['slow_k'][i] < 20 and data['slow_k'][i - 1] < data['slow_d'][i - 1] and data['slow_d'][i] < data['slow_k'][i]: if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 7.0 if not (data['avg120'][i - 1] < data['avg60'][i - 1] < data['avg20'][i - 1] < data['avg5'][i - 1]) and (data['avg120'][i] < data['avg60'][i] < data['avg20'][i] < data['avg5'][i]): if data['slow_k'][i] < 30: buy = data['low'][i] data['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 10.0 if data['slow_k'][i] > 75: if (data['slow_d'][i-1] < data['slow_k'][i-1] and data['slow_k'][i] < data['slow_d'][i]): sell = data['close'][i] weight = 100 data['sell'][i] = sell bsLine['sell'][i] = sell bsLine['sell_weight'][i] = weight if data['slow_k'][i] > 85: if data['slow_k'][i] < data['slow_d'][i]: sell = data['close'][i] weight = 100 data['sell'][i] = sell bsLine['sell'][i] = sell bsLine['sell_weight'][i] = weight return bsLine, data def checkTransactionWithEnvelope(self, data, stock_code, analyzed_day, isRealTime=False): if isRealTime: if stock_code == "252670": bsLine, data = self.checkWithEnvelope_252670(data, isRealTime) elif stock_code == "122630": bsLine, data = self.checkWithEnvelope_122630(data, isRealTime) else: bsLine, data = self.checkWithEnvelope(data, analyzed_day, isRealTime) else: # 사야 할 시점과 팔아야 할 시점을 체크한다. if stock_code == "252670": bsLine, data = self.checkWithEnvelope_252670(data, isRealTime) elif stock_code == "122630": bsLine, data = self.checkWithEnvelope_122630(data, isRealTime) else: bsLine, data = self.checkWithEnvelope(data, analyzed_day, isRealTime) return bsLine, data