def simple_wedge(series: Series): output = { "name": "wedge", "upper_band": [], "lower_band": [], "middle_band": [], "info": [], } last_tops = (Event.query.filter_by(timeframe=series.timeframe, pair=series.pair, name="TOP").order_by(desc( Event.time)).limit(2).all()) last_bottoms = (Event.query.filter_by(timeframe=series.timeframe, pair=series.pair, name="BOTTOM").order_by( desc(Event.time)).limit(2).all()) if len(last_bottoms) != 2 and len(last_tops) != 2: return output min_threshold = min(p.time for p in last_tops + last_bottoms) xs = np.array([x if x >= min_threshold else np.nan for x in series.time]) line = make_line(*last_tops) output.update(upper_band=nan_to_null(line(xs))) line = make_line(*last_bottoms) output.update(lower_band=nan_to_null(line(xs))) return output
def STOCH( data, limit, fastk_period=14, slowk_period=14, slowk_matype=3, slowd_period=14, slowd_matype=3, ): slowk, slowd = talib.STOCH( data.high, data.low, data.close, fastk_period, slowk_period, slowk_matype, slowd_period, slowd_matype, ) # TOKENS info = [] if slowk[-1] >= 80: info.append("OSCILLATOR_OVERBOUGHT") elif slowk[-1] <= 20: info.append("OSCILLATOR_OVERSOLD") return { "k": nan_to_null(slowk.tolist()[-limit:]), "d": nan_to_null(slowd.tolist()[-limit:]), "info": info, }
def MACD(data, limit, fastperiod=12, slowperiod=26, signalperiod=9): macd, signal, hist = talib.MACD(data.close, fastperiod, slowperiod, signalperiod) return { "macd": nan_to_null(macd.tolist()[-limit:]), "signal": nan_to_null(signal.tolist()[-limit:]), "histogram": nan_to_null(hist.tolist()[-limit:]), "info": [], }
def STOCHRSI(data, limit, timeperiod=14, fastk_period=14, fastd_period=14, fastd_matype=3): m = 10000000 fastk, fastd = talib.STOCHRSI(m * data.close, timeperiod, fastk_period, fastd_period, fastd_matype) return { "k": nan_to_null(fastk.tolist()[-limit:]), "d": nan_to_null(fastd.tolist()[-limit:]), "info": [], }
def EMA(data, limit): close = data.close periods = [10, 20, 50] names = ["fast", "medium", "slow"] dic = {} info = [] for name, p in zip(names, periods): real = talib.EMA(close, p) dic[name] = nan_to_null(real.tolist()[-limit:]) # TOKENS if close[-1] > real[-1]: info.append("POSITION_UP_{}".format(name.upper())) else: info.append("POSITION_DOWN_{}".format(name.upper())) # TOKENS points2check = -10 for i in range(points2check, 0): if dic["fast"][i] < dic["slow"][i] and dic["fast"][ i - 1] >= dic["slow"][i - 1]: info.append("CROSS_BEARISH") elif (dic["fast"][i] > dic["slow"][i] and dic["fast"][i - 1] <= dic["slow"][i - 1]): info.append("CROSS_BULLISH") for name in names: if close[i] > real[i] and close[i - 1] < real[i - 1]: info.append("CROSS_UP_{}".format(name.upper())) elif close[i] < real[i] and close[i - 1] > real[i - 1]: info.append("CROSS_DOWN_{}".format(name.upper())) dic.update(info=info) return dic
def BB(data, limit, timeperiod=20): m = 1000000 close = m * data.close upperband, middleband, lowerband = talib.BBANDS(close, timeperiod, 2, 2, matype=0) # TOKENS info = [] band_position = (close - lowerband) / (upperband - lowerband) p = band_position[-1] if p > 1: info.append("PRICE_BREAK_UP") elif p < 0: info.append("PRICE_BREAK_DOWN") elif p > 0.95: info.append("PRICE_ONBAND_UP") elif p < 0.05: info.append("PRICE_ONBAND_DOWN") elif 0.40 <= p <= 0.60: info.append("PRICE_BETWEEN") # Check Squeeze width = upperband - lowerband period = 20 width = width[-period:] x = np.arange(width.size) slope = np.polyfit(x, width, 1)[0] if width[-1] / width[0] < 0.8 and slope < 0: info.append("BANDS_SQUEEZE") upperband = upperband / m middleband = middleband / m lowerband = lowerband / m return { "upper_band": nan_to_null(upperband.tolist()[-limit:]), "middle_band": nan_to_null(middleband.tolist()[-limit:]), "lower_band": nan_to_null(lowerband.tolist()[-limit:]), "info": info, }
def KC(data, limit): # Keltner Channels # Middle Line: 20-day exponential moving average # Upper Channel Line: 20-day EMA + (2 x ATR(10)) # Lower Channel Line: 20-day EMA - (2 x ATR(10)) close = data.close high = data.high low = data.low mid = talib.SMA(close, 20) upperch = mid + (2 * talib.ATR(high, low, close, 10)) lowerch = mid - (2 * talib.ATR(high, low, close, 10)) return { "middle_band": nan_to_null(mid.tolist()[-limit:]), "upper_band": nan_to_null(upperch.tolist()[-limit:]), "lower_band": nan_to_null(lowerch.tolist()[-limit:]), "info": [], }
def RSI(data, limit, timeperiod=14): close = data.close m = 10000000 real = talib.RSI(m * close, timeperiod) # TOKENS info = [] if real[-1] >= 70: info.append("OSCILLATOR_OVERBOUGHT") elif real[-1] <= 30: info.append("OSCILLATOR_OVERSOLD") n = int(0.20 * limit) dir_rsi = stats.linregress(np.arange(n), real[-n:]).slope dir_price = stats.linregress(np.arange(n), close[-n:]).slope if dir_rsi * dir_price >= 0.01: info.append("DIV_POSITIVE") elif dir_rsi * dir_price < -0.01: info.append("DIV_NEGATIVE") return {"rsi": nan_to_null(real.tolist()[-limit:]), "info": info}
def OBV(data, limit): real = talib.OBV(data.close, data.volume) return {"obv": nan_to_null(real.tolist()[-limit:]), "info": []}
def MOM(data, limit, timeperiod=10): real = talib.MOM(data.close, timeperiod) return {"mom": nan_to_null(real.tolist()[-limit:]), "info": []}
def ICM(data, limit): margin = Config.MARGIN high, low, close = data.high, data.low, data.close close_size = close.size # Tenkan-sen (Conversion Line): (9-period high + 9-period low)/2)) n1 = 9 conversion_line = [0] * (n1 - 1) for i in range(n1, close_size): conversion_line.append((np.max(high[i - n1 : i]) + np.min(low[i - n1 : i])) / 2) conversion_line = np.array(conversion_line) # Kijun-sen (Base Line): (26-period high + 26-period low)/2)) n2 = 26 base_line = [0] * (n2 - 1) for i in range(n2, close_size): base_line.append((np.max(high[i - n2 : i]) + np.min(low[i - n2 : i])) / 2) base_line = np.array(base_line) # Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2)) leading_span_a = (conversion_line + base_line) / 2 # Senkou Span B (Leading Span B): (52-period high + 52-period low)/2)) n3 = 52 leading_span_b = [0] * (n3 - 1) for i in range(n3, close_size): leading_span_b.append((np.max(high[i - n3 : i]) + np.min(low[i - n3 : i])) / 2) leading_span_b = np.array(leading_span_b) # Some magic leading_span_a = leading_span_a[-(limit + margin) :] leading_span_b = leading_span_b[-(limit + margin) :] # Tokens info = [] actual_a = leading_span_a[-margin] actual_b = leading_span_b[-margin] if actual_a >= actual_b and close[-1] < actual_a: if close[-1] < actual_b: info.append("PIERCED_UP") else: info.append("IN_CLOUD_UP") elif actual_b > actual_a and close[-1] > actual_a: if close[-1] > actual_b: info.append("PIERCED_DOWN") else: info.append("IN_CLOUD_DOWN") width = np.abs(leading_span_a - leading_span_b) p1 = np.percentile(width, 0.80) p2 = np.percentile(width, 0.25) if width[-margin] >= p1: info.append("CLOUD_WIDE") elif width[-margin] <= p2: info.append("CLOUD_THIN") return { "leading_span_a": nan_to_null(leading_span_a.tolist()), "leading_span_b": nan_to_null(leading_span_b.tolist()), "base_line": nan_to_null(base_line.tolist()[-limit:]), "info": info, }
def EWO(data, limit, fast=5, slow=35): start = Config.MAGIC_LIMIT close = data.close real = talib.EMA(close, fast) - talib.EMA(close, slow) return {"ewo": nan_to_null(real.tolist()[-limit:]), "info": []}