From 5c098d84fbef31ce8584492d66bcbcb7effcc563 Mon Sep 17 00:00:00 2001 From: "dosang.yoon" Date: Sun, 17 Jul 2022 02:12:38 +0900 Subject: [PATCH] init --- hts/BuySellChecker.py | 551 +++++++++++++++++++++++++----------------- hts/HTS_252670.py | 5 +- hts/Simulation.py | 34 +-- 3 files changed, 339 insertions(+), 251 deletions(-) diff --git a/hts/BuySellChecker.py b/hts/BuySellChecker.py index 4410553..0328720 100644 --- a/hts/BuySellChecker.py +++ b/hts/BuySellChecker.py @@ -167,50 +167,95 @@ class BuySellChecker: if i >= START_TIME_INDEX: # 매수 분석 - # 장 초기 (시작 3분 이내) 양봉 2개에 3분차에 장대 양봉이면 매수. - if i < 381 + 4: - if data["open"][i] == data["low"][i] and data["close"][i] == data["high"][i]: - if data["close"][i-2] <= data["open"][i-1]: - if data["open"][i-2] < data["close"][i-2] and data["open"][i-1] < data["close"][i-1]: - buy = data["high"][i] + 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 = 1 + 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 = 1 return self.getBuyCheck(data, i, buy, weight) - # 장 초기 (시작 7분 이내), 볼린져 하단에서 시작하여 이병선을 모두 상승하여 마감한 경우 low 값에서 매수한다. - if i < 381 + 8: - if data["open"][i] == data["low"][i] and data["close"][i] == data["high"][i]: - if data["close"][i] > max(data["avg3"][i], data["avg5"][i], data["avg10"][i], data["avg20"][i], data["avg30"][i]): - buy = data["low"][i] - weight = 2 + # 최근 양봉 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 = 1 return self.getBuyCheck(data, i, buy, weight) + - # 만약 30원 이상 장대 양봉이 나온 경우, 다음이나 다다음 중간 값에서 매수를 한다. - if (data["close"][i] - data["low"][i]) >= 30: - middle = int((data["close"][i] + data["low"][i])/2) - buy = middle - 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) - - # 이동선을 이용한 매매 - # 3분선과 10분선이 30분 이상 내려오다가 3분선이 10분선을 넘어 서는 순간 매수 - 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 + # 장시작 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 = 1 return self.getBuyCheck(data, i, buy, weight) + # 장 초기 (시작 9분 이내), 볼린져 하단에서 시작하여 이병선을 모두 상승하여 마감한 경우 high 값에서 매수한다. + # (2022-07-15 09:08 09:09) + 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분선과 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(data["avg3"][i]) > int(data["avg5"][i]): valid = True same_count = 0 @@ -225,78 +270,23 @@ class BuySellChecker: buy = data["close"][i] - 5 weight = 1 return self.getBuyCheck(data, i, buy, weight) - - # 다이버젼스 - # slow_k가 20 이하에서 이전 최저점의 slow_k보다 지금 최저점의 slow_k가 더 높은 경우 - if data["slow_k"][i] < 20: - if data["close"][i] > data["close"][i - 1]: - p_slow_k = 100 - p_close = 0 - top = False - for c in range(1, 60): - if not top and data["close"][i-c] > min(data["open"][i-c], data["close"][i-c]): - top = True - if top and data["close"][i-c] > min(data["open"][i-c], data["close"][i-c]): - p_slow_k = data["slow_k"][i-c] - p_close = data["close"][i-c] - break - if data["close"][i] < p_close and data["slow_k"][i] > p_slow_k: - buy = data["close"][i] - weight = 1 - return self.getBuyCheck(data, i, buy, weight) - - + # 이동선을 이용한 매매 - # 3분선이 10분선에 돌파 후 지지하는지 확인하고 slow_k < 40일 때 매수함 - - # 현재 단계: - # - avg3[i]이 avg10[i]보다 커야함 - # - avg3[i]가 avg3[i-1]보다 커야함 - if data['avg10'][i] < data['avg3'][i] and data['avg3'][i-1] < data['avg3'][i] and abs(data['avg10'][i] - data['avg3'][i]) > 2: - # 첫 이전 단계: - # - avg3[i-1]과 avg10[i-1]의 abs가 3이내여야 함 - if abs(data['avg3'][i-1] - data['avg10'][i-1]) < 3 and data['avg3'][i-1] < data['avg3'][i-2]: - index1 = -1 - valid = False - for j in range(2, 20): - # 두 번째 이전 단계: - # - avg3[i-2]가 avg10[i-2]보다 커야 함 - # - avg3[i-2]가 avg3[i-3]보다 작아야함 - if data['avg10'][i-j] < data['avg3'][i-j] and data['avg3'][i-j] > data['avg3'][i-j-1]: - index1 = j - break - for j in range(index1 + 1, 20): - # 세 번째 이전 단계: - # - avg3[i-3]가 avg3[i-4]보다 커야 함 - if data['avg3'][i-j] > data['avg3'][i-j-1]: - valid = True - index1 = j - else: - break - # 마지막 체크: - # 만약 avg[3]이 avg[10]보다 작다면 매수함 - if valid: - if data['avg3'][i-index1-1] < data['avg10'][i-index1-1]: - if data["slow_k"][i] < 40: - buy = data["close"][i] - weight = 2 - return self.getBuyCheck(data, i, buy, weight) - - - # 10분 이상 10분 선 아래 3분선이 있다가 10분선 위로 올라 올때 장대장봉임 - # 해당 기간 clsoe 값이 10분 선 아래 있을 때, - if data["avg10"][i] < data["avg3"][i] and data["low"][i] == data["open"][i] < data["close"][i] == data["high"][i]: - if (data["avg3"][i-1] <= data["avg10"][i-1]) and ((data["avg10"][i-1] and data["avg3"][i-1]) < data["close"][i-1]): - valid = True - for c in range(2, 11): - if data["avg10"][i-c] < data["avg3"][i-c] or data["avg10"][i-c] < data["close"][i-c]: - valid = False - break - if valid: - buy = int((data["open"][i] + data["close"][i])/2) - weight = 1 - return self.getBuyCheck(data, i, 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 = 1 + return self.getBuyCheck(data, i, buy, weight) # 이동선을 이용한 매매 # 20분선이 30분선에 돌파 후 지지하는지 확인하고 해당 시점이 양봉이면 매수함 @@ -316,49 +306,38 @@ class BuySellChecker: return self.getBuyCheck(data, i, buy, weight) - # macd를 이용한 매수 - if data.index[i].strftime("%H:%M") < "10:00": - if data["macd"][i] < -15 and data["macd"][i-1] < min(data["macd"][i-7], data["macd"][i-6], data["macd"][i-5], data["macd"][i-4], data["macd"][i-3], data["macd"][i-2], data["macd"][i]): - buy = (data["open"][i]+data["close"][i])/2 - weight = 1 - return 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 - # slow_k를 이용한 매수 - if data.index[i].strftime("%H:%M") < "09:20": - if data["slow_k"][i] < 10 and data["slow_k"][i-1] < min(data["slow_k"][i-4], data["slow_k"][i-3], data["slow_k"][i-2], data["slow_k"][i]): - buy = (data["open"][i]+data["close"][i])/2 - weight = 1 - return buy, weight - else: - if data["slow_k"][i] < 10 and data["slow_k"][i-1] < min(data["slow_k"][i-7], data["slow_k"][i-6], data["slow_k"][i-5], data["slow_k"][i-4], data["slow_k"][i-3], data["slow_k"][i-2], data["slow_k"][i]): + 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 = 1 return self.getBuyCheck(data, i, buy, weight) - # 볼린저 밴드가 하락에서 상승으로 전환할 때, - # 지금 양봉 close가 upper를 돌파했다. (이전 거래량 보다 많음) - # 20분 이내로 양봉 close가 upper를 돌파 한 것이 있어야 한다. - # 지금 양봉의 close가 이전 양봉의 close보다 높아야 한다. - # 이 사이에 종가가 20분봉 위에 있어야 한다. - if data.index[i].strftime("%H:%M") > "09:15": - if (data['open'][i] < data['close'][i]==data['high'][i]) and (data['upper'][i] < data['close'][i]) and (data['volume'][i-1] < data['volume'][i]): - if data['open'][i-1] < data['close'][i-1] and data['open'][i-2] < data['close'][i-2]: - if data['close'][i-1] < data['upper'][i-1] and data['close'][i-2] < data['upper'][i-2] and data['close'][i-2] < data['upper'][i-2]: - index = -1 - for c in range(6, 21): - if data['open'][i-c] < data['close'][i-c] and data['upper'][i-c] < data['close'][i-c]: - index = c - break - if index != -1: - valid = True - for c in range(2, index+1): - if data['open'][i-c] < data['avg20'][i-c] and data['close'][i-c] < data['avg20'][i-c]: - valid = False - break - if valid: - buy = data["close"][i] - weight = 1 - return self.getBuyCheck(data, i, buy, weight) + + """ + # 만약 30원 이상 장대 양봉이 나온 경우, 다음이나 다다음 중간 값에서 매수를 한다. + if (data["close"][i] - data["low"][i]) >= 30: + middle = int((data["close"][i] + data["low"][i])/2) + buy = middle + weight = 1 + return self.getBuyCheck(data, i, buy, weight) + """ return buy, weight @@ -375,6 +354,7 @@ class BuySellChecker: if i >= START_TIME_INDEX: # 매도 분석 + # 3분 선이 40분 전부터 게속 20분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg20"][i]: valid = True @@ -385,6 +365,7 @@ class BuySellChecker: if valid: sell = int((data["open"][i] + data["close"][i])/2) return sell, weight + # 3분 선이 60분 전부터 게속 30분선 위에 있다가 아래로 내려오면 매도함 if data["avg3"][i] < data["avg30"][i]: @@ -397,33 +378,38 @@ class BuySellChecker: sell = int((data["open"][i] + data["close"][i])/2) return sell, weight - # 5분 선이 20분 전부터 게속 10분선 위에 있다가 아래로 내려오면 매도함 - if data["avg5"][i] < data["avg10"][i]: - valid = True - for c in range(1, 21): - if data["avg5"][i-c] < data["avg10"][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]: - sell = int((data["open"][i] + data["close"][i]) / 2) + 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 + if data.index[i].strftime("%H:%M") < "12:00" and data['rsis'][i] < 70: + return -1, -1 - return sell, weight + 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 return sell, weight @@ -440,19 +426,120 @@ class BuySellChecker: START_TIME_INDEX = c break - if i >= START_TIME_INDEX + 60: + 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 = (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분선이 20분 이상 내려오다가 3분선이 10분선을 넘어 서는 순간 매수 - if int(data["avg3"][i]) > int(data["avg10"][i]): - if data["slow_k"][i] < 10: + # 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, 21): - if int(data["avg3"][i-c]) == int(data["avg10"][i-c]): + 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]): + if int(data["avg3"][i - c]) > int(data["avg10"][i - c]): valid = False break if valid and same_count < 2: @@ -460,35 +547,47 @@ class BuySellChecker: weight = 1 return self.getBuyCheck(data, i, buy, weight) - # slow_k를 이용한 매수 - if data["slow_k"][i-2] < 5 and data["slow_k"][i-1] < 5 and data["slow_k"][i] < 7: - if data["slow_k"][i-2] < data["slow_k"][i] < data["slow_k"][i-1]: - buy = (data["open"][i]+data["close"][i])/2 - weight = 1 - return buy, weight - - - # macd를 이용한 매수 - if data["macd"][i-2] < -45 and data["macd"][i-1] < -45 and data["macd"][i] < -45: - if data["macd"][i-1] < min (data["macd"][i-2], data["macd"][i]): - buy = (data["open"][i]+data["close"][i])/2 - weight = 1 - return self.getBuyCheck(data, i, buy, weight) - - - # slow_k를 이용한 매수 - if data["slow_k"][i-2] < 15 and data["slow_k"][i-1] < 12 and data["slow_k"][i] < 12: - if data["slow_k"][i-2] < data["slow_k"][i] < data["slow_k"][i-1]: - if data["macd"][i - 1] < -25: - buy = (data["open"][i]+data["close"][i])/2 + # 음봉이 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) return buy, weight - def getSellPriceAndWeight2(self, data, i): sell, weight = -1, -1 @@ -501,77 +600,77 @@ class BuySellChecker: if i >= START_TIME_INDEX: # 매도 분석 - #4분전에 upper 돌파 후 4음봉이면 매도 - if data["open"][i-3] > data["upper"][i-3]: - if data["open"][i - 2] > data["close"][i - 2]: - if data["open"][i - 1] > data["close"][i - 1]: - if data["open"][i] > data["close"][i]: - sell = int((data["open"][i] + data["close"][i]) / 2) - return sell, weight - - # 3분 선이 15분 전부터 게속 5분선 위에 있다가 아래로 내려오면 매도함 - if data["avg3"][i] <= data["avg5"][i]: - valid = True - for c in range(1, 16): - if data["avg3"][i-c] < data["avg5"][i-c] and abs(data["avg3"][i-c] - data["avg5"][i-c]) > 5: - valid = False - break - if valid: - sell = int((data["open"][i] + data["close"][i])/2) - return sell, weight # 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]: + if data["avg3"][i - c] < data["avg20"][i - c]: valid = False break if valid: - sell = int((data["open"][i] + data["close"][i])/2) + 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]: + if data["avg3"][i - c] < data["avg30"][i - c]: valid = False break if valid: - sell = int((data["open"][i] + data["close"][i])/2) + sell = int((data["open"][i] + data["close"][i]) / 2) return sell, weight - # 5분 선이 20분 전부터 게속 10분선 위에 있다가 아래로 내려오면 매도함 - if data["avg5"][i] < data["avg10"][i]: - valid = True - for c in range(1, 21): - if data["avg5"][i-c] < data["avg10"][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]: + 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]: - sell = int((data["open"][i] + data["close"][i]) / 2) + 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 + if data.index[i].strftime("%H:%M") < "12:00" and data['rsis'][i] < 70: + return -1, -1 - return sell, weight + 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: + 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"] diff --git a/hts/HTS_252670.py b/hts/HTS_252670.py index 28dcd05..9c6d74f 100644 --- a/hts/HTS_252670.py +++ b/hts/HTS_252670.py @@ -84,7 +84,9 @@ class HTS_252670 (HTS): final_sell_check = False while datetime.strptime(today + " 070000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 153100", '%Y%m%d %H%M%S'): - if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'): + if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 150000", '%Y%m%d %H%M%S'): + # 3시 까지만 매수를 시도한다. + if THIS_TIME.strftime('%Y%m%d %H%M%S') in timecheck and not timecheck[THIS_TIME.strftime('%Y%m%d %H%M%S')]: # 데이터를 가지고 온다. @@ -150,6 +152,7 @@ class HTS_252670 (HTS): timecheck[THIS_TIME] = True elif datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151600", '%Y%m%d %H%M%S'): + # 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다. if not final_sell_check: #### diff --git a/hts/Simulation.py b/hts/Simulation.py index 2e45d26..a110a60 100644 --- a/hts/Simulation.py +++ b/hts/Simulation.py @@ -184,48 +184,34 @@ class Simulation: if __name__ == "__main__": - """ # to check bying - stock_codes = { - # 122630 - "252670": [ - ('20220627', '20220628'), - ('20220701', '20220704'), - ], - } - """ - - """ stock_codes = { # 252670 # 122630 "122630": [ - ('20220617', '20220620'), - ('20220620', '20220621'), - ('20220621', '20220622'), - ('20220622', '20220623'), - ('20220623', '20220624'), - ('20220624', '20220627'), - ('20220627', '20220628'), - ('20220628', '20220629'), - ('20220629', '20220630'), - ('20220630', '20220701'), ('20220701', '20220704'), ('20220704', '20220705'), ('20220705', '20220706'), ('20220706', '20220707'), - ('20220707', '20220708') + ('20220707', '20220708'), + + ('20220708', '20220711'), + ('20220711', '20220712'), + ('20220712', '20220713'), + ('20220713', '20220714'), + ('20220714', '20220715') ], } - """ + path = './hts/data' + """ path = './hts/backup' fileList = glob(path + '/122630*.csv') fileList = sorted(fileList, reverse=True) stock_codes = {'122630':[]} for i in range(11, 21): stock_codes['122630'].append((fileList[i][20:28], fileList[i-1][20:28])) - + """ for stock_code in stock_codes: simulation = Simulation(stock_code)