tendencyCalculator
1from numpy import average 2import pandas as pd 3 4BIG_NUMBER = 999999999 5predefined_type_of_price = 'Close' 6 7#TODO Añadir que con longer dataset compruebe si pasa la resistencia 8 9def findPatternTendency(data_sequence, longer_data_sequence, type): 10 """Method to redirect and calculate the tendency for a given dataframe""" 11 if type == 'double_top': 12 return findDoubleTopTendency(data_sequence, longer_data_sequence) 13 if type == 'double_bottom': 14 return findDoubleBottomTendency(data_sequence, longer_data_sequence) 15 else: 16 raise Exception('Pattern type not found') 17 18def findDoubleTopTendency(data_sequence, longer_data_sequence): 19 """Calculates the tendency for a double top pattern 20 21 Args: 22 data_sequence (dataframe): dataframe representing the pattern 23 longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made 24 Return: 25 tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern 26 but it ends where the tendency was determined 27 """ 28 first_top = [0, None] #index 0 representa el valor y el index 1 representa la posicion dentro del dataframe 29 second_top = [0, None] 30 for i in range(data_sequence.size - 1): #Buscar los dos techos 31 day_value = data_sequence.iloc[i][predefined_type_of_price] 32 if i > 0: 33 previous_day_value = data_sequence.iloc[i - 1][predefined_type_of_price] 34 if i < data_sequence.size - 1: 35 next_day_value = data_sequence.iloc[i + 1][predefined_type_of_price] 36 if i > 0 and previous_day_value < day_value and day_value > next_day_value: #hemos encontrado un maximo 37 relative_maximum = day_value 38 if relative_maximum > first_top[0]: # [1] para acceder a lo que no es timestamps y Close porque es la etiqueta del valor 39 first_top = second_top 40 second_top = [relative_maximum, i] 41 elif relative_maximum > second_top[0]: 42 second_top = [relative_maximum, i] 43 44 if first_top[1] == None or second_top[1] == None: 45 return None #No se encontraron dos techos 46 47 resistance = [BIG_NUMBER, None] 48 for i in range(first_top[1], second_top[1]): #Busqueda de la linea de apoyo 49 current_value = data_sequence.iloc[i][predefined_type_of_price] 50 if current_value < resistance[0]: 51 resistance[0] = current_value 52 resistance[1] = i 53 54 #Añadir que los dos techo no estas muy lejos, como mucho en la mitad entre el mas alto y la linea de soporte 55 56 first_top_to_resistance_distance = first_top[0] - resistance[0] 57 second_top_to_resistance_distance = second_top[0] - resistance[0] 58 if first_top_to_resistance_distance > second_top_to_resistance_distance and second_top_to_resistance_distance < first_top_to_resistance_distance * 2 / 3: 59 return None # Demasiada diferencia entre techos 60 if second_top_to_resistance_distance > first_top_to_resistance_distance and first_top_to_resistance_distance < second_top_to_resistance_distance * 2 / 3: 61 return None # Demasiada diferencia entre techos 62 63 breaks_resistance_from_left = [False, None] 64 breaks_resistance_from_right = [False, None] 65 66 #Confirmar que en rompe por la linea de apoyo en ambos lados 67 i = first_top[1] 68 while i >= 0 and not breaks_resistance_from_left[0]: 69 current_value_left = data_sequence.iloc[i][predefined_type_of_price] 70 if current_value_left < resistance[0]: 71 breaks_resistance_from_left[0] = True 72 breaks_resistance_from_left[1] = i 73 i -= 1 74 75 # Hacer esto pero en longer dataset 76 i = second_top[1] 77 while i < data_sequence.size and not breaks_resistance_from_right[0]: 78 current_value_right = data_sequence.iloc[i][predefined_type_of_price] 79 if current_value_right < resistance[0]: 80 breaks_resistance_from_right[0] = True 81 breaks_resistance_from_right[1] = i 82 i += 1 83 84 if breaks_resistance_from_left[1] is None or breaks_resistance_from_right[1] is None: # Comprobar que se rompe la linea de apoyo 85 return None 86 #DiscardPatterns 87 #Una vez rompe el patron, debemos averiguar en que direccion 88 89 pattern_width = breaks_resistance_from_right[1] - breaks_resistance_from_left[1] 90 91 average_height = ((first_top[0] + second_top[0]) / 2) - resistance[0] 92 objective = resistance[0] - average_height 93 94 if pattern_width: 95 for i in range(breaks_resistance_from_right[1], breaks_resistance_from_right[1] + pattern_width * 2): 96 if i >= longer_data_sequence.size: 97 break 98 current_value = longer_data_sequence.iloc[i][predefined_type_of_price] 99 if current_value > resistance[0]: 100 return [False, longer_data_sequence.iloc[:i + 1]] 101 if current_value < objective: 102 return [True, longer_data_sequence.iloc[:i + 1]] 103 else: 104 return None #Significa que el valor no cruzo ningun limite 105 106def findDoubleBottomTendency(data_sequence, longer_data_sequence): 107 """Calculates the tendency for a double top pattern 108 109 Args: 110 data_sequence (dataframe): dataframe representing the pattern 111 longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made 112 Return: 113 tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern 114 but it ends where the tendency was determined 115 """ 116 first_bottom = [BIG_NUMBER, None] #index 0 representa el valor y el index 1 representa la posicion dentro del dataframe 117 second_bottom = [BIG_NUMBER, None] 118 for i in range(data_sequence.size - 1): #Buscar los dos suelos 119 day_value = data_sequence.iloc[i][predefined_type_of_price] 120 if i > 0: 121 previous_day_value = data_sequence.iloc[i - 1][predefined_type_of_price] 122 if i < data_sequence.size - 1: 123 next_day_value = data_sequence.iloc[i + 1][predefined_type_of_price] 124 if i > 0 and previous_day_value > day_value and day_value < next_day_value: #hemos encontrado un minimo 125 relative_minimum = day_value 126 if relative_minimum < first_bottom[0]: # [1] para acceder a lo que no es timestamps y Close porque es la etiqueta del valor 127 first_bottom = second_bottom 128 second_bottom = [relative_minimum, i] 129 elif relative_minimum < second_bottom[0]: 130 second_bottom = [relative_minimum, i] 131 132 if first_bottom[1] == None or second_bottom[1] == None: 133 return None #No se encontraron dos suelos 134 135 resistance = [0, None] 136 for i in range(first_bottom[1], second_bottom[1]): #Busqueda de la linea de apoyo 137 current_value = data_sequence.iloc[i][predefined_type_of_price] 138 if current_value > resistance[0]: 139 resistance[0] = current_value 140 resistance[1] = i 141 142 # Comprobamos si los suelos no estan muy lejos 143 first_bottom_to_resistance_distance = resistance[0] - first_bottom[0] 144 second_bottom_to_resistance_distance = resistance[0] - second_bottom[0] 145 if first_bottom_to_resistance_distance > second_bottom_to_resistance_distance and second_bottom_to_resistance_distance < first_bottom_to_resistance_distance * 2 / 3: 146 return None # Demasiada diferencia entre suelos 147 if second_bottom_to_resistance_distance > first_bottom_to_resistance_distance and first_bottom_to_resistance_distance < second_bottom_to_resistance_distance * 2 / 3: 148 return None # Demasiada diferencia entre suelos 149 150 breaks_resistance_from_left = [False, None] 151 breaks_resistance_from_right = [False, None] 152 153 #Confirmar que en rompe por la linea de apoyo en ambos lados 154 i = first_bottom[1] 155 while i >= 0 and not breaks_resistance_from_left[0]: 156 current_value_left = data_sequence.iloc[i][predefined_type_of_price] 157 if current_value_left > resistance[0]: 158 breaks_resistance_from_left[0] = True 159 breaks_resistance_from_left[1] = i 160 i -= 1 161 162 # Hacer esto pero en longer dataset 163 i = second_bottom[1] 164 while i < data_sequence.size and not breaks_resistance_from_right[0]: 165 current_value_right = data_sequence.iloc[i][predefined_type_of_price] 166 if current_value_right > resistance[0]: 167 breaks_resistance_from_right[0] = True 168 breaks_resistance_from_right[1] = i 169 i += 1 170 171 if breaks_resistance_from_left[1] is None or breaks_resistance_from_right[1] is None: # Comprobar que se rompe la linea de apoyo 172 return None # Pattern\'s resistance not broken 173 #Una vez rompe el patron, debemos averiguar en que direccion 174 175 pattern_width = breaks_resistance_from_right[1] - breaks_resistance_from_left[1] 176 177 average_height = abs(((first_bottom[0] + second_bottom[0]) / 2) - resistance[0]) 178 objective = resistance[0] + average_height 179 if pattern_width: 180 for i in range(breaks_resistance_from_right[1], breaks_resistance_from_right[1] + pattern_width): 181 if i >= longer_data_sequence.size: 182 break 183 current_value = longer_data_sequence.iloc[i][predefined_type_of_price] 184 if current_value < resistance[0]: 185 return [False, longer_data_sequence.iloc[:i + 1]] 186 if current_value > objective: 187 return [True, longer_data_sequence.iloc[:i + 1]] 188 else: 189 return None #Significa que el valor no cruzo ningun limite
10def findPatternTendency(data_sequence, longer_data_sequence, type): 11 """Method to redirect and calculate the tendency for a given dataframe""" 12 if type == 'double_top': 13 return findDoubleTopTendency(data_sequence, longer_data_sequence) 14 if type == 'double_bottom': 15 return findDoubleBottomTendency(data_sequence, longer_data_sequence) 16 else: 17 raise Exception('Pattern type not found')
Method to redirect and calculate the tendency for a given dataframe
19def findDoubleTopTendency(data_sequence, longer_data_sequence): 20 """Calculates the tendency for a double top pattern 21 22 Args: 23 data_sequence (dataframe): dataframe representing the pattern 24 longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made 25 Return: 26 tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern 27 but it ends where the tendency was determined 28 """ 29 first_top = [0, None] #index 0 representa el valor y el index 1 representa la posicion dentro del dataframe 30 second_top = [0, None] 31 for i in range(data_sequence.size - 1): #Buscar los dos techos 32 day_value = data_sequence.iloc[i][predefined_type_of_price] 33 if i > 0: 34 previous_day_value = data_sequence.iloc[i - 1][predefined_type_of_price] 35 if i < data_sequence.size - 1: 36 next_day_value = data_sequence.iloc[i + 1][predefined_type_of_price] 37 if i > 0 and previous_day_value < day_value and day_value > next_day_value: #hemos encontrado un maximo 38 relative_maximum = day_value 39 if relative_maximum > first_top[0]: # [1] para acceder a lo que no es timestamps y Close porque es la etiqueta del valor 40 first_top = second_top 41 second_top = [relative_maximum, i] 42 elif relative_maximum > second_top[0]: 43 second_top = [relative_maximum, i] 44 45 if first_top[1] == None or second_top[1] == None: 46 return None #No se encontraron dos techos 47 48 resistance = [BIG_NUMBER, None] 49 for i in range(first_top[1], second_top[1]): #Busqueda de la linea de apoyo 50 current_value = data_sequence.iloc[i][predefined_type_of_price] 51 if current_value < resistance[0]: 52 resistance[0] = current_value 53 resistance[1] = i 54 55 #Añadir que los dos techo no estas muy lejos, como mucho en la mitad entre el mas alto y la linea de soporte 56 57 first_top_to_resistance_distance = first_top[0] - resistance[0] 58 second_top_to_resistance_distance = second_top[0] - resistance[0] 59 if first_top_to_resistance_distance > second_top_to_resistance_distance and second_top_to_resistance_distance < first_top_to_resistance_distance * 2 / 3: 60 return None # Demasiada diferencia entre techos 61 if second_top_to_resistance_distance > first_top_to_resistance_distance and first_top_to_resistance_distance < second_top_to_resistance_distance * 2 / 3: 62 return None # Demasiada diferencia entre techos 63 64 breaks_resistance_from_left = [False, None] 65 breaks_resistance_from_right = [False, None] 66 67 #Confirmar que en rompe por la linea de apoyo en ambos lados 68 i = first_top[1] 69 while i >= 0 and not breaks_resistance_from_left[0]: 70 current_value_left = data_sequence.iloc[i][predefined_type_of_price] 71 if current_value_left < resistance[0]: 72 breaks_resistance_from_left[0] = True 73 breaks_resistance_from_left[1] = i 74 i -= 1 75 76 # Hacer esto pero en longer dataset 77 i = second_top[1] 78 while i < data_sequence.size and not breaks_resistance_from_right[0]: 79 current_value_right = data_sequence.iloc[i][predefined_type_of_price] 80 if current_value_right < resistance[0]: 81 breaks_resistance_from_right[0] = True 82 breaks_resistance_from_right[1] = i 83 i += 1 84 85 if breaks_resistance_from_left[1] is None or breaks_resistance_from_right[1] is None: # Comprobar que se rompe la linea de apoyo 86 return None 87 #DiscardPatterns 88 #Una vez rompe el patron, debemos averiguar en que direccion 89 90 pattern_width = breaks_resistance_from_right[1] - breaks_resistance_from_left[1] 91 92 average_height = ((first_top[0] + second_top[0]) / 2) - resistance[0] 93 objective = resistance[0] - average_height 94 95 if pattern_width: 96 for i in range(breaks_resistance_from_right[1], breaks_resistance_from_right[1] + pattern_width * 2): 97 if i >= longer_data_sequence.size: 98 break 99 current_value = longer_data_sequence.iloc[i][predefined_type_of_price] 100 if current_value > resistance[0]: 101 return [False, longer_data_sequence.iloc[:i + 1]] 102 if current_value < objective: 103 return [True, longer_data_sequence.iloc[:i + 1]] 104 else: 105 return None #Significa que el valor no cruzo ningun limite
Calculates the tendency for a double top pattern
Args:
data_sequence (dataframe): dataframe representing the pattern
longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made
Return:
tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern
but it ends where the tendency was determined
107def findDoubleBottomTendency(data_sequence, longer_data_sequence): 108 """Calculates the tendency for a double top pattern 109 110 Args: 111 data_sequence (dataframe): dataframe representing the pattern 112 longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made 113 Return: 114 tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern 115 but it ends where the tendency was determined 116 """ 117 first_bottom = [BIG_NUMBER, None] #index 0 representa el valor y el index 1 representa la posicion dentro del dataframe 118 second_bottom = [BIG_NUMBER, None] 119 for i in range(data_sequence.size - 1): #Buscar los dos suelos 120 day_value = data_sequence.iloc[i][predefined_type_of_price] 121 if i > 0: 122 previous_day_value = data_sequence.iloc[i - 1][predefined_type_of_price] 123 if i < data_sequence.size - 1: 124 next_day_value = data_sequence.iloc[i + 1][predefined_type_of_price] 125 if i > 0 and previous_day_value > day_value and day_value < next_day_value: #hemos encontrado un minimo 126 relative_minimum = day_value 127 if relative_minimum < first_bottom[0]: # [1] para acceder a lo que no es timestamps y Close porque es la etiqueta del valor 128 first_bottom = second_bottom 129 second_bottom = [relative_minimum, i] 130 elif relative_minimum < second_bottom[0]: 131 second_bottom = [relative_minimum, i] 132 133 if first_bottom[1] == None or second_bottom[1] == None: 134 return None #No se encontraron dos suelos 135 136 resistance = [0, None] 137 for i in range(first_bottom[1], second_bottom[1]): #Busqueda de la linea de apoyo 138 current_value = data_sequence.iloc[i][predefined_type_of_price] 139 if current_value > resistance[0]: 140 resistance[0] = current_value 141 resistance[1] = i 142 143 # Comprobamos si los suelos no estan muy lejos 144 first_bottom_to_resistance_distance = resistance[0] - first_bottom[0] 145 second_bottom_to_resistance_distance = resistance[0] - second_bottom[0] 146 if first_bottom_to_resistance_distance > second_bottom_to_resistance_distance and second_bottom_to_resistance_distance < first_bottom_to_resistance_distance * 2 / 3: 147 return None # Demasiada diferencia entre suelos 148 if second_bottom_to_resistance_distance > first_bottom_to_resistance_distance and first_bottom_to_resistance_distance < second_bottom_to_resistance_distance * 2 / 3: 149 return None # Demasiada diferencia entre suelos 150 151 breaks_resistance_from_left = [False, None] 152 breaks_resistance_from_right = [False, None] 153 154 #Confirmar que en rompe por la linea de apoyo en ambos lados 155 i = first_bottom[1] 156 while i >= 0 and not breaks_resistance_from_left[0]: 157 current_value_left = data_sequence.iloc[i][predefined_type_of_price] 158 if current_value_left > resistance[0]: 159 breaks_resistance_from_left[0] = True 160 breaks_resistance_from_left[1] = i 161 i -= 1 162 163 # Hacer esto pero en longer dataset 164 i = second_bottom[1] 165 while i < data_sequence.size and not breaks_resistance_from_right[0]: 166 current_value_right = data_sequence.iloc[i][predefined_type_of_price] 167 if current_value_right > resistance[0]: 168 breaks_resistance_from_right[0] = True 169 breaks_resistance_from_right[1] = i 170 i += 1 171 172 if breaks_resistance_from_left[1] is None or breaks_resistance_from_right[1] is None: # Comprobar que se rompe la linea de apoyo 173 return None # Pattern\'s resistance not broken 174 #Una vez rompe el patron, debemos averiguar en que direccion 175 176 pattern_width = breaks_resistance_from_right[1] - breaks_resistance_from_left[1] 177 178 average_height = abs(((first_bottom[0] + second_bottom[0]) / 2) - resistance[0]) 179 objective = resistance[0] + average_height 180 if pattern_width: 181 for i in range(breaks_resistance_from_right[1], breaks_resistance_from_right[1] + pattern_width): 182 if i >= longer_data_sequence.size: 183 break 184 current_value = longer_data_sequence.iloc[i][predefined_type_of_price] 185 if current_value < resistance[0]: 186 return [False, longer_data_sequence.iloc[:i + 1]] 187 if current_value > objective: 188 return [True, longer_data_sequence.iloc[:i + 1]] 189 else: 190 return None #Significa que el valor no cruzo ningun limite
Calculates the tendency for a double top pattern
Args:
data_sequence (dataframe): dataframe representing the pattern
longer_data_sequence (dataframe): dataframe representing the pattern but ends on the day the search is made
Return:
tendency (Pair[]): first element for True, False or None, and second element for the specific dataframe containing the pattern
but it ends where the tendency was determined