def return_macd_histogram_and_closing_prices_buy(stock): closing_price_list = stock['Close'].tolist() numpyclose = np.asarray(closing_price_list) macd1, macd2, macdhistogram = ti.macd( numpyclose, 8, 17, 9) # for sell signals it should be 12, 26, 9 return [list(macdhistogram)[-10:], closing_price_list[-10:]]
async def evaluate(self, cryptocurrency, symbol, time_frame, candle_data, candle): self.eval_note = commons_constants.START_PENDING_EVAL_NOTE if len(candle_data) > self.long_period_length: macd, macd_signal, macd_hist = tulipy.macd(candle_data, self.short_period_length, self.long_period_length, self.signal_period_length) # on macd hist => M pattern: bearish movement, W pattern: bullish movement # max on hist: optimal sell or buy macd_hist = data_util.drop_nan(macd_hist) zero_crossing_indexes = EvaluatorUtil.TrendAnalysis.get_threshold_change_indexes(macd_hist, 0) last_index = len(macd_hist) - 1 pattern, start_index, end_index = EvaluatorUtil.PatternAnalyser.find_pattern(macd_hist, zero_crossing_indexes, last_index) if pattern != EvaluatorUtil.PatternAnalyser.UNKNOWN_PATTERN: # set sign (-1 buy or 1 sell) sign_multiplier = -1 if pattern == "W" or pattern == "V" else 1 # set pattern time frame => W and M are on 2 time frames, others 1 pattern_move_time = 2 if (pattern == "W" or pattern == "M") and end_index == last_index else 1 # set weight according to the max value of the pattern and the current value current_pattern_start = start_index price_weight = macd_hist[-1] / macd_hist[current_pattern_start:].max() if sign_multiplier == 1 \ else macd_hist[-1] / macd_hist[current_pattern_start:].min() if not math.isnan(price_weight): self._analyse_pattern(pattern, macd_hist, zero_crossing_indexes, price_weight, pattern_move_time, sign_multiplier) await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
def eval_impl(self): self.eval_note = START_PENDING_EVAL_NOTE long_period_length = 26 if len(self.data[PriceIndexes.IND_PRICE_CLOSE.value]) >= long_period_length: macd, macd_signal, macd_hist = tulipy.macd(self.data[PriceIndexes.IND_PRICE_CLOSE.value], 12, long_period_length, 9) # on macd hist => M pattern: bearish movement, W pattern: bullish movement # max on hist: optimal sell or buy macd_hist = DataUtil.drop_nan(macd_hist) zero_crossing_indexes = TrendAnalysis.get_threshold_change_indexes(macd_hist, 0) last_index = len(macd_hist) - 1 pattern, start_index, end_index = PatternAnalyser.find_pattern(macd_hist, zero_crossing_indexes, last_index) if pattern != PatternAnalyser.UNKNOWN_PATTERN: # set sign (-1 buy or 1 sell) sign_multiplier = -1 if pattern == "W" or pattern == "V" else 1 # set pattern time frame => W and M are on 2 time frames, others 1 pattern_move_time = 2 if (pattern == "W" or pattern == "M") and end_index == last_index else 1 # set weight according to the max value of the pattern and the current value current_pattern_start = start_index price_weight = macd_hist[-1] / macd_hist[current_pattern_start:].max() if sign_multiplier == 1 \ else macd_hist[-1] / macd_hist[current_pattern_start:].min() if not math.isnan(price_weight): self._analyse_pattern(pattern, macd_hist, zero_crossing_indexes, price_weight, pattern_move_time, sign_multiplier)
def draw_macd_buy(stock, name): closing_price_list = stock['Close'].tolist() date_list = list(stock.index) numpyclose = np.asarray(closing_price_list) macd1, macd2, macdhistogram = ti.macd(numpyclose, 8, 17, 9) # for buy signals it should be 8,17,9 sma = ti.sma(numpyclose, 17) plt.figure(figsize=(15, 8)) ax1 = plt.subplot(212) ax2 = plt.subplot(211, sharex=ax1, title=name) numberofactivedays = len(date_list[16:]) arrangeddates = np.arange(numberofactivedays) ax1.plot(arrangeddates, macd1, 'r') ax1.plot(arrangeddates, macd2, 'y') ax1.bar(arrangeddates, macdhistogram) ax1.plot(arrangeddates, [0] * len(date_list[16:])) ax2.plot(arrangeddates, closing_price_list[16:]) ax2.plot(arrangeddates, sma, 'r') ax1.set_xticks(np.append(arrangeddates[0::20], arrangeddates[-1])) ax2.set_xticks(np.append(arrangeddates[0::20], arrangeddates[-1])) ax1.set_xticklabels([date.strftime("%Y-%m-%d") for date in date_list[16:]][0::20] + [[date.strftime("%Y-%m-%d") for date in date_list[16:]][-1]]) ax2.set_xticklabels([date.strftime("%Y-%m-%d") for date in date_list[16:]][0::20] + [[date.strftime("%Y-%m-%d") for date in date_list[16:]][-1]]) ax1.tick_params(rotation=30) ax2.tick_params(rotation=30) plt.show()
def macd(self): try: return macd(self.data, short_period=1, long_period=5, signal_period=10) except Exception: logging.exception('')
def add_macd(df, short=6, long=15, signal=20): # opt = {'short period':6, 'long period':15, 'signal period':20} rows = df.shape[0] (macd, macd_signal, macd_histogram) = ti.macd( np.array(df.close), short, long, signal) df[f'macd_{short}{long}{signal}'] = pad_left(macd, rows) df[f'macd_signal_{short}{long}{signal}'] = pad_left(macd_signal, rows) df[f'macd_histogram_{short}{long}{signal}'] = pad_left( macd_histogram, rows)
def macd_potential_buy(stock): closing_price_list = stock['Close'].tolist() numpyclose = np.asarray(closing_price_list) macd1, macd2, macdhistogram = ti.macd( numpyclose, 8, 17, 9) # for buy signals it should be 8,17,9 if macdhistogram[-1] > 0 > macdhistogram[-2] and \ macdhistogram[-1] >= macdhistogram[-2] >= macdhistogram[-3] >= macdhistogram[-4]: return True else: return False
def macd_potential_sell(stock): closing_price_list = stock['Close'].tolist() numpyclose = np.asarray(closing_price_list) macd1, macd2, macdhistogram = ti.macd( numpyclose, 12, 26, 9) # for sell signals it should be 12, 26, 9 if macdhistogram[-1] < 0 < macdhistogram[-2] and \ macdhistogram[-1] <= macdhistogram[-2] <= macdhistogram[-3] <= macdhistogram[-4]: return True else: return False
def calculate(self, candles): candles_len = len(candles) if candles_len < self.long_period: return (0, 0, 0) close_array = np.array( [float(x['ohlc'].close) for x in candles[-self.period:]]) #calculate (macd, macdsignal, macdhist) = ti.macd(close_array, short_period=self.short_period, long_period=self.long_period, signal_period=self.signal_period) return (macd[-1], macdsignal[-1], macdhist[-1])
def macd(ticker): alist = [] dfh = rh.get_historicals(ticker,'day','regular') for term in dfh: alist.append(float(term['close_price'])) data = np.array(alist) macd, macd_signal, macd_histogram = ti.macd(data,12,26,9) macd_list = macd_histogram index = len(macd_list) if(index > 2): if macd_list[index - 1] > macd_list[index - 2] and macd_list[index - 2] > macd_list[index - 3]: return True else: return False else: return False
def save_macd_buy(stock_name): stock = yf.download(tickers=stock_name, interval="1wk", period="2y", threads=True) stock.index = stock.index.where(~stock.index.duplicated(), stock.index + timedelta(1)) # Remove all the NaN values for index, row in stock.iterrows(): if math.isnan(row["Close"]) or math.isnan(row["Volume"]): stock = stock.drop([index]) closing_price_list = stock['Close'].tolist() date_list = list(stock.index) numpyclose = np.asarray(closing_price_list) macd1, macd2, macdhistogram = ti.macd( numpyclose, 8, 17, 9) # for buy signals it should be 8,17,9 sma = ti.sma(numpyclose, 17) plt.figure(figsize=(15, 8)) ax1 = plt.subplot(212) ax2 = plt.subplot(211, sharex=ax1, title=stock_name) numberofactivedays = len(date_list[16:]) arrangeddates = np.arange(numberofactivedays) ax1.plot(arrangeddates, macd1, 'r') ax1.plot(arrangeddates, macd2, 'y') ax1.bar(arrangeddates, macdhistogram) ax1.plot(arrangeddates, [0] * len(date_list[16:])) ax1.set(ylabel='MACD') ax2.plot(arrangeddates, closing_price_list[16:]) ax2.plot(arrangeddates, sma, 'r') ax2.set(ylabel="Price") ax1.set_xticks(np.append(arrangeddates[0::15], arrangeddates[-1])) ax2.set_xticks(np.append(arrangeddates[0::15], arrangeddates[-1])) ax1.set_xticklabels( [date.strftime("%Y-%m-%d") for date in date_list[16:]][0::15] + [[date.strftime("%Y-%m-%d") for date in date_list[16:]][-1]]) ax2.set_xticklabels( [date.strftime("%Y-%m-%d") for date in date_list[16:]][0::15] + [[date.strftime("%Y-%m-%d") for date in date_list[16:]][-1]]) ax1.tick_params(rotation=30) ax2.tick_params(rotation=30) plt.savefig("Support Files/" + stock_name + "-price" + ".png") plt.close()
def test_macd(data): """Values match approx Oanda via spot check but not tulipy, hence marked to fail""" arr = data["close"].to_numpy(copy=True).astype(float) ti_macd, ti_signal, ti_histogram = ti.macd(arr, 12, 26, 9) s = indicator.Indicate(data["close"], exp=6)\ .moving_average_convergence_divergence() assert np.allclose(ti_macd[-250:], s['macd'][-250:].astype(float), atol=1e-05, equal_nan=True) assert np.allclose(ti_signal[-250:], s['signal'][-250:].astype(float), atol=1e-05, equal_nan=True) assert np.allclose(ti_histogram[-250:], s['histogram'][-250:].astype(float), atol=1e-05, equal_nan=True)
def inds(self): Indicators = {} for i in range(len(self.time)): #i/o? ''' 2 = High, 3 = Low, 4 = Close, 5 = Volume collects the needed market data into one list to push to the indicators''' close = self.time[i][4].values.copy(order='C') high = self.time[i][2].values.copy(order='C') low = self.time[i][3].values.copy(order='C') volume = self.time[i][5].values.copy(order='C') # !!!This needs to be changed. Each volume of the base time must be indexed up to the slice __time = self.time[i][6] # these are the indicators currently being used, and recored Indicators[i] = { 'stochrsi': ti.stochrsi(close, 5), 'rsi': ti.rsi(close, 5), # indicators that need to be doublechecked 'mfi': ti.mfi(high, low, close, volume, 5), 'sar': ti.psar(high, low, .2, 2), 'cci': ti.cci(high, low, close, 5), 'ema': ti.ema(close, 5) } # this one is good Indicators[i]['stoch_k'], Indicators[i]['stoch_d'] = ti.stoch( high, low, close, 5, 3, 3) # check on this, to see if it functions properly Indicators[i]['bbands_lower'], Indicators[i]['bbands_middle'], Indicators[i]['bbands_upper'] = ti.bbands(close, 5, 2) Indicators[i]['macd'], Indicators[i]['macd_signal'], Indicators[i]['macd_histogram'] = ti.macd(close, 12, 26, 9) Indicators[i]['time'] = __time Indicators[i]['close'] = close ''' below changes the length of each array to match the longest one, for a pandas df np.nan for the tail of the shorter ones''' Indicators[i] = to_pd(Indicator=Indicators[i]).dropna(how='all') return Indicators
def test_tulip_macd(): ti.macd(close_np, 12, 26, 9)
def _compute_simple_states(self): self.short_time = 12 self.long_time = 26 start, end = self.get_time_endpoints(self.mode) self.start = start self.end = end # We need prepadding for MACD, and the rolling calcuations prepadding = pd.Timedelta(days=self.short_time + self.long_time + self.WINDOW_SIZE + 7) postpadding = pd.Timedelta( days=7) # to get around the weekend and possible holidays self.prices = web.get_data_yahoo("AAPL", start=start - prepadding, end=end + postpadding, session=self.session)["Close"] self.prices_pct_change = self.prices.pct_change() # We must rescale the data dynamically for numerical stability. min_prices = self.prices.expanding().min() max_prices = self.prices.expanding().max() assert not all(min_prices == max_prices), "Price doesn't change" width = max_prices - min_prices width[0] = width[1] center = self.prices.expanding().median() scaled_prices = (self.prices - center) / width self.prices_normalized = scaled_prices # We compute the mean, and standard deviation of the first WINDOW_SIZE days, and use this to standardize # the entire time series. assert self.WINDOW_SIZE > 1, "WINDOW_SIZE is too small" self.data = pd.DataFrame() self.data["x"] = scaled_prices self.data["diff_x"] = self.data["x"].diff(-1) self.mu_hat = self.data["x"][:self.WINDOW_SIZE].mean() self.sigma_hat = self.data["x"][:self.WINDOW_SIZE].std() self.data["std"] = self.data["x"].rolling(self.WINDOW_SIZE).std() smallest_nonzero_std = self.data["std"][ self.data["std"] > 0].expanding().min() self.data["std"][self.data["std"] == 0] = smallest_nonzero_std[ self.data["std"] == 0] # Use additive returns, because the reward is computed using the additive return # rets = self.prices - self.prices.shift(-1) rets = self.prices.diff().shift(-1) self.data["sharpe"] = (rets.rolling(self.WINDOW_SIZE).mean() / rets.rolling(self.WINDOW_SIZE).std()) self.data["sharpe"][self.data["sharpe"].apply(math.isnan)] = 0 macd = ti.macd( self.prices.values, short_period=self.short_time, long_period=self.long_time, signal_period=self.WINDOW_SIZE, ) self.data["macd"] = 0 self.data["macd"][self.long_time - 1:] = macd[2] # to look up current price from self.data, irrespective of the date break due to the weekend self.df_initial_index = self.data.index.get_loc(self.start) self.df_index = self.df_initial_index self.df_final_index = self.data.index.get_loc(self.end)
def get_indicators(self): short_period = int(self.strategy_value['short_period']) long_period = int(self.strategy_value['long_period']) signal_period = int(self.strategy_value['signal_period']) return ti.macd(self.open, short_period, long_period, signal_period)
'side': 'SELL', 'amount': AMOUNT_NOW }) reset_position() martingale() LOSSES += 1 for row in OHLC[::-1]: CLOSE.insert(0, row['close']) if len(CLOSE) < 50: continue is_close_position(row) if POSITION['price'] > 0: continue macd, macd_signal, macd_histogram = ti.macd(np.array(CLOSE), 12, 26, 9) if ti.crossover(macd, macd_signal)[0]: POSITION['price'] = row['close'] POSITION['side'] = 'BUY' POSITION['date'] = row['date'] elif ti.crossover(macd_signal, macd)[0]: POSITION['price'] = row['close'] POSITION['side'] = 'SELL' POSITION['date'] = row['date'] print(TRADES) print('MAX_MARTINGALE', MAX_MARTINGALE) print('MAX_AMOUNT', MAX_AMOUNT) print('WINS', WINS) print('LOSSES', LOSSES)
def get_MACD(close, slow_signal, fast_signal, signal): macd = np.zeros([3,len(close)]) macd[:,fast_signal-1:] = ti.macd(close, slow_signal ,fast_signal, signal) return macd