def exponential_moving_average_signal(prices, fast=50, slow=200): """Calculate slow and fast Exponential Moving Averages (EMA) and identify crossovers - i.e. when the fast EMA crosses the slow EMA from below (bullish) and from above (bearish) for a single commodity type NOTE: Computation time for this function is quite long """ from pyti.exponential_moving_average import exponential_moving_average as ema # Technical analysis python library (https://pypi.org/project/pyti/) ema_fast = pd.DataFrame(ema(prices, fast), index=prices.index) ema_slow = pd.DataFrame(ema(prices, slow), index=prices.index) signal = pd.concat([ema_fast, ema_slow], axis=1) #concatenate slow EMA and fast EMA data signal.columns = ['EMA Fast', 'EMA Slow'] signal['Signal'] = np.where( signal['EMA Slow'] < signal['EMA Fast'], 1, 0) # Compare Slow EMA to fast EMA and generate 1,0 signal signal = signal.dropna() signal['EMA Crossovers'] = signal['Signal'].diff() signal.loc[ signal['EMA Crossovers'] == -1, 'EMA Crossovers'] = 'Death Cross' # -1 : Fast EMA crosses slow EMA from above - bearish signal signal.loc[ signal['EMA Crossovers'] == 1, 'EMA Crossovers'] = 'Golden Cross' # +1 : Fast EMA crosses slow EMA from below - bullish signal signal = signal[signal['EMA Crossovers'] != 0] # Keep only observations of crossovers signal = signal.dropna() return signal
def true_strength_index(close_data): """ True Strength Index. Double Smoothed PC ------------------ PC = Current Price minus Prior Price First Smoothing = 25-period EMA of PC Second Smoothing = 13-period EMA of 25-period EMA of PC Double Smoothed Absolute PC --------------------------- Absolute Price Change |PC| = Absolute Value of Current Price minus Prior Price First Smoothing = 25-period EMA of |PC| Second Smoothing = 13-period EMA of 25-period EMA of |PC| TSI = 100 x (Double Smoothed PC / Double Smoothed Absolute PC) """ if len(close_data) < 40: raise RuntimeError("Data must have at least 40 items") pc = np.diff(close_data, 1) apc = np.abs(pc) num = ema(pc, 25) num = ema(num, 13) den = ema(apc, 25) den = ema(den, 13) tsi = 100 * num / den tsi = fill_for_noncomputable_vals(close_data, tsi) return tsi
def chaikin_oscillator(close_data, high_data, low_data, volume, short_period=3, long_period=10): """ Chaikin Oscillator (CHO). Chaikin Accumulation Distribution Line (ADL). Formula: ADL = M(Period-1) + M(Period) CHO = ADL = 3day EMA(ADL) - 10day EMA(ADL) """ ac = [] val_last = 0 for index in range(0, len(close_data)): if high_data[index] != low_data[index]: val = val_last + ( (close_data[index] - low_data[index]) - (high_data[index] - close_data[index])) / ( high_data[index] - low_data[index]) * volume[index] else: val = val_last ac.append(val) cho = ema(ac, short_period) - ema(ac, long_period) return cho
def construct_ma(self, candles, price_type='ask'): o, c, h, l, v = self.extract_prices(candles, price_type=price_type) slow_ma = ema(c, self.slow_ma_period) fast_ma = ema(c, self.fast_ma_period) macd = slow_ma - fast_ma macd_ewm = np.array(pd.DataFrame(macd).ewm(span=9).mean().squeeze()) return macd, macd_ewm
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 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 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 add_indicators(data, ema_period=[5, 25, 100], rsi_period=[14], prefix=""): result = None for period in ema_period: r_r = ema(data, period) df = pd.DataFrame(r_r, index=data.index, columns=[prefix + "_%dema" % period]) if result is None: result = df else: result = pd.merge(df, result, how='outer', left_index=True, right_index=True) for period in rsi_period: r_r = rsi(data, period) df = pd.DataFrame(r_r, index=data.index, columns=[prefix + "_%drsi" % period]) result = pd.merge(df, result, how='outer', left_index=True, right_index=True) return result
def percent_d(data, period): """ %D. Formula: %D = SMA(%K, 3) """ p_k = percent_k(data, period) percent_d = ema(p_k, 15) return percent_d
def add_indicators(self): self.candles = self.candles.drop(['Open_time', 'Close_time'], axis=1) self.candles['EMA - 15'] = ema(self.candles['Close'].tolist(), 15) self.candles['aaron down'] = aroon_down(self.candles['Close'].tolist(), 25) self.candles['aaron up'] = aroon_up(self.candles['Close'].tolist(), 25) self.candles['tenkansen'] = tenkansen(self.candles['Close'].tolist()) self.candles['kijunsen'] = kijunsen(self.candles['Close'].tolist()) self.candles['momentun'] = momentum(self.candles['Close'], 15) return self.candles
def prepare_data(symbol): coin = symbol coin_1 = crypto_data(coin) df = coin_1 df['SMA_20'] = sma(df['Close'], 20) df['SMA_50'] = sma(df['Close'], 50) df['EMA_20'] = ema(df['Close'], 20) df['EMA_50'] = ema(df['Close'], 50) df['MACD'] = macd(df['Close'], 26, 12) df['per_k_stoch_10'] = percent_k(df['Close'], 10) df['per_d_stoch_10'] = percent_d(df['Close'], 10) df['OBV'] = obv(df['Close'], df['Volume']) fp = [] for price in df['Close']: fp.append(price) fp.pop(0) fp.append(df['Close'].mean()) df['FP'] = fp df_predict = df.tail(1) df.drop(df.tail(1).index, inplace=True) label = [] for i in range(len(df)): if df['FP'][i] > df['Close'][i]: label.append(1) else: label.append(0) df['goes_up'] = label df = df.drop(['FP'], axis=1) df = df.fillna(df.mean()) df_predict = df_predict.drop(['FP'], axis=1) return df, df_predict
def next_calculation(self, candle): if self.get_datawindow() is not None: md = macd(self.get_close(), self.params['short_window'], self.periods)[-1] self.macd.append(md) signal = ema(self.macd, self.params['signal_window']) self.value = { 'macd': md, 'signal': signal[-1], 'crossover': md - signal[-1] }
def check_trend_ema(params): limit = params['limit'] prices = [trade['price'] for trade in get_trades(params, limit)] result = ema(prices, params['period']) change_rate = (result[-1] / result[-2]) trend = "UP" if ( 1 + params['decision_rate_up'] < change_rate) else "DOWN" if ( 1 - params['decision_rate_down'] > change_rate) else None return trend
def next_calculation(self, candle): """get latest candles from market, do calculation, write results to db""" dataset = self.market.candles[self.interval] # save reference of market candles for read-ability if len(dataset) >= self.periods: # check that enough market candles are available for calculation # take slice of correct number of candles data_window = dataset[-self.periods:] # take list of close values from candles data = list(c[4] for c in data_window) self.value = round( ema(data, self.periods)[-1], 6) # update current value
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 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 macd_func(indices, presences, data): presence = np.mean([presences]) if presence > 52.5: if indices[0] > indices[1]: indices[0], indices[1] = indices[1], indices[0] print("indices: " + str(indices[0]) + " " + str(indices[1])) values = "(" + str(indices[0]) + "," + str(indices[1]) + ")" data['macd' + values] = macd(data['Close'].values, indices[0], indices[1]) data['macd_sign'] = ema(data['macd' + values].values, 9) data['macd_hist'] = data['macd' + values].values - data['macd_sign'].values return data
def on_new_trade(self, key: Key, trade: Trade) -> None: if not self.bar: self.bar = Bar(trade) b_t = self.price_change(trade) self.b_ts.append(b_t) self.theta += b_t self.bar.append(trade) self.last_trade = trade if np.abs(self.theta) >= np.abs(self.expected_theta): self.t_vals.append(self.bar.count) window = 5 if len(self.t_vals) > window: expected_T = ema(self.t_vals, window)[-1] else: expected_T = self.t_vals[-1] namespace = key[1] self._build_new_bar(trade, namespace) self.theta = 0 logger.info(f"Expected T: {expected_T}") # print(ema(self.b_ts, 10)) probability = ema(self.b_ts, 10)[-1] self.expected_theta = expected_T * (2 * probability - 1) logger.info(self.expected_theta)
def center_band(close_data, high_data, low_data, period, exp=False): """ Center Band. Formula: CB = SMA(TP) """ tp = typical_price(close_data, high_data, low_data) if exp: cb = ema(tp, period) else: cb = sma(tp, period) return cb
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 = map( lambda idx: data[idx] - np.min(data[idx+1-period:idx+1]), range(period-1, len(data)) ) sm_lows = ema(ema(lows, period), period) highs = map( lambda idx: np.max(data[idx+1-period:idx+1]) - np.min(data[idx+1-period:idx+1]), 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
def band_width(high_data, low_data, period, exp=False): """ Bandwidth. Formula: BW = SMA(H - L) """ catch_errors.check_for_input_len_diff(high_data, low_data) diff = np.array(high_data) - np.array(low_data) if exp: bw = ema(diff, period) else: bw = sma(diff, period) return bw
def check_trend(): global rates result = [0] change_rate = 0 trend = 'NONE' ticker = exchanger.fetch_ticker(SYMBOL) last = ticker['last'] ask, bid, spread = get_ticker(exchanger) rates.append(last) if len(rates) >= PERIOD: result = ema(rates, PERIOD) change_rate = (result[-1] / result[-2]) trend = "UP" if (1 + DECISION_RATE_UP < change_rate) else "DOWN" if (1 - DECISION_RATE_DOWN > change_rate) else "NONE" if len(rates) > RATES_SIZE_MAX: rates.pop(0) log(ask, last, bid, spread, result[-1], change_rate, trend) return trend
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
start=dt.datetime(2016, 1, 1), end=dt.datetime(2018, 6, 10)) #df = pd.read_csv('historical_data.csv', index_col = 0) """<h3>Define the EMA Strategy</h3>""" # Define our pip cost and lot size pip_cost = .0911 lot_size = 10 # Define our EMA Fast / Slow parameters ema_fast = 12 ema_slow = 20 # Populate our dataframe with fast and slow EMA figures df['mva_fast'] = ema(df['askclose'], ema_fast) df['mva_slow'] = ema(df['askclose'], ema_slow) # When the EMA fast crosses the EMA slow, a buy signal is triggered df['signal'] = np.where(df['mva_fast'] > df['mva_slow'], 1, 0) df['position'] = df['signal'].diff() # Check on the dataframe to see the newly created columns df """<h3>A Simple Backtest</h3>""" begin_prices = [] end_prices = [] profits = 0
def ema(data, period): return ema(data, period)
if __name__ == '__main__': cn = 0 data = [] inventory = [] while cn < 100: close = get_historic_klines(symbol, "2 days ago UTC", "now UTC", Client.KLINE_INTERVAL_5MINUTE) ochl = get_historic_klines_ochl(symbol, "2 days ago UTC", "now UTC", Client.KLINE_INTERVAL_5MINUTE) source = close data.append(source[-1]) fastLength = 12 slowLength = 26 # take from binance signalLength = 9 fastMA = ema(source, fastLength) slowMA = ema(source, slowLength) macd = fastMA - slowMA signal = sma(macd, signalLength) hist = macd - signal stochastic_data = get_historic_klines_stochastic( symbol, "20 days ago UTC", "now UTC", Client.KLINE_INTERVAL_1DAY) stochastic_li = stochastic_data['%K'].tolist() decision(hist, stochastic_li, data, inventory) cn += 1 #decision(macdo,signalo) """ final = histo.join(macdo, lsuffix='_left', rsuffix='_right')
def macd_signal(data): # data is macd signal = ema(data, 9) return signal
def ema(self, df): period = 9 if len(df) < period: period = len(df) // 2 data = ema(df, period) return (data)
def primitive(data): """ Function return result """ quotes = {} quotes['open']=numpy.asarray([item['open'] for item in data]) quotes['close']=numpy.asarray([item['close'] for item in data]) # quotes['high']=numpy.asarray([item['high'] for item in data]) # quotes['low']=numpy.asarray([item['low'] for item in data]) # xdate = quotes['timestamp']=numpy.asarray([item['timestamp'] for item in data]) open=quotes['open'] open=open[-1] close=quotes['close'] close=close[-1] usebody = True # /* # * Logic # * # */ # // Рассчитывается размер тела свечи # // body = abs(close - open) body = abs(close - open) print("Body: ", body) # Рассчитывается средний размер тел свечей ( EMA за 30 последних свечей) # sbody = ema(body, 30) / 2 bodyArray = [] bodyArray.append(abs(quotes['close'] - quotes['open'])) # print("BodyArray: ", bodyArray[0]) new_ema = ema(bodyArray[0], 30) # print("EMA: ", new_ema) sbody = new_ema[-1] print("EMA: ", sbody) # выводим Ema sbody = sbody/2 print("Sbody: ", sbody) # bar = close > open ? 1 : close < open ? -1 : 0 bar = None # // Свеча зеленая if (close > open): bar = "green" print(f'Close: {close} > Open: {open}') print("Bar: ", bar) # // Свеча красная elif(close < open): bar = "red" print(f"Close: {close} < Open: {open}") print("Bar: ", bar) # // Ничего не произошло else: bar = "still" print('Close: %(close)f < Open: %(open)f' % {close, open}) print("Bar: ", bar) # stop = 1 # /* # * Signals # * # */ # // Если свеча красная, и тело больше половины среднего - открыть лонг (и закрыть шорт, если шорт был открыт) # // Если свеча зеленая, тело больше половины среднего и позиция прибыльная - закрыть лонг # // Если свеча зеленая, тело больше половины среднего - открыть шорт (и закрыть лонг, если лонг был открыт) # // Если свеча красная, тело больше половины среднего и позиция прибыльная - закрыть шорт # // up = bar == -1 and (body > sbody or usebody == false) and (close < strategy.position_avg_price or strategy.position_size <= 0 or useus == false) up = None # // Если свеча красная, и тело больше половины среднего - открыть лонг (и закрыть шорт, если шорт был открыт) if (bar == 'red' and (body > sbody or usebody == False)): up = True print(f"Bar: {bar}, Body: {body} > SBody: {sbody}, Up = true") # // dn = bar == 1 and (body > sbody or usebody == false) and (close > strategy.position_avg_price or strategy.position_size >= 0 or useus == false) down = None if(bar == 'green' and (body > sbody or usebody == False)): down = True print(f"Bar: {bar}, Body: {body} > SBody: {sbody}, Down = true") if up: return 'up' elif down: return 'down' else: return 'hold'
def exponential_moving_average(data, period): return ema(data, period)