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 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 = [[ (close_data[idx + 1 - period:idx + 1][i] - close_data[idx + 1 - period:idx + 1][i - 1]) for i in range(1, len(close_data[idx + 1 - period:idx + 1])) ] for idx in range(0, len(close_data))] sum_up = [] sum_down = [] for period_diffs in moving_period_diffs: ups = [val if val > 0 else 0 for val in period_diffs] sum_up.append(sum(ups)) downs = [abs(val) if val < 0 else 0 for val in 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 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 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 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 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 = [ sum(bp[idx + 1 - period:idx + 1]) / sum(tr[idx + 1 - period:idx + 1]) for idx in 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 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 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 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 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 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 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 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 relative_strength_index(data, period): """ Relative Strength Index. Formula: RSI = 100 - (100 / 1 + (prevGain/prevLoss)) """ catch_errors.check_for_period_error(data, period) period = int(period) changes = [ data_tup[1] - data_tup[0] for data_tup in zip(data[::1], data[1::1]) ] filtered_gain = [val < 0 for val in changes] gains = [ 0 if filtered_gain[idx] is True else changes[idx] for idx in range(0, len(filtered_gain)) ] filtered_loss = [val > 0 for val in changes] losses = [ 0 if filtered_loss[idx] is True else abs(changes[idx]) for idx in range(0, len(filtered_loss)) ] avg_gain = np.mean(gains[:period]) avg_loss = np.mean(losses[:period]) rsi = [] if avg_loss == 0: rsi.append(100) else: rs = avg_gain / avg_loss rsi.append(100 - (100 / (1 + rs))) for idx in range(1, len(data) - period): avg_gain = ((avg_gain * (period - 1) + gains[idx + (period - 1)]) / period) avg_loss = ((avg_loss * (period - 1) + 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) return rsi
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 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 price_oscillator(data, short_period, long_period): """ Price Oscillator. Formula: (short EMA - long EMA / long EMA) * 100 """ catch_errors.check_for_period_error(data, short_period) catch_errors.check_for_period_error(data, long_period) ema_short = ema(data, short_period) ema_long = ema(data, long_period) po = ((ema_short - ema_long) / ema_long) * 100 return po
def percent_k(data, period): """ %K. Formula: %k = data(t) - low(n) / (high(n) - low(n)) """ catch_errors.check_for_period_error(data, period) percent_k = [((data[idx] - np.min(data[idx + 1 - period:idx + 1])) / (np.max(data[idx + 1 - period:idx + 1]) - np.min(data[idx + 1 - period:idx + 1]))) for idx in range(period - 1, len(data))] percent_k = fill_for_noncomputable_vals(data, percent_k) return percent_k
def exponential_moving_average(data, period): """ Exponential Moving Average. Formula: p0 + (1 - w) * p1 + (1 - w)^2 * p2 + (1 + w)^3 * p3 +... / 1 + (1 - w) + (1 - w)^2 + (1 - w)^3 +... where: w = 2 / (N + 1) """ catch_errors.check_for_period_error(data, period) emas = [exponential_moving_average_helper( data[idx - period + 1:idx + 1], period) for idx in range(period - 1, len(data))] emas = fill_for_noncomputable_vals(data, emas) return emas
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 - list(reversed(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
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 - list(reversed(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 standard_variance(data, period): """ Standard Variance. Formula: (Ct - AVGt)^2 / N """ catch_errors.check_for_period_error(data, period) sv = [ np.var(data[idx + 1 - period:idx + 1], ddof=1) for idx in range(period - 1, len(data)) ] sv = fill_for_noncomputable_vals(data, sv) return sv
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 = [ ((np.mean(data[idx - (period - 1):idx + 1]) - (np.mean(data[idx - (period - 1):idx + 1]) / period) + data[idx]) / period) for idx in range(0, len(data)) ] smma = fill_for_noncomputable_vals(data, smma) return smma
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 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 double_smoothed_stochastic(data, period): """ Double Smoothed Stochastic. Formula: dss = 100 * EMA(Close - Lowest Low) / EMA(Highest High - Lowest Low) """ catch_errors.check_for_period_error(data, period) lows = [data[idx] - np.min(data[idx+1-period:idx+1]) for idx in range(period-1, len(data))] sm_lows = ema(ema(lows, period), period) highs = [np.max(data[idx+1-period:idx+1]) - np.min(data[idx+1-period:idx+1]) for idx in range(period-1, len(data))] sm_highs = ema(ema(highs, period), period) dss = (sm_lows / sm_highs) * 100 dss = fill_for_noncomputable_vals(data, dss) return dss