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 ichimokuCloud = None def __init__(self): self.common = Common() self.stochastic = Stochastic() self.rsi = RSI() self.macd = MACD() self.ichimokuCloud = IchimokuCloud() return def getPriceAndWeight1(self, data, i): buy, weight, sell = -1, -1, -1 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: ################ ### sell 분석 ### ################ # 1. 볼린져밴드 상단이 최고와 종가 사이 아래에 있는 경우 매도한다. #if (hts["high"][i] - hts["close"][i]) / 2 + hts["close"][i] > hts["upper"][i]: # sell = hts["high"][i] # 2. slow_k가 90이 넘으면 매도한다. if data["slow_k"][i] > 90: sell = data["high"][i] #if hts["slow_k"][i] >= 85: # if hts["slow_d"][i-1] < hts["slow_k"][i-1] and hts["slow_k"][i] < hts["slow_d"][i]: # sell = hts["high"][i] # 3. 2시 이후에는 최고가가 볼린져밴드 상단 위에 있으면 매도한다. if i > 300 and data["high"][i] > data["upper"][i]: sell = data["high"][i] ########################## ### buy 분석 ### ########################## if data["low"][i] < data["lower"][i] + 5 and data["open"][i] <= data["close"][i]: if data["slow_k"][i-1] < 30 and data["slow_k"][i] < 30: if data["slow_k"][i-1] < data["slow_k"][i]: buy = data["low"][i] if data["rsi"][i] < 25: if data["rsi"][i - 2] < data["rsis"][i - 2] and data["rsi"][i - 1] < data["rsis"][i - 1] and data["rsis"][i] < data["rsi"][i]: if data["close"][i] < data["avg5"][i]: buy = data["close"][i] else: buy = data["low"][i] weight = 1 ############################# ### STOCHASTIC weight 분석 ### ############################# if data["slow_k"][i] in (0, 1, 2, 3): weight = 1 if data["slow_k"][i] in (4, 5, 6, 7, 8): weight = 1 elif data["slow_k"][i] in (9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20): weight = 1 elif data["slow_k"][i] in (21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35): weight = 1 return buy, weight, sell def getPriceAndWeight2(self, data, i): buy, weight, sell = -1, -1, -1 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: ################ ### sell 분석 ### ################ # 1. 볼린져밴드 상단이 최고와 종가 사이 아래에 있는 경우 매도한다. if (data["high"][i] - data["close"][i]) / 2 + data["close"][i] > data["upper"][i]: sell = data["high"][i] if data["slow_k"][i] >= 85: if data["slow_d"][i - 1] < data["slow_k"][i - 1] and data["slow_k"][i] < data["slow_d"][i]: sell = data["high"][i] # 3. 2시 이후에는 최고가가 볼린져밴드 상단 위에 있으면 매도한다. if i > 300 and data["high"][i] > data["upper"][i]: sell = data["high"][i] ########################## ### STOCHASTIC buy 분석 ### ########################## if i < 40: pre_slow = data["slow_k"][i - 1] / data["slow_d"][i - 1] - 1 now_slow = data["slow_k"][i] / data["slow_d"][i] - 1 if pre_slow < 0 and 0 < now_slow: if data["slow_k"][i] <= 35: if (data["close"][i] - data["lower"][i]) / (data["upper"][i] - data["lower"][i]) < 0.35: if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]: if data['avg10'][i] < data['avg5'][i]: if data["open"][i] < data["close"][i]: buy = data["close"][i] else: buy = data["low"][i] else: pre_slow = data["slow_k"][i - 1] / data["slow_d"][i - 1] - 1 now_slow = data["slow_k"][i] / data["slow_d"][i] - 1 if pre_slow < 0 and pre_slow < now_slow and -0.15 < now_slow: if data["slow_k"][i] <= 30: if (data["close"][i] - data["lower"][i]) / (data["upper"][i] - data["lower"][i]) < 0.35: if data["slow_k"][i - 1] < data["slow_d"][i - 1] and data["slow_d"][i] < data["slow_k"][i]: if data['avg10'][i] < data['avg5'][i]: if data["close"][i] < data["avg5"][i]: buy = data["close"][i] else: buy = data["low"][i] ############################# ### STOCHASTIC weight 분석 ### ############################# if data["slow_k"][i] in (0, 1, 2, 3): weight = 1 if data["slow_k"][i] in (4, 5, 6, 7, 8): weight = 1 elif data["slow_k"][i] in (9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20): weight = 1 elif data["slow_k"][i] in (21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35): weight = 1 return buy, weight, sell def getBuyCheck(self, data, i, buy, weight): if data['close'][i]40: buy, weight, sell = -1, -1, -1 return buy, weight def isYangbong(self, data, i): if data['close'][i] > data['open'][i]: return True if data['close'][i] == data['open'][i]: if data['low'][i] < data['close'][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 if data['close'][i] == data['open'][i]: if data['close'][i] == data['low'][i] < data['high'][i]: return True if data['low'][i] < data['open'][i] == data['close'][i] < data['high'][i]: return True return False # 곱버스에 해당함 def getBuyPriceAndWeight_3000(self, data, i): buy, weight = -1, -1 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: # 매수 분석 if i > 740: # "15:00" 까지만 매수 return buy, weight # 중위선 20분선 아래에서 볼린져 상단을 뚫고 종료할 때 # (2022-07-06 11:17) (2022-07-07 14:29) (2022-07-08 12:41 12:44) (2022-07-11 13:58) # (2022-07-13 12:02 12:03) (2022-07-14 10:50) (2022-07-15 09:52) if data["open"][i] < data["avg10"][i] < data["avg20"][i] < data["avg30"][i] < data["close"][i]: if data["avg20"][i - 2] <= data["avg20"][i - 1] <= data["avg20"][i]: buy = int((data["close"][i] + data["low"][i])/2) weight = 2 return self.getBuyCheck(data, i, buy, weight) # 30일 이전부터 모든 선이 좁혀졌다 녋혀지면서 다시 상승하며 좁혀짐 # (2022-07-08 10:52), (2022-07-14 14:33 14:36) if max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]) - min( data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]) < 5: if (data["close"][i] > (data["avg3"][i] and data["avg5"][i] and data["avg10"][i] and data["avg20"][i] and data["avg30"][i])): if data["close"][i] > data["open"][i]: check1 = False check2 = False for c in range(30, 0, -1): if not check1 and not check2: if max(data["avg3"][i-c], data["avg5"][i-c], data["avg10"][i-c], data["avg20"][i-c], data["avg30"][i-c]) - min(data["avg3"][i-c], data["avg5"][i-c], data["avg10"][i-c], data["avg20"][i-c], data["avg30"][i-c]) < 2: check1 = True continue if check1 and not check2: if max(data["avg3"][i-c], data["avg5"][i-c], data["avg10"][i-c], data["avg20"][i-c], data["avg30"][i-c]) - min(data["avg3"][i-c], data["avg5"][i-c], data["avg10"][i-c], data["avg20"][i-c], data["avg30"][i-c]) > 10: if data["avg20"][i-c] < data["avg10"][i-c] < data["avg5"][i-c] < data["avg3"][i-c]: check2 = True break if check1 and check2: buy = int((data["close"][i] + data["low"][i]) / 2) weight = 7 return buy, weight # 최근 양봉 3개가 나오면, # 최근 10개 중에서 9개가 음봉이었음. 이 상태에서 양봉 3개가 나오면, 중간값에서 매수한다. # (2022-07-05 09:22 11:01 11:14) (2022-07-05 09:56 12:47) # (2022-07-06 14:25) (2022-07-07 09:50 11:29 11:52 12:23 12:50) (2022-07-08 09:06 10:05 10:49 11:35 14:14) (2022-07-11 09:25 09:59 11:54) # (2022-07-12 10:37 12:49 14:52) (2022-07-13 09:06 09:13 10:12 12:30) (2022-07-14 11:16 13:50) (2022-07-15 11:39) if data["open"][i-2] < data["close"][i-2] and data["open"][i-1] <= data["close"][i-1] and data["open"][i] < data["close"][i]: umbong = 0 for c in range(13, 3, -1): if data['close'][i-c] <= data['open'][i-c]: umbong += 1 if umbong >= 8: if data["open"][i] < data["open"][i-10]: buy = data["open"][i] weight = 7 return self.getBuyCheck(data, i, buy, weight) # 최근 양봉 3개가 나오면, # 9시 3분이나 4분에 장 시작 양봉 연속 3개면 매수 # (2022-07-11 09:03), (2022-07-14 14:33 14:36) if data.index[i].strftime("%H:%M") == "09:03": if data["low"][i - 2] <= data["open"][i - 2] < data["close"][i - 2] <= data["high"][i - 2]: if data["low"][i - 1] <= data["open"][i - 1] < data["close"][i - 1] <= data["high"][i - 1]: if data["low"][i] <= data["open"][i] < data["close"][i] <= data["high"][i]: buy = data["high"][i] + 5 weight = 5 return buy, weight # 장시작 5개 high가 볼린져 상단 위에 있을 때 중간 값에서 매수 if data.index[i].strftime("%H:%M") == "09:05": if data["upper"][i-4] < data["high"][i-4] and data["upper"][i-3] < data["high"][i-3] and data["upper"][i-2] < data["high"][i-2] and data["upper"][i-1] < data["high"][i-1] and data["upper"][i] < data["high"][i]: buy = (data["open"][i]+data["close"][i])/2 weight = 5 return self.getBuyCheck(data, i, buy, weight) # 장 초기 (시작 9분 이내), 볼린져 하단에서 시작하여 이병선을 모두 상승하여 마감한 경우 high 값에서 매수한다. # (2022-07-15 09:08 09:09) if i <= 381 + 10: if data["close"][i] > max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]): c = 382 # 장 시작 역배열 상태임 if data["avg3"][c] < data["avg5"][c] < data["avg10"][c] < data["avg20"][c] < data["avg30"][c] and data["close"][c] < data["lower"][c]: if data["upper"][i] < data["high"][i]: buy = data["close"][i] else: buy = data["high"][i] weight = 7 return buy, weight # 이동선을 이용한 매매 # 3분선과 10분선이 30분 이상 내려오다가 3분선이 10분선을 넘어 서는 순간 매수 # (2022-07-07 11:26) (2022-07-08 10:05) if int(data["avg3"][i]) > int(data["avg10"][i]): valid = True same_count = 0 for c in range(1, 30): if int(data["avg3"][i-c]) == int(data["avg10"][i-c]): same_count += 1 if int(data["avg3"][i-c]) > int(data["avg10"][i-c]): valid = False break if valid and same_count < 2: buy = data["close"][i] - 5 weight = 3 return self.getBuyCheck(data, i, buy, weight) # MACD를 이용한 다이버젼스 # lower를 하단으로 깼을 때, 5분선 기준으로 이전 저점보다 낮거나 같은데, MACD는 더 높은 경우 매수한다. # 오전 10시 이후일 때만 해당함 if data["close"][i] < data["lower"][i]: if data['macd'][i] < -2: low = 99999999999 high = 0 idx = 0 for c in range(30, 60): if i-c > 381: if data['macd'][i-c] < -2 and data['low'][i-c] < low: low = data['low'][i-c] idx = i-c for c in range(i-1, idx, -1): if high < data['high'][c]: high = data['high'][c] if data['macd'][idx] < data['macd'][i] and data['low'][i] <= data['low'][idx] and high-data['high'][i] > 20: buy = (data["open"][i]+data["close"][i])/2 weight = 7 return self.getBuyCheck(data, i, buy, weight) # 10분선이 30분 이상 20분선 아래에 있다가 20분선 위로 올라옴 # 이때 3, 5, 10, 20분선의 max-min이 5원 미만이다. if i > 381 + 20: vaild = True max_price = 0 if i > 381 + 30: last = 30 else: last = i - 381 for c in range(4, last): if data["avg10"][i - c] >= data["avg20"][i - c]: vaild = False if max_price < data["high"][i - c]: max_price = data["high"][i - c] if vaild: if ((data["avg10"][i-3] > data["avg20"][i-3] and data["avg10"][i-2] > data["avg20"][i-2] and data["avg10"][i-1] > data["avg20"][i-1] and data["avg10"][i] > data["avg20"][i]) or (abs(data["avg10"][i-3] - data["avg20"][i-3]) < 2 and abs(data["avg10"][i-2] - data["avg20"][i-2]) < 2 and abs(data["avg10"][i-1] - data["avg20"][i-1]) < 2 and abs(data["avg10"][i] - data["avg20"][i])<2)) : if max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i]) - min(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i]) <= 5: if max_price - data["close"][i] >= 30: buy = data["high"][i] weight = 10 return self.getBuyCheck(data, i, buy, weight) """ # 이동선을 이용한 매매 # 20분선이 30분선에 돌파 후 지지하는지 확인하고 해당 시점이 양봉이면 매수함 if hts['avg20'][i] > hts['avg30'][i]: diff1 = hts['avg20'][i] - hts['avg30'][i] diff2 = hts['avg20'][i-1] - hts['avg30'][i-1] diff3 = hts['avg20'][i-2] - hts['avg30'][i-2] diff4 = hts['avg20'][i-3] - hts['avg30'][i-3] diff5 = hts['avg20'][i-4] - hts['avg30'][i-4] if 0 < diff3 < diff2 < diff1: if hts['high'][i-2] <= hts['high'][i-1] <= hts['high'][i]: if hts['open'][i - 2] <= hts['close'][i - 2] and hts['open'][i-1] <= hts['close'][i-1] and hts['open'][i] <= hts['close'][i]: if diff5 < diff4 < 0: if hts["rsi"][i] < 30: buy = (hts["open"][i]+hts["close"][i])/2 weight = 7 return self.getBuyCheck(hts, i, buy, weight) # 이동선을 이용한 매매 # 3분선과 5분선이 10분 이상 내려오다가 3분선이 5분선을 넘어 서는 순간 매수 # (2022-07-04 09:22) (2022-07-05 09:38) (2022-07-07 09:35) (2022-07-08 09:06) (2022-07-11 09:25) (2022-07-13 10:12) (2022-07-15 14:48) if int(hts["avg3"][i]) > int(hts["avg5"][i]): valid = True same_count = 0 for c in range(1, 11): if int(hts["avg3"][i-c]) == int(hts["avg5"][i-c]): same_count += 1 if int(hts["avg3"][i-c]) > int(hts["avg5"][i-c]): valid = False break if valid and same_count < 2: if hts['macd'][i] < -5: buy = hts["close"][i] - 5 weight = 1 return self.getBuyCheck(hts, i, buy, weight) # 만약 30원 이상 장대 양봉이 나온 경우, 다음이나 다다음 중간 값에서 매수를 한다. if (hts["close"][i] - hts["low"][i]) >= 30: middle = int((hts["close"][i] + hts["low"][i])/2) buy = middle weight = 1 return self.getBuyCheck(hts, i, buy, weight) """ return buy, weight def getSellPriceAndWeight_3000(self, data, i): sell, weight = -1, -1 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분 선이 40분 전부터 게속 20분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg20"][i]: valid = True for c in range(1, 41): if data["avg3"][i-c] < data["avg20"][i-c]: valid = False break if valid: sell = int((data["open"][i] + data["close"][i])/2) return sell, weight # 3분 선이 60분 전부터 게속 30분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg30"][i]: valid = True for c in range(1, 61): if data["avg3"][i-c] < data["avg30"][i-c]: valid = False break if valid: sell = int((data["open"][i] + data["close"][i])/2) return sell, weight # rsi와 rsis가 75이상에서 slow_k가 slow_d 아래롸 내려온 경우 if data["rsi"][i] >= 70 and data["rsis"][i] >= 70: if data["rsi"][i-1] > data["rsis"][i-1] and data["rsi"][i] < data["rsis"][i]: sell = int((data["open"][i] + data["close"][i]) / 2) return sell, weight # slow_k와 slow_d가 90이상에서 slow_k가 slow_d 아래롸 내려온 경우 if data["slow_k"][i] >= 90 and data["slow_d"][i] >= 90: if data["slow_k"][i-1] > data["slow_d"][i-1] and data["slow_k"][i] < data["slow_d"][i]: if data["avg3"][i] < data["avg5"][i]: sell = int((data["open"][i] + data["close"][i]) / 2) if data.index[i].strftime("%H:%M") < "12:00" and data['rsis'][i] < 70: return -1, -1 return sell, weight # 양봉 5개 이후 음봉이 나온 경우 if ((data["low"][i-5] <= data["open"][i-5] <= data["close"][i-5] <= data["high"][i-5] and data["low"][i-4] <= data["open"][i-4] <= data["close"][i-4] <= data["high"][i-4] and data["low"][i-3] <= data["open"][i-3] <= data["close"][i-3] <= data["high"][i-3] and data["low"][i-2] <= data["open"][i-2] <= data["close"][i-2] <= data["high"][i-2] and data["low"][i-1] <= data["open"][i-1] <= data["close"][i-1] <= data["high"][i-1]) and data["high"][i-5] <= data["high"][i-4] <= data["high"][i-3] <= data["high"][i-2] <= data["high"][i-1]): if data["avg30"][i-1] < data["avg20"][i-1] < data["avg10"][i-1] < data["avg5"][i-1] < data["avg3"][i-1]: if data["close"][i] < data["open"][i] and data["low"][i] < data["low"][i-1]: if data["slow_k"][i] >= 95: sell = data["close"][i] weight = 1 return sell, weight if i > 381 + 15: # 볼린저를 돌파했거나 고가가 모든 선위에 있다가 3번 이상 음봉 맞은 경우 if ((data["high"][i-4] > data["upper"][i-4] or data["high"][i-4] > data["avg3"][i-4] > data["avg5"][i-4] > data["avg10"][i-4] > data["avg20"][i-4] > data["avg30"][i-4]) or (data["high"][i-3] > data["upper"][i-3] or data["high"][i-3] > data["avg3"][i-3] > data["avg5"][i-3] > data["avg10"][i-3] > data["avg20"][i-3] > data["avg30"][i-3])): if self.isUmbong(data, i-2) and self.isUmbong(data, i-1) and self.isUmbong(data, i): if data["slow_k"][i] >= 80: sell = data["low"][i] weight = 1 return sell, weight return sell, weight # 레버리지에 해당함 def getBuyPriceAndWeight_15000(self, data, i): buy, weight = -1, -1 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: # 매수 분석 if i > 740: # "15:00" 까지만 매수 return buy, weight # 30일 이전부터 모든 선이 좁혀졌다 녋혀지면서 다시 상승하며 좁혀짐 if max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]) - min(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i]) < 5: if data["avg3"][i - 1] < data["avg3"][i] and data["macd"][i] < 20: if (data["close"][i] > (data["avg3"][i] and data["avg5"][i] and data["avg10"][i] and data["avg20"][i] and data["avg30"][i])): if data["close"][i] > data["open"][i]: check1 = False check2 = False high = 0 for c in range(1, 30): if not check1 and not check2: if max(data["avg3"][i - c], data["avg5"][i - c], data["avg10"][i - c], data["avg20"][i - c], data["avg30"][i - c]) - min(data["avg3"][i - c], data["avg5"][i - c], data["avg10"][i - c], data["avg20"][i - c]) < 20: check1 = True if high < data['high'][i-c]: high = data['high'][i-c] continue if check1 and not check2: if max(data["avg3"][i - c], data["avg5"][i - c], data["avg10"][i - c], data["avg20"][i - c], data["avg30"][i - c]) - min(data["avg3"][i - c], data["avg5"][i - c], data["avg10"][i - c], data["avg20"][i - c], data["avg30"][i - c]) > 60: if data["avg20"][i - c] < data["avg10"][i - c] < data["avg5"][i - c] < data["avg3"][i - c]: check2 = True if high < data['high'][i - c]: high = data['high'][i - c] break if check1 and check2: if high - data["close"][i] >= 20: buy = int((data["close"][i] + data["low"][i]) / 2) weight = 1 return self.getBuyCheck(data, i, buy, weight) # 최근 양봉 3개가 나오면, # 최근 10개의 min(open, close)가 계속 낮아지거나 동일함 if data["low"][i - 2] <= data["open"][i - 2] < data["close"][i - 2] <= data["high"][i - 2]: if data["low"][i - 1] <= data["open"][i - 1] < data["close"][i - 1] <= data["high"][i - 1]: if data["low"][i] <= data["open"][i] <= data["close"][i] <= data["high"][i]: if data['close'][i-2]-data['open'][i-2] >= 20 or data['close'][i-1]-data['open'][i-1] >= 20 or data['close'][i]-data['open'][i] >= 20: if data['high'][i-7] > data['high'][i]: invalid = False for c in range(4, 8): if max(data['open'][i-c], data['close'][i-c]) > max(data['open'][i-c-1], data['close'][i-c-1]): invalid = True if not invalid: buy = data["close"][i] weight = 1 return self.getBuyCheck(data, i, buy, weight) # 최근 양봉 3개가 나오면, # 9시 3분이나 4분에 장 시작 양봉 연속 3개면 매수 # (2022-07-11 09:03), (2022-07-14 14:33 14:36) if data.index[i].strftime("%H:%M") == "09:03": if data["low"][i - 2] <= data["open"][i - 2] < data["close"][i - 2] <= data["high"][i - 2]: if data["low"][i - 1] <= data["open"][i - 1] < data["close"][i - 1] <= data["high"][i - 1]: if data["low"][i] <= data["open"][i] < data["close"][i] <= data["high"][i]: buy = data["high"][i] + 5 weight = 1 return self.getBuyCheck(data, i, buy, weight) # 최근 양봉 5개가 나오면, # 최근 10개의 min(open, close)가 계속 낮아지거나 동일함 if data["low"][i - 4] <= data["open"][i - 4] <= data["close"][i - 4] <= data["high"][i - 4]: if data["low"][i - 3] <= data["open"][i - 3] <= data["close"][i - 3] <= data["high"][i - 3]: if data["low"][i - 2] <= data["open"][i - 2] <= data["close"][i - 2] <= data["high"][i - 2]: if data["low"][i - 1] <= data["open"][i - 1] <= data["close"][i - 1] <= data["high"][i - 1]: if data["low"][i] <= data["open"][i] <= data["close"][i] <= data["high"][i]: down = 0 for c in range(5, 21): if max(data['open'][i-c], data['close'][i-c]) < max(data['open'][i-c-1], data['close'][i-c-1]): down += 1 if down >= 10: buy = data["close"][i] weight = 1 return self.getBuyCheck(data, i, buy, weight) # 장시작 5개 high가 볼린져 상단 위에 있을 때 중간 값에서 매수 if data.index[i].strftime("%H:%M") == "09:05": if data["upper"][i - 4] < data["high"][i - 4] and data["upper"][i - 3] < data["high"][i - 3] and \ data["upper"][i - 2] < data["high"][i - 2] and data["upper"][i - 1] < data["high"][i - 1] and \ data["upper"][i] < data["high"][i]: buy = int((data["open"][i] + data["close"][i]) / 2) weight = 1 return self.getBuyCheck(data, i, buy, weight) # 장 초기 (시작 9분 이내), 볼린져 하단에서 시작하여 이병선을 모두 상승하여 마감한 경우 high 값에서 매수한다. if i < 381 + 9: if data["close"][i] > max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]): c = 382 # 장 시작 역배열 상태임 if data["avg3"][c] < data["avg5"][c] < data["avg10"][c] < data["avg20"][c] < data["avg30"][c] and data["close"][c] < data["lower"][c]: if data["upper"][i] < data["high"][i]: buy = data["close"][i] else: buy = data["high"][i] weight = 1 return self.getBuyCheck(data, i, buy, weight) # 이동선을 이용한 매매 # 3분선과 10분선이 30분 이상 내려오다가 3분선이 10분선을 넘어 서는 순간 매수 # (2022-07-08 14:57) (2022-07-04 10:39) (2022-07-11 11:09) (2022-07-15 09:36) if i < 381 * 2 - 50: if int(data["avg3"][i]) > int(data["avg10"][i]): valid = True same_count = 0 for c in range(1, 30): if int(data["avg3"][i - c]) == int(data["avg10"][i - c]): same_count += 1 if int(data["avg3"][i - c]) > int(data["avg10"][i - c]): valid = False break if valid and same_count < 2: buy = data["close"][i] - 5 weight = 1 return self.getBuyCheck(data, i, buy, weight) # 음봉이 4개 이상 이후 이전 2개의 음봉 위로 올라오는 장대 양봉 if data["close"][i-4] < data["open"][i-4] and data["close"][i-3] < data["open"][i-3] and data["close"][i-2] < data["open"][i-2] and data["close"][i-1] < data["open"][i-1]: if data["close"][i-1] <= data["open"][i] and data["open"][i-2] <= data["close"][i]: if data["close"][i] - data["open"][i] >= 20: buy = data["close"][i] + 5 weight = 1 return self.getBuyCheck(data, i, buy, weight) # 30분 이내로 역배열에서 현재 정배열 시작 if i > 381 + 30: if max(data["avg3"][i-2], data["avg5"][i-2], data["avg10"][i-2], data["avg20"][i-2],data["avg30"][i-2]) - min(data["avg3"][i-2], data["avg5"][i-2], data["avg10"][i-2],data["avg20"][i-2]) < 7: if data["avg3"][i-2] > data["avg5"][i-2] > data["avg10"][i-2] > data["avg20"][i-2] > data["avg30"][i-2]: if data["avg3"][i] > data["avg5"][i] > data["avg10"][i] > data["avg20"][i] > data["avg30"][i]: for c in range(10, 38): if data["avg3"][i-c] < data["avg5"][i-c] < data["avg10"][i-c] < data["avg20"][i-c] < data["avg30"][i-c]: buy = data["close"][i] weight = 1 return self.getBuyCheck(data, i, buy, weight) if i > 381 + 18: # 최근 저점이 이전 저점보다 avg3는 크지만, rsi는 높은 경우 if data['avg3'][i-2] < data['avg3'][i-1] < data['avg3'][i]: if data['avg3'][i-2] < data['avg3'][i-3] < data['avg3'][i-4] < data['avg3'][i-5]: if data['open'][i-1] < data['close'][i-1] and data['open'][i] < data['close'][i]: if data['avg3'][i-1] < data['avg3'][i] and data['avg5'][i-1] < data['avg5'][i] and data['avg10'][i-1] < data['avg10'][i]: if data['close'][i] - data['open'][i] >= 10: if max(data["avg3"][i - 2], data["avg5"][i - 2], data["avg10"][i - 2],data["avg20"][i - 2], data["avg30"][i - 2]) - min(data["avg3"][i - 2], data["avg5"][i - 2], data["avg10"][i - 2], data["avg20"][i - 2]) > 15: idx = -1 value = 9999999999 for c in range(6, 18): if data['avg3'][i-c] < value: value = data['avg3'][i-c] idx = i-c if data['avg3'][idx] < data['avg3'][i-2] and data['rsi'][i-2] < data['rsi'][idx]: buy = data["high"][i] weight = 1 return self.getBuyCheck(data, i, buy, weight) if data['close'][i] - data['open'][i] >= 90 and data['close'][i] == data['high'][i]: buy = int((data["open"][i] + data["close"][i]) / 2) weight = 1 return buy, weight # 장 초기 (시작 9분 이내), 볼린져 하단에서 시작하여 이병선을 모두 상승하여 마감한 경우 high 값에서 매수한다. # (2022-07-15 09:08 09:09) if i <= 381 + 4: if data["close"][381] < min(data["lower"][381], data["avg3"][381], data["avg5"][381], data["avg10"][381], data["avg20"][381], data["avg30"][381]): for c in range(1, 4): if i-c < 382: break if data["close"][i-c] > max(data["upper"][i-c], data["avg3"][i-c], data["avg5"][i-c], data["avg10"][i-c], data["avg20"][i-c], data["avg30"][i-c]): buy = data["high"][i] weight = 3 return buy, weight return buy, weight def getSellPriceAndWeight_15000(self, data, i): sell, weight = -1, -1 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분 선이 40분 전부터 게속 20분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg20"][i]: valid = True for c in range(1, 41): if data["avg3"][i - c] < data["avg20"][i - c]: valid = False break if valid: sell = int((data["open"][i] + data["close"][i]) / 2) return sell, weight # 3분 선이 60분 전부터 게속 30분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg30"][i]: valid = True for c in range(1, 61): if data["avg3"][i - c] < data["avg30"][i - c]: valid = False break if valid: sell = int((data["open"][i] + data["close"][i]) / 2) return sell, weight # rsi와 rsis가 75이상에서 slow_k가 slow_d 아래롸 내려온 경우 if data["rsi"][i] >= 70 and data["rsis"][i] >= 70: if data["rsi"][i - 1] > data["rsis"][i - 1] and data["rsi"][i] < data["rsis"][i]: sell = int((data["open"][i] + data["close"][i]) / 2) return sell, weight # slow_k와 slow_d가 90이상에서 slow_k가 slow_d 아래롸 내려온 경우 if data["slow_k"][i] >= 90 and data["slow_d"][i] >= 90: if data["slow_k"][i - 1] > data["slow_d"][i - 1] and data["slow_k"][i] < data["slow_d"][i]: if data["avg3"][i] < data["avg5"][i]: sell = int((data["open"][i] + data["close"][i]) / 2) if data.index[i].strftime("%H:%M") < "12:00" and data['rsis'][i] < 70: return -1, -1 return sell, weight # 양봉 5개 이후 음봉이 나온 경우 if ((data["low"][i - 5] <= data["open"][i - 5] <= data["close"][i - 5] <= data["high"][i - 5] and data["low"][i - 4] <= data["open"][i - 4] <= data["close"][i - 4] <= data["high"][i - 4] and data["low"][i - 3] <= data["open"][i - 3] <= data["close"][i - 3] <= data["high"][i - 3] and data["low"][i - 2] <= data["open"][i - 2] <= data["close"][i - 2] <= data["high"][i - 2] and data["low"][i - 1] <= data["open"][i - 1] <= data["close"][i - 1] <= data["high"][i - 1]) and data["high"][i - 5] <= data["high"][i - 4] <= data["high"][i - 3] <= data["high"][i - 2] <= data["high"][i - 1]): if data["avg30"][i - 1] < data["avg20"][i - 1] < data["avg10"][i - 1] < data["avg5"][i - 1] < data["avg3"][i - 1]: if data["close"][i] < data["open"][i] and data["low"][i] < data["low"][i - 1]: if data["slow_k"][i] >= 95: sell = data["close"][i] weight = 1 return sell, weight if i > 381 + 15: # 볼린저를 돌파했거나 고가가 모든 선위에 있다가 3번 이상 음봉 맞은 경우 if (data["high"][i - 3] > data["upper"][i - 3] or data["high"][i - 3] > data["avg3"][i - 3] > data["avg5"][i - 3] > data["avg10"][i - 3] > data["avg20"][i - 3] > data["avg30"][i - 3]): if data["close"][i - 2] < data["open"][i - 2] and data["close"][i - 1] < data["open"][i - 1] and data["close"][i] < data["open"][i]: sell = data["low"][i] weight = 1 return sell, weight 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) avg3_list = close_df.rolling(window=3).mean().fillna(close[0]).values.tolist() avg3 = [item[0] for item in avg3_list] avg5_list = close_df.rolling(window=5).mean().fillna(close[0]).values.tolist() avg5 = [item[0] for item in avg5_list] avg10_list = close_df.rolling(window=10).mean().fillna(close[0]).values.tolist() avg10 = [item[0] for item in avg10_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] 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], 'avg3': avg3[i], 'avg5': avg5[i],'avg10': avg10[i],'avg20': avg20[i],'avg30': avg30[i],'avg60': avg60[i]}) # stochastic 계산 stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5) stochastic_df = stochastic_df.fillna(100) 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 = macd_df.fillna(100) 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_df = rsi_df.fillna(100) 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 = rsi_df.fillna(100) # changeLine = rsi_df['changeLine'].values.tolist() # baseLine = rsi_df['baseLine'].values.tolist() # leadingSpan1 = rsi_df['leadingSpan1'].values.tolist() # leadingSpan2 = rsi_df['leadingSpan2'].values.tolist() temp = {"date": point_temp, "open": open, "high": high, "low": low, "close": close, "volume": vol, "upper": upper, "lower": lower, "avg3": avg3, "avg5": avg5, "avg10": avg10, "avg20": avg20, "avg30": avg30, "avg60": avg60, "macd": macd, "macds": macds, "macdo": macdo, "fast_k": fast_k, "slow_k": slow_k, "slow_d": slow_d, "rsi": rsi, "rsis": rsis} data = pd.DataFrame(temp) df_final_time = pd.DatetimeIndex(point_temp) data.index = df_final_time return data def checkTransaction(self, data, stock_code): size = len(data["close"]) bsLine = {} bsLine['buy'] = [-1 for i in range(size)] bsLine['weight'] = [-1 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] for i in range(size): if stock_code == "252670": sell, weight = self.getSellPriceAndWeight_3000(data, i) buy, weight = self.getBuyPriceAndWeight_3000(data, i) else: sell, weight = self.getSellPriceAndWeight_15000(data, i) buy, weight = self.getBuyPriceAndWeight_15000(data, i) bsLine['buy'][i] = buy bsLine['weight'][i] = weight bsLine['sell'][i] = sell return bsLine