def get_moving_average_analysis(data, current_moving_average, time_period): time_period_unit_moving_average = tulipy.sma(data, time_period) # equalize array size min_len_arrays = min(len(time_period_unit_moving_average), len(current_moving_average)) # compute difference between 1 unit values and others ( >0 means currently up the other one) values_difference = (current_moving_average[-min_len_arrays:] - time_period_unit_moving_average[-min_len_arrays:]) values_difference = DataUtil.drop_nan(values_difference) if len(values_difference): # indexes where current_unit_moving_average crosses time_period_unit_moving_average crossing_indexes = TrendAnalysis.get_threshold_change_indexes(values_difference, 0) multiplier = 1 if values_difference[-1] > 0 else -1 # check at least some data crossed 0 if crossing_indexes: normalized_data = DataUtil.normalize_data(values_difference) current_value = min(abs(normalized_data[-1])*2, 1) if math.isnan(current_value): return 0 # check <= values_difference.count()-1if current value is max/min if current_value == 0 or current_value == 1: chances_to_be_max = TrendAnalysis.get_estimation_of_move_state_relatively_to_previous_moves_length( crossing_indexes, values_difference) return multiplier*current_value*chances_to_be_max # other case: maxima already reached => return distance to max else: return multiplier*current_value # just crossed the average => neutral return 0
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)))