def obv(price, volume): '''OBV''' price = utils.safe_series(price) volume = utils.safe_series(volume) obv = (roc(price) > 0).astype(int) * volume - (roc(price) <= 0).astype(int) * volume obv[0:1] = volume[0:1] obv = obv.cumsum() rval = obv utils.safe_name(rval, name='OBV') rval.index = price.index return rval
def pd_ema(arg, ratio=0.1): ''' EMA, implemented with `pandas.stats.moments.ewma` ''' span = 2.0 / (1-ratio) - 1 arg = utils.safe_series(arg) rval = ewma(arg, span=span) utils.safe_name(rval, name='pdEMA') return rval
def wilder_sum(arg, window=14): ''' An internal function of R TTR package ''' arg = utils.safe_series(arg) rval = fast.wilder_sum(arg, window) rval.name = arg.name utils.safe_name(rval, name='wilderSum') rval.index = arg.index return rval
def emv(hl, volume, window=9, ma_type='sma', vol_divisor=1000): '''EMV''' high, low = utils.safe_hl(hl) volume = utils.safe_series(volume) mid = .5 * (high + low) volume /= vol_divisor rval = (mid - mid.shift(1)) / (volume / (high - low)) rval_ma = ma.get_ma(ma_type)(rval, window) return pd.DataFrame(dict(emv=rval, maEMV=rval_ma), index=hl.index)
def trix(price, window=20, n_sig=9, ma_type='ema', percent=True): ''' Triple Smoothed Exponential Oscillator ''' warnings.warn('The parameter of n_sig is not used in TTR. So currently it is not used as well here for unittest purpose.') price = utils.safe_series(price) mafunc = ma.get_ma(ma_type) mavg0 = mafunc(price, window) mavg1 = mafunc(mavg0, window) mavg2 = mafunc(mavg1, window) if percent: trix_ = 100 * roc(mavg2, window=1, type_='discrete') else: trix_ = mavg2 - mavg2.shift(1) signal = mafunc(trix_, window) return pd.DataFrame(dict(TRIX=trix_, signal=signal), index=price.index)
def tdi(price, window=20, multiple=2): ''' Trend Detection Index ''' price = utils.safe_series(price) mom = price - price.shift(window) mom[np.isnan(mom)] = 0 di = pd.rolling_sum(mom, window) di_abs = di.abs() mom_2n_abs = pd.rolling_sum(mom.abs(), window*multiple) mom_1n_abs = pd.rolling_sum(mom.abs(), window) tdi_ = di_abs - (mom_2n_abs - mom_1n_abs) return pd.DataFrame(dict(tdi=tdi_, di=di), index=price.index)
def mfi(hlc, volume, window=14): '''MFI''' high, low, close = utils.safe_hlc(hlc) volume = utils.safe_series(volume) / 1000 price = (high+low+close) * 1.0 / 3 mf = price * volume pmf = (mf > mf.shift(1)).astype(int) * mf nmf = (mf < mf.shift(1)).astype(int) * mf mr = pd.rolling_sum(pmf, window) / pd.rolling_sum(nmf, window) rval = 100 - (100/(1 + mr)) utils.safe_name(rval, name='MFI') rval.index = hlc.index return rval
def roc(arg, window=1, type_='continuous'): arg = utils.safe_series(arg) arg = arg.astype(float) if type_ == 'continuous': rval = np.log(arg) - np.log(arg.shift(window)) elif type_ == 'discrete': rval = arg / arg.shift(window) - 1 else: raise NotImplementedError() rval.name = arg.name utils.safe_name(rval, name='ROC') rval.index = arg.index return rval
def dpo(arg, window, ma_type='sma', shift=None, percent=False): if shift is None: shift = window / 2 + 1 arg = utils.safe_series(arg) ma_fn = eval('ma.%s'%ma_type) arg_mean = ma_fn(arg, window=window) arg_mean = arg_mean.shift(-shift) if percent: rval = 100 * (arg/arg_mean - 1) else: rval = arg - arg_mean rval.name = arg.name utils.safe_name(rval, name='DPO') rval.index = arg.index return rval
def rsi(arg, window=14, ma_type='ema'): ''' Relative strength index ''' arg = utils.safe_series(arg) ma_fn = eval('ma.%s'%ma_type) last = arg.shift(1).fillna(0) diff = arg - last up = diff * (diff > 0) down = diff * (diff < 0) * -1 rs = ma_fn(up, window=window) / ma_fn(down, window=window) rval = 100 - 100 / (1+rs) rval.name = arg.name utils.safe_name(rval, name='RSI') rval.index = arg.index return rval
def sma(arg, window=10): ''' Simple Mean Average ''' arg = utils.safe_series(arg) rval = pd.rolling_mean(arg, window) utils.safe_name(rval, name='SMA') return rval