diff --git a/stock/analysis/AnalyzerSqlite.py b/stock/analysis/AnalyzerSqlite.py index 7afad38..565eb9b 100644 --- a/stock/analysis/AnalyzerSqlite.py +++ b/stock/analysis/AnalyzerSqlite.py @@ -153,10 +153,11 @@ class AnalyzerSqlite: macds = list(reversed(stock['macds'])) rsi = list(reversed(stock['rsi'])) rsis = list(reversed(stock['rsis'])) - stochastic_slow_k = list(reversed(stock['stochastic_slow_k'])) - stochastic_slow_d = list(reversed(stock['stochastic_slow_d'])) - bolingerband_upper = list(reversed(stock['bolingerband_upper'])) - bolingerband_lower = list(reversed(stock['bolingerband_lower'])) + stochastic_slow_k = list(reversed(stock['slow_k'])) + stochastic_slow_d = list(reversed(stock['slow_d'])) + bolingerband_upper = list(reversed(stock['upper'])) + bolingerband_lower = list(reversed(stock['lower'])) + bolingerband_middle = list(reversed(stock['middle'])) envelope_upper = list(reversed(stock['envelope_upper'])) envelope_lower = list(reversed(stock['envelope_lower'])) ichimokucloud_changeLine = list(reversed(stock['ichimokucloud_changeLine'])) @@ -416,10 +417,10 @@ class AnalyzerSqlite: "close": close, "open": open, "high": high, "low": low, "volume": volume, "avg3": avg3, "avg4": avg4, "avg5": avg5, "avg6": avg6, "avg10": avg10, "avg12": avg12, "avg20": avg20, "avg36": avg36, "avg40": avg40, "avg48": avg48, "avg60": avg60, "avg120": avg120, "avg200": avg200, "avg240": avg240, "avg300": avg300, "disparity_avg5": disparity_avg5, "disparity_avg10": disparity_avg10, "disparity_avg20": disparity_avg20, "disparity_avg60": disparity_avg60, "disparity_avg120": disparity_avg120, - "bolingerband_upper": bolingerband_upper, "bolingerband_lower": bolingerband_lower, "bolingerband_middle": bolingerband_middle, + "upper": bolingerband_upper, "lower": bolingerband_lower, "middle": bolingerband_middle, "envelope_upper": envelope_upper, "envelope_lower": envelope_lower, "envelope_middle": envelope_middle, "ichimokucloud_changeLine": ichimokucloud_changeLine, "ichimokucloud_baseLine": ichimokucloud_baseLine, "ichimokucloud_leadingSpan1": ichimokucloud_leadingSpan1, "ichimokucloud_leadingSpan2": ichimokucloud_leadingSpan2, - "stochastic_fast_k": stochastic_fast_k, "stochastic_slow_k": stochastic_slow_k, "stochastic_slow_d": stochastic_slow_d, + "fast_k": stochastic_fast_k, "slow_k": stochastic_slow_k, "slow_d": stochastic_slow_d, "rsi": rsi, "rsis": rsis, "macd": macd, "macds": macds, "macdo": macdo, "obv5": [], "obv20": [], "obv60": [] @@ -458,6 +459,7 @@ class AnalyzerSqlite: self.makeDir("daily_5일선_돌파") self.makeDir("daily_5일선_20일선_돌파") self.makeDir("daily_20일선_60일선_돌파") + self.makeDir("daily_최적_타이밍_찾기") #self.makeDir("daily_OBV") #self.makeDir("daily_EV하단_내려옴") #self.makeDir("daily_BB하단_내려옴") @@ -670,6 +672,12 @@ class AnalyzerSqlite: log = dir_name + "_" self.writeFile(dir_name, CODE, NAME, top, stock_daily, log) + check = self.common.check_optimal_buy_timeing(stock_daily) + if check: + dir_name = "daily_최적_타이밍_찾기" + log = dir_name + "_" + self.writeFile(dir_name, CODE, NAME, top, stock_daily, log) + """ # daily_OBV obv = self.common.check_obv(stock_daily) diff --git a/stock/analysis/Common.py b/stock/analysis/Common.py index 6f95a73..9f4fa9e 100644 --- a/stock/analysis/Common.py +++ b/stock/analysis/Common.py @@ -572,6 +572,68 @@ class Common: return False + def check_optimal_buy_timeing(self, stock): + + max_vol_5 = max(stock['volume'][0: 4]) + max_vol_30 = max(stock['volume'][4: 24]) + if max_vol_30 < max_vol_5: + if stock['open'][1] < stock['close'][1] and stock['volume'][1] < stock['volume'][0]: + # if stock['open'][i - 1] < stock['close'][i - 1] and stock['volume'][i - 1] < stock['volume'][i]: + + # 1) 스토캐스틱 과매도 + slow_k_buy = False + for idx in range(0, 10): + if stock['slow_k'][idx] < 20: + slow_k_buy = True + break + + # 2) macd 교차 신호 + macd_buy = False + if slow_k_buy: + for idx in range(0, 10): + if stock['macd'][idx+1] < 0 and stock['macds'][idx+1] < 0 and stock['macd'][idx] < 0 and stock['macds'][idx] < 0: + if stock['macd'][idx+1] < stock['macds'][idx+1] and stock['macd'][idx] > stock['macds'][idx]: + macd_buy = True + break + + # 3) RSI 지수가 50위로 올라갈 때 + if macd_buy: + if stock['rsi'][1] < 40 and stock['rsi'][0] > 40: + return True + + + if stock['close'][0] < stock['avg200'][0] and stock['open'][0] < stock['close'][0] and max(stock['avg5'][0], stock['avg20'][0], stock['avg200'][0]) < stock['avg60'][0]: + if stock['open'][0] < min(stock['close'][0], stock['avg5'][0], stock['avg20'][0], stock['avg60'][0], stock['avg120'][0]): + if max(stock['volume'][:10]) * 4 < stock['volume'][0]: + if stock['open'][0] < (stock['upper'][0] + stock['lower'][0]) / 2: + return True + + if stock['avg200'][0] < stock['avg5'][0] and stock['avg200'][0] < stock['avg20'][0] and stock['avg200'][0] < stock['avg60'][0]: + if stock['open'][0] < stock['close'][0]: + if max(stock['volume'][:10]) * 3 < stock['volume'][0]: + if max(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0]) - min(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0]) < 0.003: + return True + + if stock['open'][1] < stock['close'][1] and stock['open'][0] < stock['close'][0]: + if stock['volume'][1] * 10 < stock['volume'][0]: + if stock['upper'][0] < stock['close'][0]: + if max(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0]) - min(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0]) < 0.005: + if max(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0], stock['disparity_avg200'][0]) - min(stock['disparity_avg5'][0], stock['disparity_avg20'][0], stock['disparity_avg60'][0], stock['disparity_avg200'][0]) < 0.006: + if stock['avg200'][0] < min(stock['open'][0], stock['close'][0], stock['avg5'][0], stock['avg20'][0], stock['avg60'][0]): + return True + + check = False + for c in range(10): + if stock['close'][c+1] < stock['close'][c+2] < stock['close'][c+3] < stock['close'][c+4] < stock['close'][c+5] < stock['close'][c+6]: + if stock['close'][c+1] < stock['lower'][c+1] and stock['close'][c+2] < stock['lower'][c+2] and stock['close'][c+3] < stock['lower'][c+3] and stock['close'][c+4] < stock['lower'][c+4] and stock['close'][c+5] < stock['lower'][c+5] and stock['close'][c+6] < stock['lower'][c+6]: + check = True + break + if check and stock['close'][0] < stock['lower'][0]: + return True + + return False + + # 낙폭 과대 체크 def check_excessive_drop(self, stock): c_index = 200 @@ -589,9 +651,9 @@ class Common: return False def check_under_BB_Low(self, stock): - if stock['bolingerband_lower'][0] is not None and stock['bolingerband_lower'][1] is not None: + if stock['lower'][0] is not None and stock['lower'][1] is not None: # bb 하단에 부딪힘 - if stock['close'][0] < stock['bolingerband_lower'][0]: + if stock['close'][0] < stock['lower'][0]: return True return False