diff --git a/HTS_etf.py b/HTS_etf.py index 39d6304..bf6dfc2 100644 --- a/HTS_etf.py +++ b/HTS_etf.py @@ -143,6 +143,8 @@ class HTS_etf(HTS): avg120 = [item[0] for item in avg120_list] avg240_list = close_df.rolling(window=240).mean().fillna(close[0]).values.tolist() avg240 = [item[0] for item in avg240_list] + avg420_list = close_df.rolling(window=420).mean().fillna(close[0]).values.tolist() + avg420 = [item[0] for item in avg420_list] avg480_list = close_df.rolling(window=480).mean().fillna(close[0]).values.tolist() avg480 = [item[0] for item in avg480_list] avg1500_list = close_df.rolling(window=1500).mean().fillna(close[0]).values.tolist() @@ -214,11 +216,11 @@ class HTS_etf(HTS): if "volume_up" in result and "volume_updown_diff" in result: for i in range(len(open)): STOCK.append({'volume': volume[i], 'volume_down': volume_down[i], 'volume_up': volume_up[i], 'volume_updown_diff': volume_updown_diff[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i], - 'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg480': avg480[i], 'avg1500': avg1500[i]}) + 'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg420': avg420[i], 'avg480': avg480[i], 'avg1500': avg1500[i]}) else: for i in range(len(open)): STOCK.append({'volume': volume[i], 'close': close[i], 'open': open[i], 'high': high[i], 'low': low[i], - 'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg480': avg480[i], 'avg1500': avg1500[i]}) + 'avg5': avg5[i], 'avg20': avg20[i], 'avg60': avg60[i], 'avg120': avg120[i], 'avg240': avg240[i], 'avg420': avg420[i], 'avg480': avg480[i], 'avg1500': avg1500[i]}) # stochastic stochastic_df = self.stochastic.apply(STOCK, n=30, m=5, t=5) @@ -254,7 +256,7 @@ class HTS_etf(HTS): "open": open, "high": high, "low": low, "close": close, "volume": volume, "volume_down": volume_down, "volume_up": volume_up, "volume_updown_diff": volume_updown_diff, "trend": trend, "trend_avg": trend_avg, - "avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg480": avg480, + "avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg420": avg420, "avg480": avg480, "avg1500": avg1500, "disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20, "disparity_avg30": disparity_avg30, "disparity_avg60": disparity_avg60, @@ -273,7 +275,7 @@ class HTS_etf(HTS): "ymd": point_temp, "open": open, "high": high, "low": low, "close": close, "volume": volume, "trend": trend, "trend_avg": trend_avg, - "avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg480": avg480, + "avg5": avg5, "avg20": avg20, "avg60": avg60, "avg120": avg120, "avg240": avg240, "avg420": avg420, "avg480": avg480, "avg1500": avg1500, "disparity_avg5": disparity_avg5, "disparity_avg20": disparity_avg20, "disparity_avg30": disparity_avg30, "disparity_avg60": disparity_avg60, @@ -422,26 +424,46 @@ class HTS_etf(HTS): disparity = { 'avg': {}, - "limit_top_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_5": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_5": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_10": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_10": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_30": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_30": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_40": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_40": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_top_99": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None}, - "limit_bottom_99": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, "avg1500": None} + "limit_top_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_1": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_3": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_5": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_5": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_10": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_10": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_20": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_30": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_30": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_98": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_98": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None}, + "limit_top_99": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, "avg480": None, + "avg1500": None}, + "limit_bottom_99": {"avg5": None, "avg20": None, "avg60": None, "avg120": None, "avg240": None, + "avg480": None, "avg1500": None} } disparity['avg'] = avg disparity_1500 = sorted(list(set(avg['avg1500'])), reverse=True) @@ -452,39 +474,28 @@ class HTS_etf(HTS): disparity_20 = sorted(list(set(avg['avg20'])), reverse=True) disparity_5 = sorted(list(set(avg['avg5'])), reverse=True) - poses = [1, 3, 5, 10, 20, 30, 40, 99] + poses = [1, 3, 5, 10, 20, 30, 98, 99] for pos in poses: + loc = pos if pos == 99: - pos = int(len(disparity_20) * 0.03) - disparity['limit_top_99']['avg1500'] = disparity_1500[pos - 1] - disparity['limit_bottom_99']['avg1500'] = disparity_1500[len(disparity_1500) - pos - 1] - disparity['limit_top_99']['avg480'] = disparity_480[pos] - disparity['limit_bottom_99']['avg480'] = disparity_480[len(disparity_480) - pos - 1] - disparity['limit_top_99']['avg240'] = disparity_240[pos] - disparity['limit_bottom_99']['avg240'] = disparity_240[len(disparity_240) - pos - 1] - disparity['limit_top_99']['avg120'] = disparity_120[pos] - disparity['limit_bottom_99']['avg120'] = disparity_120[len(disparity_120) - pos - 1] - disparity['limit_top_99']['avg60'] = disparity_60[pos] - disparity['limit_bottom_99']['avg60'] = disparity_60[len(disparity_60) - pos - 1] - disparity['limit_top_99']['avg20'] = disparity_20[pos] - disparity['limit_bottom_99']['avg20'] = disparity_20[len(disparity_20) - pos - 1] - disparity['limit_top_99']['avg5'] = disparity_5[pos] - disparity['limit_bottom_99']['avg5'] = disparity_5[len(disparity_5) - pos - 1] - else: - disparity['limit_top_' + str(pos)]['avg1500'] = disparity_1500[pos - 1] - disparity['limit_bottom_' + str(pos)]['avg1500'] = disparity_1500[len(disparity_1500) - pos - 1] - disparity['limit_top_' + str(pos)]['avg480'] = disparity_480[pos] - disparity['limit_bottom_' + str(pos)]['avg480'] = disparity_480[len(disparity_480) - pos - 1] - disparity['limit_top_' + str(pos)]['avg240'] = disparity_240[pos] - disparity['limit_bottom_' + str(pos)]['avg240'] = disparity_240[len(disparity_240) - pos - 1] - disparity['limit_top_' + str(pos)]['avg120'] = disparity_120[pos] - disparity['limit_bottom_' + str(pos)]['avg120'] = disparity_120[len(disparity_120) - pos - 1] - disparity['limit_top_' + str(pos)]['avg60'] = disparity_60[pos] - disparity['limit_bottom_' + str(pos)]['avg60'] = disparity_60[len(disparity_60) - pos - 1] - disparity['limit_top_' + str(pos)]['avg20'] = disparity_20[pos] - disparity['limit_bottom_' + str(pos)]['avg20'] = disparity_20[len(disparity_20) - pos - 1] - disparity['limit_top_' + str(pos)]['avg5'] = disparity_5[pos] - disparity['limit_bottom_' + str(pos)]['avg5'] = disparity_5[len(disparity_5) - pos - 1] + loc = int(len(disparity_20) * 0.03) + elif pos == 98: + loc = int(len(disparity_20) * 0.05) + + disparity['limit_top_' + str(pos)]['avg1500'] = disparity_1500[loc - 1] + disparity['limit_bottom_' + str(pos)]['avg1500'] = disparity_1500[len(disparity_1500) - loc - 1] + disparity['limit_top_' + str(pos)]['avg480'] = disparity_480[pos] + disparity['limit_bottom_' + str(pos)]['avg480'] = disparity_480[len(disparity_480) - loc - 1] + disparity['limit_top_' + str(pos)]['avg240'] = disparity_240[pos] + disparity['limit_bottom_' + str(pos)]['avg240'] = disparity_240[len(disparity_240) - loc - 1] + disparity['limit_top_' + str(pos)]['avg120'] = disparity_120[pos] + disparity['limit_bottom_' + str(pos)]['avg120'] = disparity_120[len(disparity_120) - loc - 1] + disparity['limit_top_' + str(pos)]['avg60'] = disparity_60[pos] + disparity['limit_bottom_' + str(pos)]['avg60'] = disparity_60[len(disparity_60) - loc - 1] + disparity['limit_top_' + str(pos)]['avg20'] = disparity_20[pos] + disparity['limit_bottom_' + str(pos)]['avg20'] = disparity_20[len(disparity_20) - loc - 1] + disparity['limit_top_' + str(pos)]['avg5'] = disparity_5[pos] + disparity['limit_bottom_' + str(pos)]['avg5'] = disparity_5[len(disparity_5) - loc - 1] return disparity diff --git a/hts/BuySellChecker.py b/hts/BuySellChecker.py index 0d229e7..91b0414 100644 --- a/hts/BuySellChecker.py +++ b/hts/BuySellChecker.py @@ -124,7 +124,8 @@ class BuySellChecker(): check = False duration = 5 + 60 if duration < i: - if np.average(data['trend_avg'][i - duration:i]) < data['trend_avg'][i]: + if np.average(data['trend_avg'][i - duration:i]) < data['trend_avg'][i] and data['avg1500'][i] < \ + data['trend_avg'][i]: if np.average(data['avg480'][i - duration:i]) < data['avg480'][i]: if data['avg480'][i] < data['trend_avg'][i]: @@ -142,20 +143,27 @@ class BuySellChecker(): buy_type = 'upward' check = True - if data['disparity_avg20'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg20']: - buy_type = 'disparity_avg20' + max_value = np.max(data['close'][i - 3000:i]) + min_value = np.min(data['close'][i - 3000:i]) + if 0.1 < (max_value - min_value) / max_value: + if data['close'][i - 1] < data['trend_avg'][i - 1] and data['trend_avg'][i] < data['close'][i]: + buy_type = 'trend_close' + check = True + + if data['disparity_avg20'][i] < BUY_LIST['disparity']['limit_bottom_5']['avg20']: + buy_type = 'disparity_avg' check = True - if data['disparity_avg60'][i] < BUY_LIST['disparity']['limit_bottom_1']['avg60']: - buy_type = 'disparity_avg60' + if data['disparity_avg60'][i] < BUY_LIST['disparity']['limit_bottom_5']['avg60']: + buy_type = 'disparity_avg' check = True - if data['disparity_avg480'][i] < BUY_LIST['disparity']['limit_bottom_3']['avg480']: - buy_type = 'disparity_avg1500' + if data['disparity_avg480'][i] < BUY_LIST['disparity']['limit_bottom_10']['avg480']: + buy_type = 'disparity_avg' check = True - if data['disparity_avg1500'][i] < BUY_LIST['disparity']['limit_bottom_5']['avg1500']: - buy_type = 'disparity_avg1500' + if data['disparity_avg1500'][i] < BUY_LIST['disparity']['limit_bottom_20']['avg1500']: + buy_type = 'disparity_avg' check = True if check: @@ -176,41 +184,65 @@ class BuySellChecker(): sell_price, sell_count, sell_type = -1, -1, '' check = False + sell_count_disparity_avg = 0 + sell_count_trend_close = 0 if 0 < len(BUY_LIST['buy_list']): - # 매수한지 3시간 이내라면 - if data['ymd'][i] - timedelta(hours=3) < BUY_LIST['buy_list'][-1]['buy_ymd']: + if data['avg480'][i - 1] <= data['avg420'][i] and data['avg420'][i] < data['avg480'][i]: + sell_count_trend_close = sum( + [price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'trend_close']) + if 0 < sell_count_trend_close: + check = True + + # 매수한지 12시간 이내라면 + if data['ymd'][i] - timedelta(hours=12) < BUY_LIST['buy_list'][-1]['buy_ymd']: if BUY_LIST['disparity']['limit_top_3']['avg20'] < data['disparity_avg20'][i]: + sell_count_disparity_avg = sum( + [price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_3']['avg60'] < data['disparity_avg60'][i]: + sell_count_disparity_avg = sum( + [price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_5']['avg480'] < data['disparity_avg480'][i]: + sell_count_disparity_avg = sum( + [price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_10']['avg1500'] < data['disparity_avg1500'][i]: + sell_count_disparity_avg = sum( + [price['buy_count'] for price in BUY_LIST['buy_list'] if price['buy_type'] == 'disparity_avg']) check = True else: - # 매수한지 3시간 이후라면 - if BUY_LIST['buy_list'][-1]['buy_price'] * 1.002 < data['close'][i]: + # 매수한지 12시간 이후라면 + if BUY_LIST['buy_list'][-1]['buy_price'] * 1.004 < data['close'][i]: if BUY_LIST['disparity']['limit_top_99']['avg20'] < data['disparity_avg20'][i]: + sell_count_disparity_avg = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if + price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_99']['avg60'] < data['disparity_avg60'][i]: + sell_count_disparity_avg = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if + price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_99']['avg480'] < data['disparity_avg480'][i]: + sell_count_disparity_avg = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if + price['buy_type'] == 'disparity_avg']) check = True if BUY_LIST['disparity']['limit_top_99']['avg1500'] < data['disparity_avg1500'][i]: + sell_count_disparity_avg = sum([price['buy_count'] for price in BUY_LIST['buy_list'] if + price['buy_type'] == 'disparity_avg']) check = True if check: sell_price = data['close'][i] - sell_count = sum([price['buy_count'] for price in BUY_LIST['buy_list']]) + sell_count = sell_count_disparity_avg + sell_count_trend_close return sell_price, sell_count, sell_type @@ -243,7 +275,8 @@ class BuySellChecker(): bsLine['buy_type'] = [buy_type] if 0 < buy_price: - BUY_LIST['buy_list'].append({'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type}) + BUY_LIST['buy_list'].append( + {'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type}) else: # Type=False, 시뮬레이션 적용 bsLine['buy_ymd'] = [-1 for i in range(size)] @@ -273,7 +306,8 @@ class BuySellChecker(): bsLine['buy_type'][last_index] = buy_type if 0 < buy_price: - BUY_LIST['buy_list'].append({'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type}) + BUY_LIST['buy_list'].append( + {'buy_ymd': buy_ymd, 'buy_price': buy_price, 'buy_count': buy_count, 'buy_cut': buy_cut, 'buy_type': buy_type}) else: bsLine['buy_price'] = [-1]