def true_range(high_ts, low_ts, close_ts): """Calculate true range.""" prev_close = generic_nb.fshift_nb(close_ts, 1) tr1 = high_ts - low_ts tr2 = np.abs(high_ts - prev_close) tr3 = np.abs(low_ts - prev_close) tr = nanmax_cube_nb(np.stack((tr1, tr2, tr3))) return tr
def atr_caching_nb(close_ts, high_ts, low_ts, windows, ewms): """Caching function for `vectorbt.indicators.basic.ATR`.""" # Calculate TR here instead of re-calculating it for each param in atr_apply_nb tr0 = high_ts - low_ts tr1 = np.abs(high_ts - generic_nb.fshift_nb(close_ts, 1)) tr2 = np.abs(low_ts - generic_nb.fshift_nb(close_ts, 1)) tr = nanmax_cube_nb(np.stack((tr0, tr1, tr2))) cache_dict = dict() for i in range(windows.shape[0]): h = hash((windows[i], ewms[i])) if h not in cache_dict: if ewms[i]: atr = generic_nb.ewm_mean_nb(tr, windows[i]) else: atr = generic_nb.rolling_mean_nb(tr, windows[i]) cache_dict[h] = atr return tr, cache_dict
def true_range_nb(high, low, close): """Calculate true range.""" prev_close = generic_nb.fshift_nb(close, 1) tr1 = high - low tr2 = np.abs(high - prev_close) tr3 = np.abs(low - prev_close) tr = np.empty(prev_close.shape, dtype=np.float_) for col in range(tr.shape[1]): for i in range(tr.shape[0]): tr[i, col] = max(tr1[i, col], tr2[i, col], tr3[i, col]) return tr
def obv_custom_func_nb(close_ts, volume_ts): """Custom calculation function for `vectorbt.indicators.basic.OBV`.""" obv = generic_nb.set_by_mask_mult_nb(volume_ts, close_ts < generic_nb.fshift_nb(close_ts, 1), -volume_ts) obv = generic_nb.cumsum_nb(obv) return obv
def obv_custom_nb(close: tp.Array2d, volume_ts: tp.Array2d) -> tp.Array2d: """Custom calculation function for `vectorbt.indicators.basic.OBV`.""" obv = generic_nb.set_by_mask_mult_nb( volume_ts, close < generic_nb.fshift_nb(close, 1), -volume_ts) obv = generic_nb.nancumsum_nb(obv) return obv