async def evaluate(self, cryptocurrency, symbol, time_frame, candle_data, candle): if candle_data is not None and len(candle_data) > self.period_length: rsi_v = tulipy.rsi(candle_data, period=self.period_length) if len(rsi_v) and not math.isnan(rsi_v[-1]): long_trend = EvaluatorUtil.TrendAnalysis.get_trend(rsi_v, self.long_term_averages) short_trend = EvaluatorUtil.TrendAnalysis.get_trend(rsi_v, self.short_term_averages) # check if trend change if short_trend > 0 > long_trend: # trend changed to up self.set_eval_note(-short_trend) elif long_trend > 0 > short_trend: # trend changed to down self.set_eval_note(short_trend) # use RSI current value last_rsi_value = rsi_v[-1] if last_rsi_value > 50: self.set_eval_note(rsi_v[-1] / 200) else: self.set_eval_note((rsi_v[-1] - 100) / 200) await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame)) return self.eval_note = commons_constants.START_PENDING_EVAL_NOTE await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
async def ohlcv_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, candle, inc_in_construction_data): symbol_candles = self.get_exchange_symbol_data(exchange, exchange_id, symbol) high_candles = trading_api.get_symbol_high_candles( symbol_candles, time_frame, include_in_construction=inc_in_construction_data) if len(high_candles) >= self.short_period: low_candles = trading_api.get_symbol_low_candles( symbol_candles, time_frame, include_in_construction=inc_in_construction_data) close_candles = trading_api.get_symbol_close_candles( symbol_candles, time_frame, include_in_construction=inc_in_construction_data) volume_candles = trading_api.get_symbol_volume_candles( symbol_candles, time_frame, include_in_construction=inc_in_construction_data) await self.evaluate(cryptocurrency, symbol, time_frame, high_candles, low_candles, close_candles, volume_candles, candle) else: self.eval_note = False await self.evaluation_completed( cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
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))
async def evaluate(self, cryptocurrency, symbol, time_frame, candle_data, candle): try: if len(candle_data) >= self.period * 2: stochrsi_value = tulipy.stochrsi( data_util.drop_nan(candle_data), self.period)[-1] if stochrsi_value * self.TULIPY_INDICATOR_MULTIPLICATOR >= self.evaluator_config[ self.HIGH_LEVEL]: self.eval_note = 1 elif stochrsi_value * self.TULIPY_INDICATOR_MULTIPLICATOR <= self.evaluator_config[ self.LOW_LEVEL]: self.eval_note = -1 else: self.eval_note = stochrsi_value - 0.5 except tulipy.lib.InvalidOptionError as e: self.logger.debug(f"Error when computing StochRSI: {e}") self.logger.exception(e, False) self.eval_note = commons_constants.START_PENDING_EVAL_NOTE await self.evaluation_completed( cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
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: time_units = [5, self.long_period_length] current_moving_average = tulipy.sma(candle_data, 2) results = [ self.get_moving_average_analysis(candle_data, current_moving_average, time_unit) for time_unit in time_units ] if len(results): self.eval_note = numpy.mean(results) else: self.eval_note = commons_constants.START_PENDING_EVAL_NOTE if self.eval_note == 0: self.eval_note = commons_constants.START_PENDING_EVAL_NOTE await self.evaluation_completed( cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
async def ohlcv_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, candle, inc_in_construction_data): exchange_symbol_data = self.get_exchange_symbol_data( exchange, exchange_id, symbol) high = trading_api.get_symbol_high_candles( exchange_symbol_data, time_frame, include_in_construction=inc_in_construction_data) low = trading_api.get_symbol_low_candles( exchange_symbol_data, time_frame, include_in_construction=inc_in_construction_data) close = trading_api.get_symbol_close_candles( exchange_symbol_data, time_frame, include_in_construction=inc_in_construction_data) self.eval_note = commons_constants.START_PENDING_EVAL_NOTE if len(close) > self.length: await self.evaluate(cryptocurrency, symbol, time_frame, candle, high, low, close) await self.evaluation_completed( cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
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))
async def ohlcv_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, candle): volume_data = self.get_symbol_candles(exchange, exchange_id, symbol, time_frame). \ get_symbol_volume_candles(self.candle_segments[0]) close_data = self.get_symbol_candles(exchange, exchange_id, symbol, time_frame). \ get_symbol_close_candles(self.candle_segments[0]) for segment in self.candle_segments: volume_data = [d for d in volume_data[-segment:] if d is not None] price_data = [d for d in close_data[-segment:] if d is not None] self.average_volumes[segment] = np.mean(volume_data) self.average_prices[segment] = np.mean(price_data) try: self.last_volume = volume_data[-1] self.last_price = close_data[-1] await self._trigger_evaluation( cryptocurrency, symbol, evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame)) except IndexError: # candles data history is probably not yet available self.logger.debug( f"Impossible to evaluate, no historical data for {symbol} on {time_frame}" )
async def kline_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, kline): if symbol in self.last_moving_average_values and len(self.last_moving_average_values[symbol]) > 0: self.eval_note = 0 last_price = kline[commons_enums.PriceIndexes.IND_PRICE_CLOSE.value] if last_price != self.last_candle_data[symbol][-1]: await self._evaluate_current_price(last_price, cryptocurrency, symbol, evaluators_util.get_eval_time(kline=kline))
async def kline_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, kline): self.last_volume = kline[ commons_enums.PriceIndexes.IND_PRICE_VOL.value] self.last_price = kline[ commons_enums.PriceIndexes.IND_PRICE_CLOSE.value] await self._trigger_evaluation( cryptocurrency, symbol, evaluators_util.get_eval_time(kline=kline))
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))
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_length: # compute bollinger bands lower_band, middle_band, upper_band = tulipy.bbands( candle_data, self.period_length, 2) # if close to lower band => low value => bad, # therefore if close to middle, value is keeping up => good # finally if up the middle one or even close to the upper band => very good current_value = candle_data[-1] current_up = upper_band[-1] current_middle = middle_band[-1] current_low = lower_band[-1] delta_up = current_up - current_middle delta_low = current_middle - current_low # its exactly on all bands if current_up == current_low: self.eval_note = commons_constants.START_PENDING_EVAL_NOTE # exactly on the middle elif current_value == current_middle: self.eval_note = 0 # up the upper band elif current_value > current_up: self.eval_note = 1 # down the lower band elif current_value < current_low: self.eval_note = -1 # regular values case: use parabolic factor all the time else: # up the middle band if current_middle < current_value: self.eval_note = math.pow( (current_value - current_middle) / delta_up, 2) # down the middle band elif current_middle > current_value: self.eval_note = -1 * math.pow( (current_middle - current_value) / delta_low, 2) await self.evaluation_completed( cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
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))
async def ohlcv_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, candle): self.eval_note = 0 new_data = self.get_symbol_candles(exchange, exchange_id, symbol, time_frame). \ get_symbol_close_candles(20) should_eval = symbol not in self.last_candle_data or \ not self._compare_data(new_data, self.last_candle_data[symbol]) self.last_candle_data[symbol] = new_data if should_eval: if len(self.last_candle_data[symbol]) > self.period: self.last_moving_average_values[symbol] = tulipy.sma(self.last_candle_data[symbol], self.period) await self._evaluate_current_price(self.last_candle_data[symbol][-1], cryptocurrency, symbol, evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
async def ohlcv_callback(self, exchange: str, exchange_id: str, cryptocurrency: str, symbol: str, time_frame, candle): volume_data = self.get_symbol_candles(exchange, exchange_id, symbol, time_frame). \ get_symbol_volume_candles(self.candle_segments[0]) close_data = self.get_symbol_candles(exchange, exchange_id, symbol, time_frame). \ get_symbol_close_candles(self.candle_segments[0]) for segment in self.candle_segments: volume_data = [d for d in volume_data[-segment:] if d is not None] price_data = [d for d in close_data[-segment:] if d is not None] self.average_volumes[segment] = np.mean(volume_data) self.average_prices[segment] = np.mean(price_data) self.last_volume = volume_data[-1] self.last_price = close_data[-1] await self._trigger_evaluation(cryptocurrency, symbol, evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
async def evaluate(self, cryptocurrency, symbol, time_frame, slow_rsi, fast_rsi, rsi_v, current_candle_time, candle): self.eval_note = commons_constants.START_PENDING_EVAL_NOTE if slow_rsi is not None and fast_rsi is not None and rsi_v is not None: last_rsi_values_to_consider = 5 analysed_rsi = rsi_v[-last_rsi_values_to_consider:] peak_reached = EvaluatorUtil.TrendAnalysis.min_has_just_been_reached(analysed_rsi, acceptance_window=0.95, delay=2) if peak_reached: price_weight, volume_weight = self._analyse_dip_weight(slow_rsi, fast_rsi, rsi_v[-1]) if price_weight is not None and volume_weight is not None: self.eval_note = { "price_weight": price_weight, "volume_weight": volume_weight, "current_candle_time": current_candle_time } await self.evaluation_completed(cryptocurrency, symbol, time_frame, eval_time=evaluators_util.get_eval_time(full_candle=candle, time_frame=time_frame))
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_time(self): return evaluators_util.get_eval_time(full_candle=self.candle, time_frame=self.time_frame)