def money_flow_index(close_data, high_data, low_data, volume, period): """ Money Flow Index. Formula: MFI = 100 - (100 / (1 + PMF / NMF)) """ catch_errors.check_for_input_len_diff( close_data, high_data, low_data, volume ) catch_errors.check_for_period_error(close_data, period) mf = money_flow(close_data, high_data, low_data, volume) tp = typical_price(close_data, high_data, low_data) flow = [tp[idx] > tp[idx-1] for idx in range(1, len(tp))] pf = [mf[idx] if flow[idx] else 0 for idx in range(0, len(flow))] nf = [mf[idx] if not flow[idx] else 0 for idx in range(0, len(flow))] pmf = [sum(pf[idx+1-period:idx+1]) for idx in range(period-1, len(pf))] nmf = [sum(nf[idx+1-period:idx+1]) for idx in range(period-1, len(nf))] # Dividing by 0 is not an issue, it turns the value into NaN which we would # want in that case with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) money_ratio = np.array(pmf) / np.array(nmf) mfi = 100 - (100 / (1 + money_ratio)) mfi = fill_for_noncomputable_vals(close_data, mfi) return mfi
def chande_momentum_oscillator(close_data, period): """ Chande Momentum Oscillator. Formula: cmo = 100 * ((sum_up - sum_down) / (sum_up + sum_down)) """ catch_errors.check_for_period_error(close_data, period) close_data = np.array(close_data) moving_period_diffs = map( lambda idx: map( lambda i: (close_data[idx + 1 - period:idx + 1][i] - close_data[ idx + 1 - period:idx + 1][i - 1]), range(1, len(close_data[idx + 1 - period:idx + 1]))), range(0, len(close_data))) sum_up = [] sum_down = [] for period_diffs in moving_period_diffs: ups = map(lambda val: val if val > 0 else 0, period_diffs) sum_up.append(sum(ups)) downs = map(lambda val: abs(val) if val < 0 else 0, period_diffs) sum_down.append(sum(downs)) sum_up = np.array(sum_up) sum_down = np.array(sum_down) # numpy is able to handle dividing by zero and makes those calculations # nans which is what we want, so we safely suppress the RuntimeWarning with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) cmo = 100 * ((sum_up - sum_down) / (sum_up + sum_down)) return cmo
def chaikin_money_flow(close_data, high_data, low_data, volume, period): """ Chaikin Money Flow. Formula: CMF = SUM[(((Cn - Ln) - (Hn - Cn)) / (Hn - Ln)) * V] / SUM(Vn) """ catch_errors.check_for_input_len_diff(close_data, high_data, low_data, volume) catch_errors.check_for_period_error(close_data, period) close_data = np.array(close_data) high_data = np.array(high_data) low_data = np.array(low_data) volume = np.array(volume) cmf = [ sum((((close_data[idx + 1 - period:idx + 1] - low_data[idx + 1 - period:idx + 1]) - (high_data[idx + 1 - period:idx + 1] - close_data[idx + 1 - period:idx + 1])) / (high_data[idx + 1 - period:idx + 1] - low_data[idx + 1 - period:idx + 1])) * volume[idx + 1 - period:idx + 1]) / sum(volume[idx + 1 - period:idx + 1]) for idx in range(period - 1, len(close_data)) ] cmf = fill_for_noncomputable_vals(close_data, cmf) return cmf
def relative_strength_index(self, data, period): """ Relative Strength Index. Formula: RSI = 100 - (100 / 1 + (prevGain/prevLoss)) """ catch_errors.check_for_period_error(data, period) period = int(period) self.changes = [ data_tup[1] - data_tup[0] for data_tup in zip(data[::1], data[1::1]) ] filtered_gain = [val < 0 for val in self.changes] self.gains = [ 0 if filtered_gain[idx] is True else self.changes[idx] for idx in range(0, len(filtered_gain)) ] filtered_loss = [val > 0 for val in self.changes] self.losses = [ 0 if filtered_loss[idx] is True else abs(self.changes[idx]) for idx in range(0, len(filtered_loss)) ] self.avg_gain = np.mean(self.gains[:period]) self.avg_loss = np.mean(self.losses[:period]) # first value rsi = [] if self.avg_loss == 0: rsi.append(100) else: rs = self.avg_gain / self.avg_loss rsi.append(100 - (100 / (1 + rs))) # others for idx in range(1, len(data) - period): avg_gain = ((self.avg_gain * (period - 1) + self.gains[idx + (period - 1)]) / period) avg_loss = ((self.avg_loss * (period - 1) + self.losses[idx + (period - 1)]) / period) if avg_loss == 0: rsi.append(100) else: rs = avg_gain / avg_loss rsi.append(100 - (100 / (1 + rs))) rsi = fill_for_noncomputable_vals(data, rsi) self.rsi = rsi return rsi
def smoothed_moving_average(data, period): """ Smoothed Moving Average. Formula: smma = avg(data(n)) - avg(data(n)/n) + data(t)/n """ catch_errors.check_for_period_error(data, period) series = pd.Series(data) return series.ewm(alpha = 1.0/period).mean().values.flatten()
def avg_helper(close_data, low_data, period): catch_errors.check_for_input_len_diff(close_data, low_data) catch_errors.check_for_period_error(close_data, period) bp = buying_pressure(close_data, low_data) tr = true_range(close_data, period) avg = map( lambda idx: sum(bp[idx + 1 - period:idx + 1]) / sum(tr[ idx + 1 - period:idx + 1]), range(period - 1, len(close_data))) avg = fill_for_noncomputable_vals(close_data, avg) return avg
def conversion_base_line_helper(data, period): """ The only real difference between TenkanSen and KijunSen is the period value """ catch_errors.check_for_period_error(data, period) cblh = [(np.max(data[idx+1-period:idx+1]) + np.min(data[idx+1-period:idx+1])) / 2 for idx in range(period-1, len(data))] cblh = fill_for_noncomputable_vals(data, cblh) return cblh
def average_true_range_percent(close_data, period): """ Average True Range Percent. Formula: ATRP = (ATR / CLOSE) * 100 """ catch_errors.check_for_period_error(close_data, period) atrp = (atr(close_data, period) / np.array(close_data)) * 100 return atrp
def aroon_oscillator(data, period): """ Aroon Oscillator. Formula: AO = AROON_UP(PERIOD) - AROON_DOWN(PERIOD) """ catch_errors.check_for_period_error(data, period) period = int(period) return aroon_up(data, period) - aroon_down(data, period)
def double_exponential_moving_average(data, period): """ Double Exponential Moving Average. Formula: DEMA = 2*EMA - EMA(EMA) """ catch_errors.check_for_period_error(data, period) dema = (2 * ema(data, period)) - ema(ema(data, period), period) return dema
def hull_moving_average(data, period): """ Hull Moving Average. Formula: HMA = WMA(2*WMA(n/2) - WMA(n)), sqrt(n) """ catch_errors.check_for_period_error(data, period) hma = wma(2 * wma(data, int(period / 2)) - wma(data, period), int(np.sqrt(period))) return hma
def triangular_moving_average(data, period): """ Triangular Moving Average. Formula: TMA = SMA(SMA()) """ catch_errors.check_for_period_error(data, period) tma = sma(sma(data, period), period) return tma
def lower_price_channel(data, period, lower_percent): """ Lower Price Channel. Formula: lpc = EMA(t) * (1 - lower_percent / 100) """ catch_errors.check_for_period_error(data, period) emas = ema(data, period) lower_channel = [val * (1 - float(lower_percent) / 100) for val in emas] return lower_channel
def detrended_price_oscillator(data, period): """ Detrended Price Oscillator. Formula: DPO = DATA[i] - Avg(DATA[period/2 + 1]) """ catch_errors.check_for_period_error(data, period) period = int(period) dop = [data[idx] - np.mean(data[idx+1-(int(period/2)+1):idx+1]) for idx in range(period-1, len(data))] dop = fill_for_noncomputable_vals(data, dop) return dop
def moving_average_convergence_divergence(data, short_period, long_period): """ Moving Average Convergence Divergence. Formula: EMA(DATA, P1) - EMA(DATA, P2) """ catch_errors.check_for_period_error(data, short_period) catch_errors.check_for_period_error(data, long_period) macd = ema(data, short_period) - ema(data, long_period) return macd
def upper_price_channel(data, period, upper_percent): """ Upper Price Channel. Formula: upc = EMA(t) * (1 + upper_percent / 100) """ catch_errors.check_for_period_error(data, period) emas = ema(data, period) upper_channel = [val * (1 + float(upper_percent) / 100) for val in emas] return upper_channel
def momentum(data, period): """ Momentum. Formula: DATA[i] - DATA[i - period] """ catch_errors.check_for_period_error(data, period) momentum = [data[idx] - data[idx+1-period] for idx in range(period-1, len(data))] momentum = fill_for_noncomputable_vals(data, momentum) return momentum
def commodity_channel_index(close_data, high_data, low_data, period): """ Commodity Channel Index. Formula: CCI = (TP - SMA(TP)) / (0.015 * Mean Deviation) """ catch_errors.check_for_input_len_diff(close_data, high_data, low_data) catch_errors.check_for_period_error(close_data, period) tp = typical_price(close_data, high_data, low_data) cci = ((tp - sma(tp, period)) / (0.015 * np.mean(np.absolute(tp - np.mean(tp))))) return cci
def standard_variance(data, period): """ Standard Variance. Formula: (Ct - AVGt)^2 / N """ catch_errors.check_for_period_error(data, period) sv = map(lambda idx: np.var(data[idx + 1 - period:idx + 1], ddof=1), range(period - 1, len(data))) sv = fill_for_noncomputable_vals(data, sv) return sv
def triple_exponential_moving_average(data, period): """ Triple Exponential Moving Average. Formula: TEMA = (3*EMA - 3*EMA(EMA)) + EMA(EMA(EMA)) """ catch_errors.check_for_period_error(data, period) tema = ((3 * ema(data, period) - (3 * ema(ema(data, period), period))) + ema(ema(ema(data, period), period), period) ) return tema
def rate_of_change(data, period): """ Rate of Change. Formula: (Close - Close n periods ago) / (Close n periods ago) * 100 """ catch_errors.check_for_period_error(data, period) rocs = [((data[idx] - data[idx - (period - 1)]) / data[idx - (period - 1)]) * 100 for idx in range(period - 1, len(data))] rocs = fill_for_noncomputable_vals(data, rocs) return rocs
def bb_range(data, period, std=2.0): """ Range. Formula: bb_range = u_bb - l_bb """ catch_errors.check_for_period_error(data, period) period = int(period) bb_range = (upper_bollinger_band(data, period, std) - lower_bollinger_band(data, period, std)) return bb_range
def volume_oscillator(volume, short_period, long_period): """ Volume Oscillator. Formula: vo = 100 * (SMA(vol, short) - SMA(vol, long) / SMA(vol, long)) """ catch_errors.check_for_period_error(volume, short_period) catch_errors.check_for_period_error(volume, long_period) vo = (100 * ((sma(volume, short_period) - sma(volume, long_period)) / sma(volume, long_period))) return vo
def middle_bollinger_band(data, period, std=2.0): """ Middle Bollinger Band. Formula: m_bb = sma() """ catch_errors.check_for_period_error(data, period) period = int(period) mid_bb = sma(data, period) return mid_bb
def smoothed_moving_average(data, period): """ Smoothed Moving Average. Formula: smma = avg(data(n)) - avg(data(n)/n) + data(t)/n """ catch_errors.check_for_period_error(data, period) smma = map( lambda idx: ((np.mean(data[idx - (period - 1):idx + 1]) - (np.mean( data[idx - (period - 1):idx + 1]) / period) + data[idx]) / period), range(0, len(data))) smma = fill_for_noncomputable_vals(data, smma) return smma
def standard_deviation(data, period): """ Standard Deviation. Formula: std = sqrt(avg(abs(x - avg(x))^2)) """ catch_errors.check_for_period_error(data, period) stds = map(lambda idx: np.std(data[idx + 1 - period:idx + 1], ddof=1), range(period - 1, len(data))) stds = fill_for_noncomputable_vals(data, stds) return stds
def percent_bandwidth(data, period, std=2.0): """ Percent Bandwidth. Formula: %_bw = data() - l_bb() / bb_range() """ catch_errors.check_for_period_error(data, period) period = int(period) percent_bandwidth = ( (np.array(data) - lower_bollinger_band(data, period, std)) / bb_range(data, period, std)) return percent_bandwidth
def bandwidth(data, period, std=2.0): """ Bandwidth. Formula: bw = u_bb - l_bb / m_bb """ catch_errors.check_for_period_error(data, period) period = int(period) bandwidth = ((upper_bollinger_band(data, period, std) - lower_bollinger_band(data, period, std)) / middle_bollinger_band(data, period, std)) return bandwidth
def aroon_up(data, period): """ Aroon Up. Formula: AROONUP = (((PERIOD) - (PERIODS since PERIOD high)) / (PERIOD)) * 100 """ catch_errors.check_for_period_error(data, period) period = int(period) a_up = [((period - data[idx + 1 - period:idx + 1].index( np.max(data[idx + 1 - period:idx + 1]))) / float(period)) * 100 for idx in range(period - 1, len(data))] a_up = fill_for_noncomputable_vals(data, a_up) return a_up
def aroon_down(data, period): """ Aroon Down. Formula: AROONDWN = (((PERIOD) - (PERIODS SINCE PERIOD LOW)) / (PERIOD)) * 100 """ catch_errors.check_for_period_error(data, period) period = int(period) a_down = [((period - data[idx + 1 - period:idx + 1].index( np.min(data[idx + 1 - period:idx + 1]))) / float(period)) * 100 for idx in range(period - 1, len(data))] a_down = fill_for_noncomputable_vals(data, a_down) return a_down