import math from datetime import datetime import pandas as pd from stockpredictor.analysis.Common import Common from stockpredictor.analysis.Stochastic import Stochastic from stockpredictor.analysis.RSI import RSI from stockpredictor.analysis.MACD import MACD from stockpredictor.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