def get_ema(): global short_ema global long_ema global cross_up global cross_down global ema_diff short = ti.ema(close_price_historicals, 10) long = ti.ema(close_price_historicals, 20) short_ema = short[-1] long_ema = long[-1] ema_diff = short_ema - long_ema short_cross_up = ti.crossover(short, long)[-1] short_cross_down = ti.crossover(long, short)[-1] if (short_cross_up == 1): cross_up = True else: cross_up = False if (short_cross_down == 1): cross_down == True else: cross_down == False
async def evaluate(self, cryptocurrency, symbol, time_frame, close_candles, high_candles, low_candles, candle): self.eval_note = commons_constants.START_PENDING_EVAL_NOTE if len(close_candles) >= self.minimal_data: min_adx = 7.5 max_adx = 45 neutral_adx = 25 adx = tulipy.adx(high_candles, low_candles, close_candles, self.period_length) instant_ema = data_util.drop_nan(tulipy.ema(close_candles, 2)) slow_ema = data_util.drop_nan(tulipy.ema(close_candles, 20)) adx = data_util.drop_nan(adx) if len(adx): current_adx = adx[-1] current_slows_ema = slow_ema[-1] current_instant_ema = instant_ema[-1] multiplier = -1 if current_instant_ema < current_slows_ema else 1 # strong adx => strong trend if current_adx > neutral_adx: # if max adx already reached => when ADX forms a top and begins to turn down, you should look for a # retracement that causes the price to move toward its 20-day exponential moving average (EMA). adx_last_values = adx[-15:] adx_last_value = adx_last_values[-1] local_max_adx = adx_last_values.max() # max already reached => trend will slow down if adx_last_value < local_max_adx: self.eval_note = multiplier * ( current_adx - neutral_adx) / (local_max_adx - neutral_adx) # max not reached => trend will continue, return chances to be max now else: crossing_indexes = EvaluatorUtil.TrendAnalysis.get_threshold_change_indexes( adx, neutral_adx) chances_to_be_max = \ EvaluatorUtil.TrendAnalysis.get_estimation_of_move_state_relatively_to_previous_moves_length( crossing_indexes, adx) if len(crossing_indexes) > 2 else 0.75 proximity_to_max = min(1, current_adx / max_adx) self.eval_note = multiplier * proximity_to_max * chances_to_be_max # weak adx => change to come else: self.eval_note = multiplier * min(1, ( (neutral_adx - current_adx) / (neutral_adx - min_adx))) 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 period_length = 14 if len(self.data[ PriceIndexes.IND_PRICE_HIGH.value]) > period_length + 10: min_adx = 7.5 max_adx = 45 neutral_adx = 25 adx = tulipy.adx(self.data[PriceIndexes.IND_PRICE_HIGH.value], self.data[PriceIndexes.IND_PRICE_LOW.value], self.data[PriceIndexes.IND_PRICE_CLOSE.value], period_length) instant_ema = tulipy.ema( self.data[PriceIndexes.IND_PRICE_CLOSE.value], 2) slow_ema = tulipy.ema( self.data[PriceIndexes.IND_PRICE_CLOSE.value], 20) adx = DataUtil.drop_nan(adx) if len(adx): current_adx = adx[-1] current_slows_ema = slow_ema[-1] current_instant_ema = instant_ema[-1] multiplier = -1 if current_instant_ema < current_slows_ema else 1 # strong adx => strong trend if current_adx > neutral_adx: # if max adx already reached => when ADX forms a top and begins to turn down, you should look for a # retracement that causes the price to move toward its 20-day exponential moving average (EMA). adx_last_values = adx[-15:] adx_last_value = adx_last_values[-1] local_max_adx = adx_last_values.max() # max already reached => trend will slow down if adx_last_value < local_max_adx: self.eval_note = multiplier * ( current_adx - neutral_adx) / (local_max_adx - neutral_adx) # max not reached => trend will continue, return chances to be max now else: crossing_indexes = TrendAnalysis.get_threshold_change_indexes( adx, neutral_adx) chances_to_be_max = \ TrendAnalysis.get_estimation_of_move_state_relatively_to_previous_moves_length( crossing_indexes, adx) if len(crossing_indexes) > 2 \ else 0.75 proximity_to_max = min(1, current_adx / max_adx) self.eval_note = multiplier * proximity_to_max * chances_to_be_max # weak adx => change to come else: self.eval_note = multiplier * min(1, ( (neutral_adx - current_adx) / (neutral_adx - min_adx)))
def get_indicators(self): short_window = int(self.strategy_value['short_window']) medium_window = int(self.strategy_value['medium_window']) long_window = int(self.strategy_value['long_window']) ema_window_short = int(self.strategy_value['ema_window_short']) ema_window_long = int(self.strategy_value['ema_window_long']) ultimate = ti.ultosc(self.high, self.low, self.close, short_window, medium_window, long_window) ema_long = ti.ema(self.close, ema_window_long) ema_short = ti.ema(self.close, ema_window_short) return ultimate, ema_short, ema_long
def get_instant_trend(self,stock,loadHist=False,wait=True): # this function analyses the instant trend # it checks the direction and returns a True if it matches self._L.info('\n\n### INSTANT TREND ANALYSIS (%s for %s) ###' % (stock.name,stock.direction)) try: while True: if loadHist: self.load_historical_data(stock,interval=gvars.fetchItval['little']) # calculate the EMAs ema9 = ti.ema(stock.df.close.dropna().to_numpy(), 9) ema26 = ti.ema(stock.df.close.dropna().to_numpy(), 26) ema50 = ti.ema(stock.df.close.dropna().to_numpy(), 50) self._L.info('[%s] Instant Trend EMAS = [%.2f,%.2f,%.2f]' % (stock.name,ema9[-1],ema26[-1],ema50[-1])) # look for a buying trend if ( (stock.direction == 'buy') and (ema9[-1] > ema26[-1]) and (ema26[-1] > ema50[-1]) ): self._L.info('OK: Trend going UP') return True # look for a selling trend elif ( (stock.direction == 'sell') and (ema9[-1] < ema26[-1]) and (ema26[-1] < ema50[-1]) ): self._L.info('OK: Trend going DOWN') return True else: self._L.info('Trend not clear, waiting (%s)' % stock.direction) if wait: self.timeout += gvars.sleepTimes['IT'] time.sleep(gvars.sleepTimes['IT']) return False except Exception as e: self._L.info('ERROR_IT: error at instant trend') self._L.info(e) block_thread(self._L,e,self.thName)
async def eval_impl(self): self.eval_note = False short_period = 35 # standard with klinger long_period = 55 # standard with klinger ema_signal_period = 13 # standard ema signal for klinger kvo = tulipy.kvo(self.data[PriceIndexes.IND_PRICE_HIGH.value], self.data[PriceIndexes.IND_PRICE_LOW.value], self.data[PriceIndexes.IND_PRICE_CLOSE.value], self.data[PriceIndexes.IND_PRICE_VOL.value], short_period, long_period) kvo = DataUtil.drop_nan(kvo) if len(kvo) >= ema_signal_period: kvo_ema = tulipy.ema(kvo, ema_signal_period) ema_difference = kvo - kvo_ema if len(ema_difference) > 1: zero_crossing_indexes = TrendAnalysis.get_threshold_change_indexes( ema_difference, 0) max_elements = 7 to_consider_kvo = min( max_elements, len(ema_difference) - zero_crossing_indexes[-1]) self.eval_note = TrendAnalysis.min_has_just_been_reached( ema_difference[-to_consider_kvo:], acceptance_window=0.9, delay=1)
def get_indicators(self): short_window = int(self.strategy_value['short_window']) long_window = int(self.strategy_value['long_window']) signal_window = int(self.strategy_value['signal_window']) kvo = ti.kvo(self.high, self.low, self.close, self.volume, short_window, long_window) return kvo, ti.ema(kvo, signal_window)
def ema(self, name='ema', period=5): if len(self.df_ohlc) > period: self._add_column_to_ohlc( name, ti.ema(self.df_ohlc.priceclose.values, period=period)) return True else: return False
async def evaluate(self, cryptocurrency, symbol, time_frame, high_candles, low_candles, close_candles, volume_candles, candle): if len(high_candles) >= self.short_period: kvo = tulipy.kvo(high_candles, low_candles, close_candles, volume_candles, self.short_period, self.long_period) kvo = data_util.drop_nan(kvo) if len(kvo) >= self.ema_signal_period: kvo_ema = tulipy.ema(kvo, self.ema_signal_period) ema_difference = kvo - kvo_ema if len(ema_difference) > 1: zero_crossing_indexes = EvaluatorUtil.TrendAnalysis.get_threshold_change_indexes(ema_difference, 0) max_elements = 7 to_consider_kvo = min(max_elements, len(ema_difference) - zero_crossing_indexes[-1]) self.eval_note = EvaluatorUtil.TrendAnalysis.min_has_just_been_reached( ema_difference[-to_consider_kvo:], acceptance_window=0.9, delay=1) await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
def get_general_trend(self, stock): # this function analyses the general trend # it defines the direction and returns a True if defined self._L.info('\n\n### GENERAL TREND ANALYSIS (%s) ###' % stock.name) timeout = 1 try: while True: self.load_historical_data(stock, interval=gvars.fetchItval['big']) # calculate the EMAs ema9 = ti.ema(stock.df.close.dropna().to_numpy(), 9) ema26 = ti.ema(stock.df.close.dropna().to_numpy(), 26) ema50 = ti.ema(stock.df.close.dropna().to_numpy(), 50) self._L.info( '[GT %s] Current: EMA9: %.3f // EMA26: %.3f // EMA50: %.3f' % (stock.name, ema9[-1], ema26[-1], ema50[-1])) # check the buying trend if (ema9[-1] > ema26[-1]) and (ema26[-1] > ema50[-1]): self._L.info('OK: Trend going UP') stock.direction = 'buy' return True # check the selling trend elif (ema9[-1] < ema26[-1]) and (ema26[-1] < ema50[-1]): self._L.info('OK: Trend going DOWN') stock.direction = 'sell' return True elif timeout >= gvars.timeouts['GT']: self._L.info('This asset is not interesting (timeout)') return False else: self._L.info('Trend not clear, waiting...') timeout += gvars.sleepTimes['GT'] time.sleep(gvars.sleepTimes['GT']) except Exception as e: self._L.info('ERROR_GT: error at general trend') self._L.info(e) block_thread(self._L, e, self.thName)
def tsi(values, long_length, short_length, signal_length): change = np.diff(values) double_smoothed_change = double_smooth(change, long_length, short_length) double_smoothed_abs_change = double_smooth(abs(change), long_length, short_length) tsi_value = 100 * (double_smoothed_change / double_smoothed_abs_change) tsi_signal = ti.ema(tsi_value, signal_length) return tsi_value, tsi_signal
async def eval_impl(self): self.eval_note = START_PENDING_EVAL_NOTE current_ema = tulipy.ema(self.data[PriceIndexes.IND_PRICE_CLOSE.value], self.get_specific_config()[self.EMA_SIZE])[-1] current_price_close = self.data[PriceIndexes.IND_PRICE_CLOSE.value][-1] diff = (current_price_close / current_ema * 100) - 100 if diff <= self.evaluator_config[self.LONG_VALUE]: self.eval_note = -1 elif diff >= self.evaluator_config[self.SHORT_VALUE]: self.eval_note = 1
def EMA(candlestickperiod, period): closeprices = [] listoftime = [] EMA = candlestickinfo(600, candlestickperiod) for i in range(len(EMA['candles'])): if EMA['candles'][i]['complete'] == True: if EMA['candles'][i]['time'] not in listoftime: closeprices.append(float(EMA['candles'][i]['mid']['c'])) listoftime.append(EMA['candles'][i]['time']) closearray = np.array(closeprices) ta = ti.ema(closearray, period = period) return round(ta[-1],5)
def calculate(self, candles): candles_len = len(candles) if candles_len < self.period: return float(0) val_array = np.array( [float(x['ohlc'].close) for x in candles[-self.period:]]) #calculate ema cur_ema = ti.ema(val_array, self.period) # log.info ("TA_EMA: %g"%cur_ema) return float(cur_ema[-1])
def get_indicators(self): short_window = int(self.strategy_value['short_window']) medium_window = int(self.strategy_value['medium_window']) long_window = int(self.strategy_value['long_window']) ultimate = ti.ultosc( self.high, self.low, self.open, short_window, medium_window, long_window ) ema = ti.ema(self.open, short_window) return ultimate, ema
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.period: current_ema = tulipy.ema(candle_data, self.period)[-1] current_price_close = candle_data[-1] diff = (current_price_close / current_ema * 100) - 100 if diff <= self.evaluator_config[self.LONG_VALUE]: self.eval_note = -1 elif diff >= self.evaluator_config[self.SHORT_VALUE]: self.eval_note = 1 await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
def wavetrend(self, name='wt', d_factor=0.015): """ https://www.quantopian.com/posts/wavetrend-oscillator """ ap = (self.df_ohlc.pricehigh + self.df_ohlc.pricelow + self.df_ohlc.priceclose) / 3 ap = ap.values #esa = numpy_ewma_vectorized_v2(ap, 10) esa = ti.ema(ap, 10) d = ti.ema(abs(ap - esa), 10) # checking for zeroes i = 0 while d[i] == 0: i += 1 if i > 0: ap = ap[i:] esa = esa[i:] d = d[i:] ci = (ap - esa) / (d_factor * d) tci = ti.ema(ci, 21) wt1 = _zero_padding(tci, len(ap)) self._add_column_to_ohlc(name, wt1) return True
def strat(pair, quantity, interval): global inpos while True: price = Get_price(pair) # get data Get_kline(pair, interval) closes = Get_kline.closes # indicators shortema = tulipy.ema(closes, 22) medema = tulipy.ema(closes, 50) longema = tulipy.ema(closes, 200) last_close = closes[-1] last_shortema = shortema[-1] last_medema = medema[-1] last_longema = longema[-1] # Buy if last_close > last_shortema and last_close > last_medema and last_close > last_longema and inpos == False: print(f'Buying {quantity} {pair}') if testing == False: price = Get_price(pair) order_succeded = Limit_buy(pair, quantity, price) if order_succeded: inpos = True print('sucess') # Sell if last_close > last_shortema or last_close > last_medema or last_close > last_longema and inpos == True: if testing == False: print('Selling') price = Get_price(pair) order_succeded = Limit_sell(pair, quantity, price) if order_succeded: time.sleep(3600) inpos = False print('sucess') print(f'{pair}:{price}') time.sleep(1)
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 strat(pair, quantity, interval): global inpos while True: # get data Get_kline(pair, interval) closes = Get_kline.closes # indicators rsi = tulipy.rsi(closes, 14) rsiema = tulipy.ema(rsi, 22) last_rsi = rsi[-1] last_rsiema = rsiema[-1] # Buy if last_rsi > last_rsiema and last_rsi > 50 and inpos == False: if testing == False: print(f'Buying {quantity} {pair}') price = Get_price(pair) order_succeded = Limit_buy(pair, quantity, price) if order_succeded: inpos = True print(f'{fg.yellow}sucess{ac.clear}') # Sell elif inpos and last_rsi < last_rsiema or last_rsi < 50: if testing == False: print(f'Selling {quantity} {pair}') price = Get_price(pair) balance = Asset_balance(pair) if balance > quantity: order_succeded = Limit_sell(pair, quantity, price) if balance < quantity: order_succeded = Limit_sell(pair, balance, price) if order_succeded: print(f'{fg.yellow}sucess{ac.clear}') time.sleep(3600) inpos = False price = Get_price(pair) print(f'{pair}: {round(price, 2)}') time.sleep(1)
async def evaluate(self, cryptocurrency, symbol, time_frame, high_candles, low_candles, close_candles, volume_candles, candle): eval_proposition = commons_constants.START_PENDING_EVAL_NOTE kvo = tulipy.kvo(high_candles, low_candles, close_candles, volume_candles, self.short_period, self.long_period) kvo = data_util.drop_nan(kvo) if len(kvo) >= self.ema_signal_period: kvo_ema = tulipy.ema(kvo, self.ema_signal_period) ema_difference = kvo - kvo_ema if len(ema_difference) > 1: zero_crossing_indexes = EvaluatorUtil.TrendAnalysis.get_threshold_change_indexes(ema_difference, 0) current_difference = ema_difference[-1] significant_move_threshold = numpy.std(ema_difference) factor = 0.2 if EvaluatorUtil.TrendAnalysis.peak_has_been_reached_already( ema_difference[zero_crossing_indexes[-1]:]): if abs(current_difference) > significant_move_threshold: factor = 1 else: factor = 0.5 eval_proposition = current_difference * factor / significant_move_threshold if abs(eval_proposition) > 1: eval_proposition = 1 if eval_proposition > 0 else -1 self.eval_note = eval_proposition 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): eval_proposition = START_PENDING_EVAL_NOTE short_period = 35 # standard with klinger long_period = 55 # standard with klinger ema_signal_period = 13 # standard ema signal for klinger kvo = tulipy.kvo(self.data[PriceIndexes.IND_PRICE_HIGH.value], self.data[PriceIndexes.IND_PRICE_LOW.value], self.data[PriceIndexes.IND_PRICE_CLOSE.value], self.data[PriceIndexes.IND_PRICE_VOL.value], short_period, long_period) kvo = DataUtil.drop_nan(kvo) if len(kvo) >= ema_signal_period: kvo_ema = tulipy.ema(kvo, ema_signal_period) ema_difference = kvo - kvo_ema if len(ema_difference) > 1: zero_crossing_indexes = TrendAnalysis.get_threshold_change_indexes( ema_difference, 0) current_difference = ema_difference[-1] significant_move_threshold = numpy.std(ema_difference) factor = 0.2 if TrendAnalysis.peak_has_been_reached_already( ema_difference[zero_crossing_indexes[-1]:]): if abs(current_difference) > significant_move_threshold: factor = 1 else: factor = 0.5 eval_proposition = current_difference * factor / significant_move_threshold if abs(eval_proposition) > 1: eval_proposition = 1 if eval_proposition > 0 else -1 self.eval_note = eval_proposition
def get_indicators(self): short_ema = ti.ema(self.open, int(self.strategy_value['short_window'])) long_ema = ti.ema(self.open, int(self.strategy_value['long_window'])) return short_ema, long_ema
def double_smooth(values, long, short): first_smooth = ti.ema(values, long) return ti.ema(first_smooth, short)
def enter_position_mode(self, stock, desiredPrice, sharesQty): # this function holds a loop taking care of the open position # it is constantly checking the conditions to exit self._L.info('Position entered') stock.avg_entry_price = float( self.alpaca.get_position(stock.name).avg_entry_price) ema50 = ti.ema(stock.df.close.dropna().to_numpy(), 50) stopLoss = self.set_stoploss( ema50, direction=stock.direction) # stoploss = EMA50 takeProfit = self.set_takeprofit(stock.avg_entry_price, stopLoss) if stock.direction is 'buy': targetGainInit = int( (takeProfit - stock.avg_entry_price) * sharesQty) reverseDirection = 'sell' elif stock.direction is 'sell': targetGainInit = int( (stock.avg_entry_price - takeProfit) * sharesQty) reverseDirection = 'buy' self._L.info('######################################') self._L.info('# TICKER : %s' % stock.name) self._L.info('# SIDE : %s' % stock.direction) self._L.info('# QTY : %d' % sharesQty) self._L.info('# TARGET GAIN : %.3f$' % targetGainInit) self._L.info('# TAKE PROFIT : %.3f$' % takeProfit) self._L.info('# DESIRED ENTRY: %.3f$' % desiredPrice) self._L.info('# AVG ENTRY : %.3f$' % stock.avg_entry_price) self._L.info('# STOP LOSS : %.3f$' % stopLoss) self._L.info('######################################\n\n') timeout = 0 stochTurn = 0 stochCrossed = False exitSignal = False while True: targetGain = targetGainInit # not at every iteration it will check every condition # some of them can wait if (stochTurn >= gvars.sleepTimes['GS']) or (timeout == 0): # check the stochastic crossing stochTurn = 0 self.load_historical_data(stock, interval=gvars.fetchItval['little']) stochCrossed = self.get_stochastic(stock, direction=reverseDirection) # check if the position exists and load the price at stock.currentPrice if not self.check_position(stock): self._L.info('Warning! Position not found at Alpaca') return False else: currentPrice = stock.currentPrice # calculate current gain if stock.direction is 'buy': currentGain = (currentPrice - stock.avg_entry_price) * sharesQty elif stock.direction is 'sell': currentGain = (stock.avg_entry_price - currentPrice) * sharesQty # if stop loss reached if ((stock.direction is 'buy' and currentPrice <= stopLoss) or (stock.direction is 'sell' and currentPrice >= stopLoss)): self._L.info('STOPLOSS reached at price %.3f' % currentPrice) self.success = 'NO: STOPLOSS' break # break the while loop # if take profit reached elif currentGain >= targetGain: self._L.info('# Target gain reached at %.3f. BYE #' % currentPrice) self.success = 'YES: TGT GAIN' break # break the while loop # if stochastics crossed otherwise elif stochCrossed: self.success = 'YES: STOCH XED WITH GAIN' break # break the while loop else: self._L.info('%s: %.2f <-- %.2f$ --> %.2f$ (gain: %.2f$)' % (stock.name, stopLoss, currentPrice, takeProfit, currentGain)) time.sleep(gvars.sleepTimes['PF']) timeout += gvars.sleepTimes['PF'] stochTurn += gvars.sleepTimes['PF'] # get out! orderOut = False while not orderOut: orderDict = { 'side': reverseDirection, 'symbol': stock.name, 'type': 'market', # it is a MARKET order, now 'limit_price': currentPrice, 'qty': sharesQty } orderOut = self.submitOrder(orderDict) self._L.info('%i %s %s at %.2f DONE' % (sharesQty, stock.name, stock.direction, currentPrice)) return True
def bot(): # globalize variables that are changed by the bot global amount_crypto global current_position global current_entry_price global old_position global old_entry_price_adjusted global next_position global n_trades global cumulated_profit # initiate start time to track how long one full bot iteration takes start = time.time() # fetch the required data from the exchange to compute the indicator from df = use_function[exchange.lower()][0](symbol=symbol, timeframe=timeframe, length=length, include_current_candle=True, file_format='', api_cooldown_seconds=0) ### INDICATOR ########################################################################################## if moving_average_type == 'simple_ma': short_ma = pd.rolling_mean(df['Close'], window=short_period) long_ma = pd.rolling_mean(df['Close'], window=long_period) if moving_average_type == 'double_exponential_ma': short_ma = pd.Series(ti.dema(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.dema(df['Close'].as_matrix(), long_period)) if moving_average_type == 'triple_exponential_ma': short_ma = pd.Series(ti.tema(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.tema(df['Close'].as_matrix(), long_period)) if moving_average_type == 'exponential_ma': short_ma = pd.Series(ti.ema(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.ema(df['Close'].as_matrix(), long_period)) if moving_average_type == 'hull_ma': short_ma = pd.Series(ti.hma(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.hma(df['Close'].as_matrix(), long_period)) if moving_average_type == 'kaufman_adaptive_ma': short_ma = pd.Series(ti.kama(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.kama(df['Close'].as_matrix(), long_period)) if moving_average_type == 'triangular_ma': short_ma = pd.Series(ti.trima(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.trima(df['Close'].as_matrix(), long_period)) if moving_average_type == 'volume_weighted_ma': short_ma = pd.Series(ti.vwma(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.vwma(df['Close'].as_matrix(), long_period)) if moving_average_type == 'zero_lag_exponential_ma': short_ma = pd.Series(ti.zlema(df['Close'].as_matrix(), short_period)) long_ma = pd.Series(ti.zlema(df['Close'].as_matrix(), long_period)) if moving_average_type == 'arnaud_legoux_ma': # prepare the data to be used for the actual indicator computation # (when this step is not done the ALMA function returns the ALMA value # from the last full candle, effectively omitting the most current value) alma_data = df['Close'].shift(-1) alma_data.iloc[-1] = 0 def ALMA(data, period=100, offset=0.85, sigma=6): ''' ALMA - Arnaud Legoux Moving Average, http://www.financial-hacker.com/trend-delusion-or-reality/ https://github.com/darwinsys/Trading_Strategies/blob/master/ML/Features.py ''' m = np.floor(float(offset) * (period - 1)) s = period / float(sigma) alma = np.zeros(data.shape) w_sum = np.zeros(data.shape) for i in range(len(data)): if i < period - 1: continue else: for j in range(period): w = np.exp(-(j - m) * (j - m) / (2 * s * s)) alma[i] += data[i - period + j] * w w_sum[i] += w alma[i] = alma[i] / w_sum[i] return alma # get the indicator values using the ALMA function above short_ma = pd.Series( ALMA(data=alma_data.as_matrix(), period=short_period, offset=0.85, sigma=6)) long_ma = pd.Series( ALMA(data=alma_data.as_matrix(), period=long_period, offset=0.85, sigma=6)) ### STRATEGY ########################################################################################### # if the current short moving average value is ABOVE (or equal) the current long moving average value go LONG if short_ma.iloc[-1] >= long_ma.iloc[-1]: next_position = 1 # LONG # if the current short moving average value is BELOW the current long moving average value go SHORT if short_ma.iloc[-1] < long_ma.iloc[-2]: next_position = -1 # SHORT ### TRADING ENGINE ##################################################################################### # print this message when trading is disabled if disable_trading == True: print('>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<') print('>>> ! CAUTION ! <<<') print('>>> TRADING DISABLED <<<') print('>>> TRADES ARE SIMULATED <<<') print('>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<') # create a list of open orders of the respective symbol # used to check if trailing-stop has been hitted, cancelling old trailing-stop if disable_trading == False: symbol_orders = [ order for order in use_function[exchange.lower()][1].fetch_open_orders( symbol=symbol) ] # check if there is an open position already (maybe the trailing stop has been hitted so there is no open position anymore) if len(symbol_orders) == 0: current_position = 0 print( '>>> TRADE LOG <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' ) # if there is an open position if current_position != 0: if next_position == -1: if current_position == -1: print('==> HOLD SHORT <==') if current_position == 1: # delete old TRAILING-STOP order if set_trailing_stop == True: if disable_trading == False: use_function[exchange.lower()][1].cancel_order( id=symbol_orders[-1]['id']) time.sleep(api_cooldown) print('Old Trailing-Stop Cancelled') # if trading is disabled get the first bid price from the order book as current_entry_price if disable_trading == True: current_entry_price = round( float( use_function[exchange.lower()][2].fetch_order_book( symbol=symbol, limit=1)['bids'][0][0]), decimals) # create SELL order if disable_trading == False: use_function[exchange.lower()][1].create_market_sell_order( symbol, amount_crypto * 2, {'type': 'market'}) time.sleep(api_cooldown) current_position = -1 print('==> ENTERED SHORT <==') # create TRAILING-STOP order, BUY if set_trailing_stop == True: if disable_trading == False: symbol_trades = [ trade for trade in use_function[exchange.lower()] [1].fetch_my_trades(symbol=symbol) ] use_function[exchange.lower()][1].create_order( symbol=symbol, type='trailing-stop', side='buy', amount=amount_crypto, price=round( float(symbol_trades[-1]['price']) * (trailing_stop_pct / 100), 4)) print('Trailing-Stop Placed (BUY)') if next_position == 1: if current_position == 1: print('==> HOLD LONG <==') if current_position == -1: # delete old TRAILING-STOP order if set_trailing_stop == True: if disable_trading == False: use_function[exchange.lower()][1].cancel_order( id=symbol_orders[-1]['id']) time.sleep(api_cooldown) print('Old Trailing-Stop Cancelled') # if trading is disabled get the first ask price from the order book as current_entry_price if disable_trading == True: current_entry_price = round( float( use_function[exchange.lower()][2].fetch_order_book( symbol=symbol, limit=1)['asks'][0][0]), decimals) # create BUY order if disable_trading == False: use_function[exchange.lower()][1].create_market_buy_order( symbol, amount_crypto * 2, {'type': 'market'}) time.sleep(api_cooldown) current_position = 1 print('==> ENTERED LONG <==') # create TRAILING-STOP order, SELL if set_trailing_stop == True: if disable_trading == False: symbol_trades = [ trade for trade in use_function[exchange.lower()] [1].fetch_my_trades(symbol=symbol) ] use_function[exchange.lower()][1].create_order( symbol=symbol, type='trailing-stop', side='sell', amount=amount_crypto, price=round( float(symbol_trades[-1]['price']) * (trailing_stop_pct / 100), 4)) print('Trailing-Stop Placed (SELL)') # if there is no position yet or the position was closed within the timeframe (trailing-stop hitted) if current_position == 0: # set the amount to be traded in respective cryptocurrency as (amount_usd_to_trade) / (current average price of the cryptocurrency) amount_crypto = round( float(amount_usd_to_trade / use_function[exchange.lower()][2].fetch_ticker( symbol=symbol)['last']), 8) if next_position == 1: # if trading is disabled get the first ask price from the order book as current_entry_price if disable_trading == True: current_entry_price = round( float(use_function[exchange.lower()][2].fetch_order_book( symbol=symbol, limit=1)['asks'][0][0]), decimals) # create BUY order if disable_trading == False: use_function[exchange.lower()][1].create_market_buy_order( symbol, amount_crypto, {'type': 'market'}) time.sleep(api_cooldown) current_position = 1 print('Initial LONG (Market Order)') # create TRAILING-STOP order, SELL if set_trailing_stop == True: if disable_trading == False: symbol_trades = [ trade for trade in use_function[exchange.lower()] [1].fetch_my_trades(symbol=symbol) ] use_function[exchange.lower()][1].create_order( symbol=symbol, type='trailing-stop', side='sell', amount=amount_crypto, price=round( float(symbol_trades[-1]['price']) * (trailing_stop_pct / 100), 4)) print('Initial Trailing-Stop (SELL)') if next_position == -1: # if trading is disabled get the first bid price from the order book as current_entry_price if disable_trading == True: current_entry_price = round( float(use_function[exchange.lower()][2].fetch_order_book( symbol=symbol, limit=1)['bids'][0][0]), decimals) # create SELL order if disable_trading == False: use_function[exchange.lower()][1].create_market_sell_order( symbol, amount_crypto, {'type': 'market'}) time.sleep(api_cooldown) current_position = -1 print('Initial SHORT (Market Order)') # create TRAILING-STOP order, BUY if set_trailing_stop == True: if disable_trading == False: symbol_trades = [ trade for trade in use_function[exchange.lower()] [1].fetch_my_trades(symbol=symbol) ] use_function[exchange.lower()][1].create_order( symbol=symbol, type='trailing-stop', side='buy', amount=amount_crypto, price=round( float(symbol_trades[-1]['price']) * (trailing_stop_pct / 100), 4)) print('Initial Trailing-Stop (BUY)') time.sleep(api_cooldown) if disable_trading == False: current_entry_price = float( bitfinex.fetch_my_trades(symbol=symbol, limit=1)[0]['info']['price']) ### END OF TRADER ###################################################################################### ### LOG OUTPUT ######################################################################################### print( '>>> BOT LOG <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<' ) # only show the full output when the position changes if next_position != old_position: n_trades += 1 print(' < ' + symbol + ' | ' + timeframe + ' | ' + exchange + ' | Iterations: ' + str(loops_per_timeframe) + ' | Inception: ' + inception_time + ' >') print('| Strategy: \t\t\t\t' + str(moving_average_type)) print('| Short Moving Average Period: \t\t' + str(short_period)) print('| Long Moving Average Period: \t\t' + str(long_period)) print('| Amount to Trade: \t\t\tUSD ' + str(amount_usd_to_trade)) if disable_trading == False: print('| Trailing Stop: \t\t\t' + str(set_trailing_stop)) if set_trailing_stop == True: print('| Trailing Stop Distance: \t\t' + str(trailing_stop_pct) + '%') print('| Date and Time: \t\t\t' + str( datetime.datetime.fromtimestamp(int(time.time())).strftime( '%d-%m-%Y %H:%M:%S'))) print() if old_position != 0: print(' -- Old Position: \t\t\t' + ('LONG' if int(old_position) == 1 else 'SHORT')) print(' -- Current Position: \t\t\t' + ('LONG' if int(current_position) == 1 else 'SHORT')) print(' -- Amount Crypto: \t\t\t' + str(symbol.split('/')[0]) + ' ' + str(round(amount_crypto, 5))) print(' -- Entry Price (Fee Adj.): \t\t' + str(symbol.split('/')[1]) + ' ' + str( round( float(current_entry_price * (1 + (bitfinex_taker_fee / 100))) if next_position == 1 else float(current_entry_price * (1 - (bitfinex_taker_fee / 100))), decimals))) print(' -- Entry Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' + str(current_entry_price)) print() print(' -- Current Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' + str(round(df['Close'].iloc[-1], decimals))) print(' -- Short Moving Average Value: \t' + str(symbol.split('/')[1]) + ' ' + str(round(short_ma.iloc[-1], decimals))) print(' -- Long Moving Average Value: \t' + str(symbol.split('/')[1]) + ' ' + str(round(long_ma.iloc[-1], decimals))) print() # the below is printed only after the first position is exited if old_entry_price_adjusted != 0: print(' -- Old Entry Price (Fee Adj.): \t' + str(symbol.split('/')[1]) + ' ' + str(round(old_entry_price_adjusted, decimals))) adjusted_profit = (( ((float(current_entry_price * (1 + (bitfinex_taker_fee / 100))) if next_position == 1 else float(current_entry_price * (1 - (bitfinex_taker_fee / 100)))) - old_entry_price_adjusted) / old_entry_price_adjusted) * 100 * int(old_position)) print(' -- Approximate P/L (Fee Adj.): \t' + str(round(adjusted_profit, decimals)) + '%') cumulated_profit += adjusted_profit print(' -- Cumulated P/L (Fee Adj.): \t\t' + str(round(cumulated_profit, decimals)) + '%') print(' -- Trades since Inception: \t\t' + str(n_trades)) # if the position changed update the old entry price old_entry_price_adjusted = float( current_entry_price * (1 + (bitfinex_taker_fee / 100))) if next_position == 1 else float( current_entry_price * (1 - (bitfinex_taker_fee / 100))) # calculate fee expenses per trade (to have it available) position_trading_fees = current_entry_price * (1 + ( (bitfinex_taker_fee * amount_crypto) / 100)) print() # leave some space for nicely formatted output if next_position == old_position: print(' -- Entry Price (Fee Adj.): \t\t' + str(symbol.split('/')[1]) + ' ' + str( round( float(current_entry_price * (1 + (bitfinex_taker_fee / 100))) if next_position == 1 else float(current_entry_price * (1 - (bitfinex_taker_fee / 100))), decimals))) print(' -- Current Price: \t\t\t' + str(symbol.split('/')[1]) + ' ' + str(round(df['Close'].iloc[-1], decimals))) print(' -- Short Moving Average Value: \t' + str(symbol.split('/')[1]) + ' ' + str(round(short_ma.iloc[-1], decimals))) print(' -- Long Moving Average Value: \t' + str(symbol.split('/')[1]) + ' ' + str(round(long_ma.iloc[-1], decimals))) # print current date and time for reference print('| Date and Time: \t\t\t' + str( datetime.datetime.fromtimestamp(int(time.time())).strftime( '%d-%m-%Y %H:%M:%S'))) # update value for old_position old_position = current_position # sleep for ((one timeframe) / (how often to reevaluate the position within the timeframe)) # - time it took to run one full bot iteration time.sleep(((timeframes[timeframe] / loops_per_timeframe) / 1000) - (time.time() - start))
def compute(self, data_dict): close = data_dict.get('close') return ti.ema(close, self.per)
def Main(): global pair, HEADER, interval, last_rsi, last_rsiema, in_position """Convert Binance api output into data usable by Python """ binance_client = Client(config.binance_api_key, config.binance_secret_key) binance_data = binance_client.get_klines(symbol=pair, interval=Client.KLINE_INTERVAL_1MINUTE) """ Creates/Opens a CSV-file then overwrites it with data from binance_data """ with open('ohlc_data.csv', 'w', newline='') as csvfile: reader = csv.DictReader(csvfile) csvwriter = csv.writer(csvfile, delimiter=',') for i in binance_data: csvwriter.writerow(i) """ Specify which columns are which """ ohlc_data = genfromtxt('ohlc_data.csv', delimiter=',') opentimes = numpy.array(ohlc_data[:,0]) opens = numpy.array(ohlc_data[:,1]) highs = numpy.array(ohlc_data[:,2]) lows = numpy.array(ohlc_data[:,3]) closes = numpy.array(ohlc_data[:,4]) volumes = numpy.array(ohlc_data[:,5]) closetimes = numpy.array(ohlc_data[:,6]) quotevolumes = numpy.array(ohlc_data[:,7]) """ Indicators """ rsis = tulipy.rsi(closes, period = 14) rsiemas = tulipy.ema(rsis, period = 22) ema200s = tulipy.ema(closes, period = 200) ema50s = tulipy.ema(closes, period = 50) ema22s = tulipy.ema(closes, period = 22) obvs = tulipy.obv(closes, volumes) obvemas = tulipy.ema(obvs, period = 100) last_rsi = rsis[-1] last_rsiema = rsiemas[-1] last_ema22 = ema22s[-1] last_ema50 = ema50s[-1] last_ema200 = ema200s[-1] last_obv = obvs[-1] last_obvema = obvemas[-1] """ Last ohlc """ last_open = opens[-1] last_high = highs[-1] last_low = lows[-1] last_close = closes[-1] open_updown_color = fg.Bwhite close_updown_color = fg.Bwhite high_updown_color = fg.Bwhite low_updown_color = fg.Bwhite next_to_last_open = opens[-2] next_to_last_high = highs[-2] next_to_last_low = lows[-2] next_to_last_close = closes[-2] if last_open > next_to_last_open: open_updown_color = fg.Bgreen else: open_updown_color = fg.Bred if last_close > next_to_last_close: close_updown_color = fg.Bgreen else: open_updown_color = fg.Bred if last_high > next_to_last_high: high_updown_color = fg.Bgreen else: high_updown_color = fg.Bred if last_low > next_to_last_low: low_updown_color = fg.Bgreen else: low_updown_color = fg.Bred if last_obv > last_obvema: obv_emoji_signal = '🟢' else: obv_emoji_signal = '🟥' if last_rsi > last_rsiema: rsi_emoji_signal = '🟢' else: rsi_emoji_signal = '🟥' if last_close > last_ema50 and last_close > last_ema200: ema_emoji_signal = '🟢' else: ema_emoji_signal = '🟥' INFO_TABLE = f"""In Trade:{bg.red}{in_position}{ac.clear} Pair:{pair} Strat:{strat} Quantity:{asset_qauntity} {fg.Bwhite} LAST:{ac.clear} Open - {open_updown_color}{last_open}{ac.clear} Close - {close_updown_color}{last_close}{ac.clear} High - {high_updown_color}{last_close}{ac.clear} Low - {low_updown_color}{last_close}{fg.Bwhite} INDICATORS:{ac.clear} RSI - {round(last_rsi, 4)} RSIema - {round(last_rsiema, 4)} EMA22 - {round(last_ema22, 4)} EMA50 - {round(last_ema50, 4)} EMA200 - {round(last_ema200, 4)} {fg.white}RSI bull/bear - {rsi_emoji_signal} EMA bull/bear - {ema_emoji_signal} OBV bull/bear - {obv_emoji_signal} """ """UI logic.""" table_grid = [[''], [''], ['']] table = SingleTable(table_grid) table.table_data[1][0] = INFO_TABLE table.table_data[0][0] = HEADER table.table_data[2][0] = output print(table.table)
def ema(self): try: return ema(self.data, 11) except Exception: logging.exception('')
df = df.loc['2007-04-25':'2007-10-07'] #фильтр для детализации plt.plot(df.index, df['test'], label='test') plt.plot(df.index, df['MA'], label='MA', color='red') plt.plot(df.index, df['EMA'], label='EMA', color='green') plt.legend() plt.title('Microsoft') plt.ylabel('Price($)') plt.show() df.plot(y=['RSI']) df.plot(y=['Stochastic']) #Tulip Indicators stoch_k, stoch_d = ti.stoch(high, low, z, 5, 3, 3) sma = ti.sma(y, 5) rsi = ti.rsi(z, 14) ema = ti.ema(y, 5) print('MA: ', sma) print('EMA: ', ema) print('RSI: ', rsi) print('Stochastic: ', stoch_d) # In[44]: new_o # In[29]: df # In[55]: