diff --git a/Simulation.py b/Simulation.py index 4b5c8a2..ab9d751 100644 --- a/Simulation.py +++ b/Simulation.py @@ -290,9 +290,8 @@ if __name__ == "__main__": PROJECT_HOME = os.getcwd() RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources") - day_list = ['20231016', '20231017', '20231018', '20231019', '20231020', - '20231023', '20231024', '20231025', '20231026', '20231027', - '20231030', '20231031', '20231101', '20231102'] + #day_list = ['20231016', '20231017', '20231018', '20231019', '20231020', '20231023', '20231024', '20231025', '20231026', '20231027', '20231030', '20231031', '20231101', '20231102'] + day_list = ['20231102'] # to check bying stock = {'code': '252670', 'name': 'KODEX 200선물인버스2X', 'ymd': day_list} diff --git a/hts/BuySellChecker_122630.py b/hts/BuySellChecker_122630.py index 5e23e3e..9666f77 100644 --- a/hts/BuySellChecker_122630.py +++ b/hts/BuySellChecker_122630.py @@ -7,53 +7,78 @@ class BuySellChecker_122630 (BuySellChecker): return def getBuyPriceAndWeight(self, stock_code, i, data, INFO): - buy, weight = -1, -1 + buy, weight, type = -1, -1, "" - C_MIN_AVG_5_200 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - C_MIN_AVG_5_60 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - - MIN_AVG_5_200 = 0.002 - MIN_AVG_5_60 = 0.002 - DIFF_200_5 = 0.001 - - if (abs(data['disparity_avg200'][i] - data['disparity_avg5'][i]) < DIFF_200_5 and C_MIN_AVG_5_200 < MIN_AVG_5_200 and C_MIN_AVG_5_60 < MIN_AVG_5_60): - if data['avg200'][i] < data['avg5'][i]: - if 180 < i: - valid = True - for c in range(5, 181): - if data['avg200'][-c] < data['avg200'][-c]: - valid = False - break - if valid: - if max(data['volume'].tolist()[i-10:i]) < data['volume'][i]: - buy = data['close'][i] - weight = 1 - 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]: - buy = data['close'][i] - weight = 1 - - if data['macd'][i-1] < -1000: - if -1000 < data['macd'][i]: - buy = data['close'][i] + """ + #매수전략 #0: 기준선 위에서 골든크로스 + if (0 < data['macd'][i] and 0 < data['macds'][i]): + if (data['macd'][i-1] < data['macds'][i-1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['macd'][i - c] < 0: + canBuy = True + break + if canBuy: weight = 1 + buy = data['close'][i] + type = 'method0' + """ + + # 매수전략 #1: 깊은 하락 + if (data['macd'][i]<-1000) and (data['macdo'][i-1] <= 0 and 0 < data['macdo'][i]): + if data['close'][i] < data['avg200'][i]: + weight = 0.5 + buy = data['close'][i] + type = 'method1' + + + # 매수전략 #2: RSI 과매도 이후 골든크로스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['rsi'][i-c] < 10: + canBuy = True + break + if canBuy: + weight = 3 + buy = data['close'][i] + type = 'method2' + + + # 매수전략 #3: 다이버전스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + index = 0 + for c in range(1, 41): + if data['macd'][i-c-1] < data['macds'][i-c-1] and data['macds'][i-c] < data['macd'][i-c]: + canBuy = True + index = c + break + if canBuy and data['rsi'][i-index] < 30: + if (data['macd'][i-index] < data['macd'][i] and + min(data['open'][i], data['close'][i]) < min(data['open'][i-index], data['close'][i-index])): + weight = 2 + buy = data['close'][i] + type = 'method3' return buy, weight - def checkTransaction(self, stock_code, data, INFO, isRealTime=True): - sell, weight = -1, -1 + def getSellPriceAndWeight(self, stock_code, i, data, INFO): + sell, weight, type = -1, -1, "" - if data['close'][i] < INFO['LIMIT_PRICE'] < data['close'][i-1]: - sell = data['close'][i] - weight = 1 - - if (650 < data['macd'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): + # 매수전략 #1: 높은 상승 + if (350 < data['macd'][i] or 300 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): #if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]: weight = 1 sell = data['close'][i] + type = 'method1' - if data['close'][i] < INFO['LIMIT_PRICE']: - weight = 1 - sell = data['close'][i] + # 매수전략 #2: RSI 과매수에서 데드크로스 + if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]): + if 80 < data['rsi'][i]: + weight = 1 + sell = data['close'][i] + type = 'method2' return sell, weight diff --git a/hts/BuySellChecker_233740.py b/hts/BuySellChecker_233740.py index 8ecf6dc..8ad9cb8 100644 --- a/hts/BuySellChecker_233740.py +++ b/hts/BuySellChecker_233740.py @@ -7,57 +7,81 @@ class BuySellChecker_233740 (BuySellChecker): return def getBuyPriceAndWeight(self, stock_code, i, data, INFO): - buy, weight = -1, -1 + buy, weight, type = -1, -1, "" - C_MIN_AVG_5_200 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - C_MIN_AVG_5_60 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - - MIN_AVG_5_200 = 0.002 - MIN_AVG_5_60 = 0.002 - DIFF_200_5 = 0.001 - - if (abs(data['disparity_avg200'][i] - data['disparity_avg5'][i]) < DIFF_200_5 and C_MIN_AVG_5_200 < MIN_AVG_5_200 and C_MIN_AVG_5_60 < MIN_AVG_5_60): - if data['avg200'][i] < data['avg5'][i]: - if 180 < i: - valid = True - for c in range(5, 181): - if data['avg200'][-c] < data['avg200'][-c]: - valid = False - break - if valid: - if max(data['volume'].tolist()[i-10:i]) < data['volume'][i]: - buy = data['close'][i] - weight = 1 - 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]: - buy = data['close'][i] - weight = 1 - - if data['macd'][i-1] < -1000: - if -1000 < data['macd'][i]: - buy = data['close'][i] + """ + #매수전략 #0: 기준선 위에서 골든크로스 + if (0 < data['macd'][i] and 0 < data['macds'][i]): + if (data['macd'][i-1] < data['macds'][i-1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['macd'][i - c] < 0: + canBuy = True + break + if canBuy: weight = 1 + buy = data['close'][i] + type = 'method0' + """ + + # 매수전략 #1: 깊은 하락 + if (data['macd'][i]<-1000) and (data['macdo'][i-1] <= 0 and 0 < data['macdo'][i]): + if data['close'][i] < data['avg200'][i]: + weight = 0.5 + buy = data['close'][i] + type = 'method1' + + + # 매수전략 #2: RSI 과매도 이후 골든크로스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['rsi'][i-c] < 10: + canBuy = True + break + if canBuy: + weight = 3 + buy = data['close'][i] + type = 'method2' + + + # 매수전략 #3: 다이버전스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + index = 0 + for c in range(1, 41): + if data['macd'][i-c-1] < data['macds'][i-c-1] and data['macds'][i-c] < data['macd'][i-c]: + canBuy = True + index = c + break + if canBuy and data['rsi'][i-index] < 30: + if (data['macd'][i-index] < data['macd'][i] and + min(data['open'][i], data['close'][i]) < min(data['open'][i-index], data['close'][i-index])): + weight = 2 + buy = data['close'][i] + type = 'method3' return buy, weight def getSellPriceAndWeight(self, stock_code, i, data, INFO): - sell, weight = -1, -1 + sell, weight, type = -1, -1, "" - if data['close'][i] < INFO['LIMIT_PRICE'] < data['close'][i-1]: - sell = data['close'][i] - weight = 1 - - if (650 < data['macd'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): + # 매수전략 #1: 높은 상승 + if (650 < data['macd'][i] or 600 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): #if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]: weight = 1 sell = data['close'][i] + type = 'method1' - if data['close'][i] < INFO['LIMIT_PRICE']: - weight = 1 - sell = data['close'][i] + # 매수전략 #2: RSI 과매수에서 데드크로스 + if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]): + if 80 < data['rsi'][i]: + weight = 1 + sell = data['close'][i] + type = 'method2' return sell, weight - def checkTransaction(self, stock_code, data, INFO, isRealTime=True): # 어제 오늘 데이터로 분석 bsLine = {} diff --git a/hts/BuySellChecker_251340.py b/hts/BuySellChecker_251340.py index ffdbe15..e92fb61 100644 --- a/hts/BuySellChecker_251340.py +++ b/hts/BuySellChecker_251340.py @@ -7,57 +7,81 @@ class BuySellChecker_251340 (BuySellChecker): return def getBuyPriceAndWeight(self, stock_code, i, data, INFO): - buy, weight = -1, -1 + buy, weight, type = -1, -1, "" - C_MIN_AVG_5_200 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - C_MIN_AVG_5_60 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - - MIN_AVG_5_200 = 0.002 - MIN_AVG_5_60 = 0.002 - DIFF_200_5 = 0.001 - - if (abs(data['disparity_avg200'][i] - data['disparity_avg5'][i]) < DIFF_200_5 and C_MIN_AVG_5_200 < MIN_AVG_5_200 and C_MIN_AVG_5_60 < MIN_AVG_5_60): - if data['avg200'][i] < data['avg5'][i]: - if 180 < i: - valid = True - for c in range(5, 181): - if data['avg200'][-c] < data['avg200'][-c]: - valid = False - break - if valid: - if max(data['volume'].tolist()[i-10:i]) < data['volume'][i]: - buy = data['close'][i] - weight = 1 - 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]: - buy = data['close'][i] - weight = 1 - - if data['macd'][i-1] < -1000: - if -1000 < data['macd'][i]: - buy = data['close'][i] + """ + #매수전략 #0: 기준선 위에서 골든크로스 + if (0 < data['macd'][i] and 0 < data['macds'][i]): + if (data['macd'][i-1] < data['macds'][i-1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['macd'][i - c] < 0: + canBuy = True + break + if canBuy: weight = 1 + buy = data['close'][i] + type = 'method0' + """ + + # 매수전략 #1: 깊은 하락 + if (data['macd'][i]<-1000) and (data['macdo'][i-1] <= 0 and 0 < data['macdo'][i]): + if data['close'][i] < data['avg200'][i]: + weight = 0.5 + buy = data['close'][i] + type = 'method1' + + + # 매수전략 #2: RSI 과매도 이후 골든크로스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['rsi'][i-c] < 10: + canBuy = True + break + if canBuy: + weight = 3 + buy = data['close'][i] + type = 'method2' + + + # 매수전략 #3: 다이버전스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + index = 0 + for c in range(1, 41): + if data['macd'][i-c-1] < data['macds'][i-c-1] and data['macds'][i-c] < data['macd'][i-c]: + canBuy = True + index = c + break + if canBuy and data['rsi'][i-index] < 30: + if (data['macd'][i-index] < data['macd'][i] and + min(data['open'][i], data['close'][i]) < min(data['open'][i-index], data['close'][i-index])): + weight = 2 + buy = data['close'][i] + type = 'method3' return buy, weight def getSellPriceAndWeight(self, stock_code, i, data, INFO): - sell, weight = -1, -1 + sell, weight, type = -1, -1, "" - if data['close'][i] < INFO['LIMIT_PRICE'] < data['close'][i-1]: - sell = data['close'][i] - weight = 1 - - if (650 < data['macd'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): + # 매수전략 #1: 높은 상승 + if (650 < data['macd'][i] or 600 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): #if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]: weight = 1 sell = data['close'][i] + type = 'method1' - if data['close'][i] < INFO['LIMIT_PRICE']: - weight = 1 - sell = data['close'][i] + # 매수전략 #2: RSI 과매수에서 데드크로스 + if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]): + if 80 < data['rsi'][i]: + weight = 1 + sell = data['close'][i] + type = 'method2' return sell, weight - def checkTransaction(self, stock_code, data, INFO, isRealTime=True): # 어제 오늘 데이터로 분석 bsLine = {} diff --git a/hts/BuySellChecker_252670.py b/hts/BuySellChecker_252670.py index 9301748..7ac2d16 100644 --- a/hts/BuySellChecker_252670.py +++ b/hts/BuySellChecker_252670.py @@ -5,64 +5,82 @@ class BuySellChecker_252670 (BuySellChecker): def __init__(self): super().__init__() return - def getBuyPriceAndWeight(self, stock_code, i, data, INFO): - buy, weight = -1, -1 + buy, weight, type = -1, -1, "" - C_MIN_AVG_5_200 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i], data['disparity_avg200'][i]) - C_MIN_AVG_5_60 = max(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - min(data['disparity_avg5'][i], data['disparity_avg20'][i], data['disparity_avg60'][i]) - C_DIFF_AVG_200_5 = abs(data['disparity_avg200'][i] - data['disparity_avg5'][i]) + """ + #매수전략 #0: 기준선 위에서 골든크로스 + if (0 < data['macd'][i] and 0 < data['macds'][i]): + if (data['macd'][i-1] < data['macds'][i-1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['macd'][i - c] < 0: + canBuy = True + break + if canBuy: + weight = 1 + buy = data['close'][i] + type = 'method0' + """ - if 0.004 < C_MIN_AVG_5_60 < 0.005 and 0.007 < C_MIN_AVG_5_200 < 0.008 and 0.007 < C_DIFF_AVG_200_5 < 0.008: - buy = data['close'][i] - weight = 1 - if 0.023 < C_MIN_AVG_5_60 < 0.024 and 0.026 < C_MIN_AVG_5_200 < 0.027 and 0.026 < C_DIFF_AVG_200_5 < 0.027: - buy = data['close'][i] - weight = 1 - if 0.013 < C_MIN_AVG_5_60 < 0.014 and 0.013 < C_MIN_AVG_5_200 < 0.014 and 0.013 < C_DIFF_AVG_200_5 < 0.014: - buy = data['close'][i] - weight = 1 - if 0.004 < C_MIN_AVG_5_60 < 0.005 and 0.005 < C_MIN_AVG_5_200 < 0.006 and 0.0008 < C_DIFF_AVG_200_5 < 0.001: - buy = data['close'][i] - weight = 1 - if 0.001 < C_MIN_AVG_5_60 < 0.0015 and 0.0055 < C_MIN_AVG_5_200 < 0.006 and 0.0055 < C_DIFF_AVG_200_5 < 0.006: - buy = data['close'][i] - weight = 1 - if 0.001 < C_MIN_AVG_5_60 < 0.0015 and 0.0015 < C_MIN_AVG_5_200 < 0.002 and 0.0015 < C_DIFF_AVG_200_5 < 0.002: - buy = data['close'][i] - weight = 1 - if 0.009 < C_MIN_AVG_5_60 < 0.0095 and 0.01 < C_MIN_AVG_5_200 < 0.012 and 0.01 < C_DIFF_AVG_200_5 < 0.012: - buy = data['close'][i] - weight = 1 - if 0.002 < C_MIN_AVG_5_60 < 0.0023 and 0.0062 < C_MIN_AVG_5_200 < 0.0068 and 0.0062 < C_DIFF_AVG_200_5 < 0.0068: - buy = data['close'][i] - weight = 1 - if 0.008 < C_MIN_AVG_5_60 < 0.0085 and 0.008 < C_MIN_AVG_5_200 < 0.0085 and 0.0075 < C_DIFF_AVG_200_5 < 0.008: - buy = data['close'][i] - weight = 1 + # 매수전략 #1: 깊은 하락 + if (data['macd'][i]<-1000) and (data['macdo'][i-1] <= 0 and 0 < data['macdo'][i]): + if data['close'][i] < data['avg200'][i]: + weight = 0.5 + buy = data['close'][i] + type = 'method1' + # 매수전략 #2: RSI 과매도 이후 골든크로스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + for c in range(1, 11): + if data['rsi'][i-c] < 10: + canBuy = True + break + if canBuy: + weight = 3 + buy = data['close'][i] + type = 'method2' + + + # 매수전략 #3: 다이버전스 + if (data['macd'][i - 1] < data['macds'][i - 1] and data['macds'][i] < data['macd'][i]): + canBuy = False + index = 0 + for c in range(1, 41): + if data['macd'][i-c-1] < data['macds'][i-c-1] and data['macds'][i-c] < data['macd'][i-c]: + canBuy = True + index = c + break + if canBuy and data['rsi'][i-index] < 30: + if (data['macd'][i-index] < data['macd'][i] and + min(data['open'][i], data['close'][i]) < min(data['open'][i-index], data['close'][i-index])): + weight = 2 + buy = data['close'][i] + type = 'method3' + return buy, weight def getSellPriceAndWeight(self, stock_code, i, data, INFO): - sell, weight = -1, -1 + sell, weight, type = -1, -1, "" - if data['close'][i] < INFO['LIMIT_PRICE'] < data['close'][i-1]: - sell = data['close'][i] - weight = 1 - - if (5 < data['macd'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): + # 매수전략 #1: 높은 상승 + if (650 < data['macd'][i] or 600 < data['macds'][i]) and (0 < data['macdo'][i-1] and data['macdo'][i] <= 0): #if data['macds'][i-1] < data['macd'][i-1] and data['macd'][i] < data['macds'][i]: weight = 1 sell = data['close'][i] + type = 'method1' - if data['close'][i] < INFO['LIMIT_PRICE']: - weight = 1 - sell = data['close'][i] + # 매수전략 #2: RSI 과매수에서 데드크로스 + if (data['macds'][i - 1] < data['macd'][i - 1] and data['macd'][i] < data['macds'][i]): + if 80 < data['rsi'][i]: + weight = 1 + sell = data['close'][i] + type = 'method2' return sell, weight - def checkTransaction(self, stock_code, data, INFO, isRealTime=True): # 어제 오늘 데이터로 분석 bsLine = {} @@ -105,4 +123,4 @@ class BuySellChecker_252670 (BuySellChecker): bsLine['sell'] = [-1] bsLine['sell_weight'] = [-1] - return bsLine \ No newline at end of file + return bsLine diff --git a/stock/analysis/AnalyzerSqlite.py b/stock/analysis/AnalyzerSqlite.py index 0a6ea76..5869900 100644 --- a/stock/analysis/AnalyzerSqlite.py +++ b/stock/analysis/AnalyzerSqlite.py @@ -1066,9 +1066,9 @@ if __name__ == "__main__": stockFileName = os.path.join(RESOURCE_PATH, 'stock.db') analyzer = AnalyzerSqlite(stockFileName) - analyzer.analyzeDaily() - analyzer.analyzeGrouping("weekly") - analyzer.analyzeGrouping("monthly") + #analyzer.analyzeDaily() + #analyzer.analyzeGrouping("weekly") + #analyzer.analyzeGrouping("monthly") # HTML 출력 outPath = os.path.join(PROJECT_HOME, "resources", "analysis") diff --git a/stock/analysis/Common.py b/stock/analysis/Common.py index 79f36b9..7207adc 100644 --- a/stock/analysis/Common.py +++ b/stock/analysis/Common.py @@ -574,65 +574,42 @@ class Common: def check_optimal_buy_timeing(self, stock): - if stock['slow_k'][0] is None: - return False + min_macd = min(stock['macd']) / 2 - 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: 깊은 하락 + if (stock['macd'][0] < min_macd) and (stock['macdo'][1] <= 0 and 0 < stock['macdo'][0]): + if stock['close'][0] < stock['avg200'][0]: + weight = 0.5 + buy = stock['close'][0] + type = 'method1' - # 1) 스토캐스틱 과매도 - slow_k_buy = False - for idx in range(0, 10): - if stock['slow_k'][idx] < 20: - slow_k_buy = True - break + # 매수전략 #2: RSI 과매도 이후 골든크로스 + if (stock['macd'][1] < stock['macds'][1] and stock['macds'][0] < stock['macd'][0]): + canBuy = False + for c in range(1, 11): + if stock['rsi'][0 - c] < 10: + canBuy = True + break + if canBuy: + weight = 3 + buy = stock['close'][0] + type = 'method2' - # 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 + # 매수전략 #3: 다이버전스 + if (stock['macd'][1] < stock['macds'][1] and stock['macds'][0] < stock['macd'][0]): + canBuy = False + index = 0 + for c in range(1, 41): + if stock['macd'][0 - c - 1] < stock['macds'][0 - c - 1] and stock['macds'][0 - c] < stock['macd'][0 - c]: + canBuy = True + index = c + break + if canBuy and stock['rsi'][0 - index] < 30: + if (stock['macd'][0 - index] < stock['macd'][0] and + min(stock['open'][0], stock['close'][0]) < min(stock['open'][0 - index], stock['close'][0 - index])): + weight = 2 + buy = stock['close'][0] + type = 'method3' return False