def damiani_volatmeter(candles: np.ndarray, vis_atr: int = 13, vis_std: int = 20, sed_atr: int = 40, sed_std: int = 100, threshold: float = 1.4, source_type: str = "close", sequential: bool = False) -> DamianiVolatmeter: """ Damiani Volatmeter :param candles: np.ndarray :param vis_atr: int - default=13 :param vis_std: int - default=20 :param sed_atr: int - default=40 :param sed_std: int - default=100 :param threshold: float - default=1.4 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ warmup_candles_num = get_config('env.data.warmup_candles_num', 240) if not sequential and len(candles) > warmup_candles_num: candles = candles[-warmup_candles_num:] source = get_candle_source(candles, source_type=source_type) atrvis = talib.ATR(candles[:, 3], candles[:, 4], candles[:, 2], timeperiod=vis_atr) atrsed = talib.ATR(candles[:, 3], candles[:, 4], candles[:, 2], timeperiod=sed_atr) vol, t = damiani_volatmeter_fast(source, sed_std, atrvis, atrsed, vis_std, threshold) if sequential: return DamianiVolatmeter(vol, t) else: return DamianiVolatmeter(vol[-1], t[-1])
def vlma(candles: np.ndarray, min_period: int = 5, max_period: int = 50, matype: int = 0, devtype: int = 0, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Variable Length Moving Average :param candles: np.ndarray :param min_period: int - default: 5 :param max_period: int - default: 50 :param matype: int - default: 0 :param devtype: int - default: 0 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ # Accept normal array too. if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) mean = ma(source, period=max_period, matype=matype, sequential=True) if devtype == 0: stdDev = talib.STDDEV(source, max_period) elif devtype == 1: stdDev = mean_ad(source, max_period, sequential=True) elif devtype == 2: stdDev = median_ad(source, max_period, sequential=True) a = mean - (1.75 * stdDev) b = mean - (0.25 * stdDev) c = mean + (0.25 * stdDev) d = mean + (1.75 * stdDev) res = vlma_fast(source, a, b, c, d, min_period, max_period) return res if sequential else res[-1]
def decycler(candles: np.ndarray, hp_period: int = 125, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ Ehlers Simple Decycler :param candles: np.ndarray :param hp_period: int - default=125 :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) hp = high_pass_2_pole_fast(source, hp_period) res = source - hp return res if sequential else res[-1]
def cg(candles: np.ndarray, period: int = 10, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ Center of Gravity (CG) :param candles: np.ndarray :param period: int - default: 10 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = go_fast(source, period) return same_length(candles, res) if sequential else res[-1]
def smma(candles: np.ndarray, period: int = 5, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ SMMA - Smoothed Moving Average :param candles: np.ndarray :param period: int - default: 5 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = numpy_ewma(source, period) return res if sequential else res[-1]
def tsf(candles: np.ndarray, period: int = 14, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ TSF - Time Series Forecast :param candles: np.ndarray :param period: int - default: 14 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.TSF(source, timeperiod=period) return res if sequential else res[-1]
def midpoint(candles: np.ndarray, period: int = 14, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ MIDPOINT - MidPoint over period :param candles: np.ndarray :param period: int - default: 14 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.MIDPOINT(source, timeperiod=period) return res if sequential else res[-1]
def dpo(candles: np.ndarray, period: int = 5, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ DPO - Detrended Price Oscillator :param candles: np.ndarray :param period: int - default: 5 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = ti.dpo(np.ascontiguousarray(source), period=period) return same_length(candles, res) if sequential else res[-1]
def vwma(candles: np.ndarray, period=20, source_type="close", sequential=False) -> Union[float, np.ndarray]: """ VWMA - Volume Weighted Moving Average :param candles: np.ndarray :param period: int - default: 20 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = ti.vwma(np.ascontiguousarray(source), np.ascontiguousarray(candles[:, 5]), period=period) return np.concatenate((np.full((candles.shape[0] - res.shape[0]), np.nan), res), axis=0) if sequential else res[-1]
def mom(candles: np.ndarray, period: int = 10, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ MOM - Momentum :param candles: np.ndarray :param period: int - default=10 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.MOM(source, timeperiod=period) return res if sequential else res[-1]
def trima(candles: np.ndarray, period: int = 30, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ TRIMA - Triangular Moving Average :param candles: np.ndarray :param period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.TRIMA(source, timeperiod=period) return res if sequential else res[-1]
def roc(candles: np.ndarray, period: int = 10, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ ROC - Rate of change : ((price/prevPrice)-1)*100 :param candles: np.ndarray :param period: int - default=10 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.ROC(source, timeperiod=period) return res if sequential else res[-1]
def wilders(candles: np.ndarray, period=5, source_type="close", sequential=False) -> Union[float, np.ndarray]: """ WILDERS - Wilders Smoothing :param candles: np.ndarray :param period: int - default: 5 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = ti.wilders(np.ascontiguousarray(source), period=period) return np.concatenate((np.full((candles.shape[0] - res.shape[0]), np.nan), res), axis=0) if sequential else res[-1]
def dema(candles: np.ndarray, period=30, source_type="close", sequential=False) -> Union[float, np.ndarray]: """ DEMA - Double Exponential Moving Average :param candles: np.ndarray :param period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = talib.DEMA(source, timeperiod=period) return res if sequential else res[-1]
def ht_trendmode(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ HT_TRENDMODE - Hilbert Transform - Trend vs Cycle Mode :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default=False :return: int | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.HT_TRENDMODE(source) return res if sequential else res[-1]
def linearreg(candles: np.ndarray, period: int = 14, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ LINEARREG - Linear Regression :param candles: np.ndarray :param period: int - default: 14 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.LINEARREG(source, timeperiod=period) return res if sequential else res[-1]
def ht_dcphase(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ HT_DCPHASE - Hilbert Transform - Dominant Cycle Phase :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.HT_DCPHASE(source) return res if sequential else res[-1]
def stc(candles: np.ndarray, fast_period: int = 23, fast_matype: int = 1, slow_period: int = 50, slow_matype: int = 1, k_period: int = 10, d_period: int = 3, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ STC - Schaff Trend Cycle (Oscillator) :param candles: np.ndarray :param fast_period: int - default: 23 :param fastmatype: int - default: 1 :param slow_period: int - default: 50 :param slowmatype: int - default: 1 :param k_period: int - default: 10 :param d_period: int - default: 3 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) macd = ma( source, period=fast_period, matype=fast_matype, sequential=True) - ma( source, period=slow_period, matype=slow_matype, sequential=True) stok = (macd - talib.MIN(macd, k_period)) / ( talib.MAX(macd, k_period) - talib.MIN(macd, k_period)) * 100 d = talib.EMA(stok, d_period) kd = (d - talib.MIN(d, k_period)) / (talib.MAX(d, k_period) - talib.MIN(d, k_period)) * 100 res = talib.EMA(kd, d_period) return res if sequential else res[-1]
def damiani_volatmeter(candles: np.ndarray, vis_atr: int = 13, vis_std: int = 20, sed_atr: int = 40, sed_std: int = 100, threshold: float = 1.4, source_type: str = "close", sequential: bool = False) -> DamianiVolatmeter: """ Damiani Volatmeter :param candles: np.ndarray :param vis_atr: int - default: 13 :param vis_std: int - default: 20 :param sed_atr: int - default: 40 :param sed_std: int - default: 100 :param threshold: float - default: 1.4 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) atrvis = talib.ATR(candles[:, 3], candles[:, 4], candles[:, 2], timeperiod=vis_atr) atrsed = talib.ATR(candles[:, 3], candles[:, 4], candles[:, 2], timeperiod=sed_atr) vol, t = damiani_volatmeter_fast(source, sed_std, atrvis, atrsed, vis_std, threshold) if sequential: return DamianiVolatmeter(vol, t) else: return DamianiVolatmeter(vol[-1], t[-1])
def ht_phasor(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> IQ: """ HT_PHASOR - Hilbert Transform - Phasor Components :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default: False :return: IQ(inphase, quadrature) """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) inphase, quadrature = talib.HT_PHASOR(source) if sequential: return IQ(inphase, quadrature) else: return IQ(inphase[-1], quadrature[-1])
def fosc(candles: np.ndarray, period: int = 5, source_type: str = "close", sequential: bool = False) -> Union[ float, np.ndarray]: """ FOSC - Forecast Oscillator :param candles: np.ndarray :param period: int - default: 5 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = ti.fosc(np.ascontiguousarray(source), period=period) return np.concatenate((np.full((candles.shape[0] - res.shape[0]), np.nan), res), axis=0) if sequential else res[-1]
def pvi(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ PVI - Positive Volume Index :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = ti.pvi(np.ascontiguousarray(source), np.ascontiguousarray(candles[:, 5])) return same_length(candles, res) if sequential else res[-1]
def ht_sine(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> SINEWAVE: """ HT_SINE - Hilbert Transform - SineWave :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default=False :return: SINEWAVE(sine, lead) """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) sine, leadsine = talib.HT_SINE(source) if sequential: return SINEWAVE(sine, leadsine) else: return SINEWAVE(sine[-1], leadsine[-1])
def maaq(candles: np.ndarray, period: int = 11, fast_period: int = 2, slow_period: int = 30, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Moving Average Adaptive Q :param candles: np.ndarray :param period: int - default: 11 :param fast_period: int - default: 2 :param slow_period: int - default: 30 :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ # Accept normal array too. if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) source = source[~np.isnan(source)] diff = np.abs(source - np_shift(source, 1, np.nan)) signal = np.abs(source - np_shift(source, period, np.nan)) noise = talib.SUM(diff, period) with np.errstate(divide='ignore'): ratio = np.where(noise == 0, 0, signal / noise) fastSc = 2 / (fast_period + 1) slowSc = 2 / (slow_period + 1) temp = np.power((ratio * fastSc) + slowSc, 2) res = maaq_fast(source, temp, period) res = same_length(candles, res) return res if sequential else res[-1]
def ht_dcperiod(candles: np.ndarray, source_type="close", sequential=False) -> Union[float, np.ndarray]: """ HT_DCPERIOD - Hilbert Transform - Dominant Cycle Period :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = talib.HT_DCPERIOD(source) return res if sequential else res[-1]
def rsx(candles: np.ndarray, period: int = 14, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ Relative Strength Xtra (rsx) :param candles: np.ndarray :param period: int - default: 14 :param sequential: bool - default: False :return: float | np.ndarray """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = rsx_fast(source, period) return res if sequential else res[-1]
def ht_trendline(candles: np.ndarray, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ HT_TRENDLINE - Hilbert Transform - Instantaneous Trendline :param candles: np.ndarray :param source_type: str - default: "close" :param sequential: bool - default: False :return: float | np.ndarray """ if len(candles.shape) == 1: source = candles else: candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) res = talib.HT_TRENDLINE(source) return res if sequential else res[-1]
def linearreg_slope(candles: np.ndarray, period: int = 14, source_type: str = "close", sequential: bool = False) -> \ Union[float, np.ndarray]: """ LINEARREG_SLOPE - Linear Regression Slope :param candles: np.ndarray :param period: int - default: 14 :param source_type: str - default: "close" :param sequential: bool - default=False :return: float | np.ndarray """ if not sequential and len(candles) > 240: candles = candles[-240:] source = get_candle_source(candles, source_type=source_type) res = talib.LINEARREG_SLOPE(source, timeperiod=period) return res if sequential else res[-1]
def bollinger_bands_width( candles: np.ndarray, period: int = 20, devup: float = 2, devdn: float = 2, matype: int = 0, devtype: int = 0, source_type: str = "close", sequential: bool = False) -> Union[float, np.ndarray]: """ BBW - Bollinger Bands Width - Bollinger Bands Bandwidth :param candles: np.ndarray :param period: int - default: 20 :param devup: float - default: 2 :param devdn: float - default: 2 :param matype: int - default: 0 :param devtype: int - default: 0 :param source_type: str - default: "close" :param sequential: bool - default: False :return: BollingerBands(upperband, middleband, lowerband) """ candles = slice_candles(candles, sequential) source = get_candle_source(candles, source_type=source_type) if devtype == 0: dev = talib.STDDEV(source, period) elif devtype == 1: dev = mean_ad(source, period, sequential=True) elif devtype == 2: dev = median_ad(source, period, sequential=True) middlebands = ma(source, period=period, matype=matype, sequential=True) upperbands = middlebands + devup * dev lowerbands = middlebands - devdn * dev if sequential: return (upperbands - lowerbands) / middlebands else: return (upperbands[-1] - lowerbands[-1]) / middlebands[-1]
def test_get_candle_source(): candle = np.array( ([1575547200000, 146.51, 147.03, 149.02, 146.51, 64788.46651], [ 1553817660000, 4092.56783507, 4092.5, 4092.56783507, 4092.5, 9.0847059 ])) close = jh.get_candle_source(candle, source_type="close") assert close[-1] == 4092.5 high = jh.get_candle_source(candle, source_type="high") assert high[-1] == 4092.56783507 low = jh.get_candle_source(candle, source_type="low") assert low[-1] == 4092.5 open = jh.get_candle_source(candle, source_type="open") assert open[-1] == 4092.56783507 volume = jh.get_candle_source(candle, source_type="volume") assert volume[-1] == 9.0847059 hl2 = jh.get_candle_source(candle, source_type="hl2") assert hl2[-1] == 4092.533917535 hlc3 = jh.get_candle_source(candle, source_type="hlc3") assert hlc3[-1] == 4092.52261169 ohlc4 = jh.get_candle_source(candle, source_type="ohlc4") assert ohlc4[-1] == 4092.533917535