From 1af4fe8460eb1080a82452e4a5ccc8179736684c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Delacotte?= Date: Thu, 15 May 2025 18:58:37 +0200 Subject: [PATCH] =?UTF-8?q?Ajout=20calcul=20de=20probabilit=C3=A9=20foncti?= =?UTF-8?q?on=20de=202=20indicateurs=20/=20stats=20calcul=C3=A9es=20depuis?= =?UTF-8?q?=202020?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Zeus_8_3_2_B_4_2.py | 110 ++++++++++++++++---------- tools/statistique/carte_thermique2.py | 33 ++++++++ 2 files changed, 100 insertions(+), 43 deletions(-) create mode 100644 tools/statistique/carte_thermique2.py diff --git a/Zeus_8_3_2_B_4_2.py b/Zeus_8_3_2_B_4_2.py index 1cba177..7fbbd2f 100644 --- a/Zeus_8_3_2_B_4_2.py +++ b/Zeus_8_3_2_B_4_2.py @@ -209,22 +209,57 @@ class Zeus_8_3_2_B_4_2(IStrategy): protection_fibo = IntParameter(1, 10, default=2, space='protection') sell_allow_decrease = DecimalParameter(0.005, 0.02, default=0.2, decimals=2, space='sell', optimize=True, load=True) + # Probabilité de hausse pour futur_percent_3h (en %): + # mid_smooth_deriv1_1h_bin B5 B4 B3 B2 B1 N0 H1 H2 H3 H4 H5 + # sma24_diff_1h_bin + # B5 41.0 47.2 48.1 45.6 74.0 65.9 66.5 83.8 77.8 72.1 81.0 + # B4 41.2 35.8 48.4 46.5 59.9 60.2 75.8 79.4 84.6 83.0 78.5 + # B3 34.1 39.7 42.8 47.0 63.3 64.5 71.5 80.4 82.0 86.6 76.6 + # B2 27.5 27.9 32.3 33.2 61.9 67.1 70.8 79.5 81.3 73.6 81.9 + # B1 35.0 26.5 24.4 34.9 50.0 59.2 69.4 72.8 79.8 77.4 69.5 + # N0 30.6 19.9 23.6 30.8 41.9 59.2 67.5 70.6 74.0 63.0 75.0 + # H1 25.2 28.7 28.6 25.8 35.9 44.2 60.1 68.8 67.7 69.6 80.9 + # H2 29.8 20.8 23.9 30.4 34.4 37.5 52.7 66.1 69.8 67.5 62.9 + # H3 25.7 29.4 22.7 29.8 37.7 47.1 59.9 68.5 66.5 68.6 66.4 + # H4 30.6 27.5 25.1 22.6 30.8 34.1 50.9 59.8 57.0 68.6 63.7 + # H5 14.8 21.6 22.2 35.3 19.3 31.6 38.3 59.6 65.2 56.8 59.6 + + # Données sous forme de dictionnaire data = { - "B5": [41.0, 41.2, 34.1, 27.5, 35.0, 30.6, 25.2, 29.8, 25.7, 30.6, 14.8], - "B4": [47.2, 35.8, 39.7, 27.9, 26.5, 19.9, 28.7, 20.8, 29.4, 27.5, 21.6], - "B3": [48.1, 48.4, 42.8, 32.3, 24.4, 23.6, 28.6, 23.9, 22.7, 25.1, 22.2], - "B2": [45.6, 46.5, 47.0, 33.2, 34.9, 30.8, 25.8, 30.4, 29.8, 22.6, 35.3], - "B1": [74.0, 59.9, 63.3, 61.9, 50.0, 41.9, 35.9, 34.4, 37.7, 30.8, 19.3], - "N0": [65.9, 60.2, 64.5, 67.1, 59.2, 59.2, 44.2, 37.5, 47.1, 34.1, 31.6], - "H1": [66.5, 75.8, 71.5, 70.8, 69.4, 67.5, 60.1, 52.7, 59.9, 50.9, 38.3], - "H2": [83.8, 79.4, 80.4, 79.5, 72.8, 70.6, 68.8, 66.1, 68.5, 59.8, 59.6], - "H3": [77.8, 84.6, 82.0, 81.3, 79.8, 74.0, 67.7, 69.8, 66.5, 57.0, 65.2], - "H4": [72.1, 83.0, 86.6, 73.6, 77.4, 63.0, 69.6, 67.5, 68.6, 68.6, 56.8], - "H5": [81.0, 78.5, 76.6, 81.9, 69.5, 75.0, 80.9, 62.9, 66.4, 63.7, 59.6] + 'B5': [41.2, 41.9, 35.3, 29.5, 26.6, 32.7, 28.8, 30.4, 25.3, 20.2, 14.6], + 'B4': [45.2, 40.1, 38.6, 31.2, 30.1, 29.5, 27.1, 24.2, 24.7, 21.6, 18.4], + 'B3': [46.7, 41.6, 37.3, 33.4, 27.3, 28.6, 28.8, 24.6, 24.2, 24.8, 23.2], + 'B2': [49.4, 47.9, 45.9, 39.8, 34.6, 28.6, 26.2, 28.9, 24.7, 29.7, 28.5], + 'B1': [74.1, 61.7, 61.7, 58.2, 50.2, 43.5, 38.1, 32.5, 33.9, 32.8, 25.3], + 'N0': [67.8, 58.3, 67.8, 61.7, 58.0, 56.2, 46.7, 42.2, 44.4, 39.7, 30.3], + 'H1': [72.6, 66.2, 70.8, 69.1, 70.8, 65.3, 56.3, 51.2, 52.6, 53.9, 48.1], + 'H2': [77.2, 78.7, 81.0, 75.9, 73.6, 73.0, 65.4, 63.3, 63.8, 56.9, 52.8], + 'H3': [78.8, 76.6, 78.8, 81.2, 76.7, 71.9, 69.2, 67.8, 66.1, 61.3, 58.1], + 'H4': [75.5, 79.0, 78.0, 78.5, 73.6, 66.4, 71.2, 63.8, 67.0, 62.6, 59.3], + 'H5': [75.1, 78.6, 81.0, 72.3, 70.0, 71.4, 67.8, 66.0, 66.2, 64.5, 59.9] } + # data = { + # "B5": [41.0, 41.2, 34.1, 27.5, 35.0, 30.6, 25.2, 29.8, 25.7, 30.6, 14.8], + # "B4": [47.2, 35.8, 39.7, 27.9, 26.5, 19.9, 28.7, 20.8, 29.4, 27.5, 21.6], + # "B3": [48.1, 48.4, 42.8, 32.3, 24.4, 23.6, 28.6, 23.9, 22.7, 25.1, 22.2], + # "B2": [45.6, 46.5, 47.0, 33.2, 34.9, 30.8, 25.8, 30.4, 29.8, 22.6, 35.3], + # "B1": [74.0, 59.9, 63.3, 61.9, 50.0, 41.9, 35.9, 34.4, 37.7, 30.8, 19.3], + # "N0": [65.9, 60.2, 64.5, 67.1, 59.2, 59.2, 44.2, 37.5, 47.1, 34.1, 31.6], + # "H1": [66.5, 75.8, 71.5, 70.8, 69.4, 67.5, 60.1, 52.7, 59.9, 50.9, 38.3], + # "H2": [83.8, 79.4, 80.4, 79.5, 72.8, 70.6, 68.8, 66.1, 68.5, 59.8, 59.6], + # "H3": [77.8, 84.6, 82.0, 81.3, 79.8, 74.0, 67.7, 69.8, 66.5, 57.0, 65.2], + # "H4": [72.1, 83.0, 86.6, 73.6, 77.4, 63.0, 69.6, 67.5, 68.6, 68.6, 56.8], + # "H5": [81.0, 78.5, 76.6, 81.9, 69.5, 75.0, 80.9, 62.9, 66.4, 63.7, 59.6] + # } + index_labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] matrix_df = pd.DataFrame(data, index=index_labels) + # Récupération des labels ordonnés + ordered_labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] + label_to_index = {label: i for i, label in enumerate(ordered_labels)} + # Extraction de la matrice numérique + numeric_matrix = matrix_df.reindex(index=ordered_labels, columns=ordered_labels).values def confirm_trade_entry(self, pair: str, order_type: str, amount: float, rate: float, time_in_force: str, @@ -232,7 +267,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): minutes = 0 if self.pairs[pair]['last_date'] != 0: - minutes = round((current_time - self.pairs[pair]['last_date']).total_seconds() / 60,0) + minutes = round(int((current_time - self.pairs[pair]['last_date']).total_seconds() / 60)) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = dataframe.iloc[-1].squeeze() @@ -354,6 +389,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): if (last_candle['tendency'] in ('H++', 'H+')) and (last_candle['rsi'] < 80): return None + mid_smooth_label = self.get_mid_smooth_label(last_candle['mid_smooth_deriv1_1h']) # ex. 'B2' + sma24_diff_label = self.get_sma24_diff_label(last_candle['sma24_diff_1h']) + + val = self.approx_val_from_bins(row_label=sma24_diff_label, col_label=mid_smooth_label) + if val > 50: + return None + baisse = self.pairs[pair]['max_profit'] - current_profit mx = self.pairs[pair]['max_profit'] / 5 if (baisse > mx) & (current_profit > expected_profit): #last_candle['min_max200'] / 3): @@ -500,7 +542,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe['haclose'] = heikinashi['close'] dataframe['hapercent'] = (dataframe['haclose'] - dataframe['haopen']) / dataframe['haclose'] - dataframe['pct_change'] = dataframe['close'].pct_change(5) dataframe = self.calculateTendency(dataframe) dataframe['min'] = talib.MIN(dataframe['close'], timeperiod=200) @@ -652,6 +693,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): # dataframe['amount'] = amount print(f"amount= {amount}") + dataframe['percent_with_previous_day'] = 100 * (dataframe['close'] - dataframe['close_1d']) / dataframe['close'] + dataframe['futur_percent_1h'] = 100 * (dataframe['close'].shift(-12) - dataframe['close']) / dataframe['close'] dataframe['futur_percent_3h'] = 100 * (dataframe['close'].shift(-36) - dataframe['close']) / dataframe['close'] dataframe['futur_percent_5h'] = 100 * (dataframe['close'].shift(-60) - dataframe['close']) / dataframe['close'] @@ -707,10 +750,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): ( (dataframe['max200_diff'] >= 0.01) & (dataframe['percent12'] < -0.002) - # & (dataframe['pct_change'] < 0) & (dataframe['open'] < dataframe['average_line_288_099']) & (dataframe['open'] < dataframe['average_line_50']) - # & (dataframe['percent'] >= -0.0005) & (dataframe['min12'].shift(2) == dataframe['min12']) & (dataframe['up_count'] > 0) & (dataframe["bb_width"] > 0.01) @@ -840,17 +881,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): return None count_of_buys = trade.nr_of_successful_entries - - # if (days_since_first_buy >= 5 and count_of_buys >= 4 and last_candle['sma5_pct_1d'] < 0): - # # print(f"waiting day increase pair {pair}") - # return None - - # if 'buy' in last_candle: - # condition = (last_candle['buy'] == 1) - # else: - # condition = False - # self.protection_nb_buy_lost.value - current_time_utc = current_time.astimezone(timezone.utc) open_date = trade.open_date.astimezone(timezone.utc) days_since_open = (current_time_utc - open_date).days @@ -880,7 +910,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): limit_buy = 20 if (count_of_buys < limit_buy) \ and (last_candle['enter_long'] == 1) \ - and (pct_max < lim and val > 50): + and (pct_max < lim and val > 50 and last_candle['mid_smooth_deriv1_1d'] > - 1): try: max_amount = self.config.get('stake_amount', 100) * 2.5 @@ -1051,7 +1081,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): return df def get_mid_smooth_label(self, value): - bins = [-2.0622, -0.1618, -0.0717, -0.0353, -0.0135, 0.0, 0.0085, 0.0276, 0.0521, 0.0923, 0.1742, 2.3286] + bins = [-6.6534, -0.1788, -0.0771, -0.0375, -0.0149, 0.0000, 0.0045, 0.0232, 0.0488, 0.0923, 0.1961, 2.7892] + # bins = [-2.0622, -0.1618, -0.0717, -0.0353, -0.0135, 0.0, 0.0085, 0.0276, 0.0521, 0.0923, 0.1742, 2.3286] labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] for i in range(len(bins) - 1): if bins[i] <= value < bins[i + 1]: @@ -1059,17 +1090,17 @@ class Zeus_8_3_2_B_4_2(IStrategy): return labels[-1] # cas limite pour la borne max def get_sma24_diff_label(self, value): - bins = [-0.84253877, -0.13177195, -0.07485074, -0.04293497, -0.02033502, -0.00215711, - 0.01411933, 0.03308264, 0.05661652, 0.09362708, 0.14898214, 0.50579505] + # bins = [-0.84253877, -0.13177195, -0.07485074, -0.04293497, -0.02033502, -0.00215711, + # 0.01411933, 0.03308264, 0.05661652, 0.09362708, 0.14898214, 0.50579505] + bins = [-2.36157394, - 0.14917999, - 0.08269905, - 0.04657017, - 0.02168984, - 0.00339744, + 0.01284104, 0.03306543, 0.05950946, 0.09880605, 0.16573819, 1.05922354] + labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] for i in range(len(bins) - 1): if bins[i] <= value < bins[i + 1]: return labels[i] return labels[-1] - import numpy as np - import pandas as pd - def interpolated_val_from_bins(self, row_pos, col_pos): """ Renvoie une approximation interpolée (bilinéaire) d'une valeur dans la matrice @@ -1140,19 +1171,12 @@ class Zeus_8_3_2_B_4_2(IStrategy): if row_label not in self.matrix_df.index or col_label not in self.matrix_df.columns: return np.nan - # Récupération des labels ordonnés - ordered_labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] - label_to_index = {label: i for i, label in enumerate(ordered_labels)} - # Index correspondant - row_idx = label_to_index.get(row_label) - col_idx = label_to_index.get(col_label) - - # Extraction de la matrice numérique - numeric_matrix = self.matrix_df.reindex(index=ordered_labels, columns=ordered_labels).values + row_idx = self.label_to_index.get(row_label) + col_idx = self.label_to_index.get(col_label) # Approximation directe (aucune interpolation complexe ici, juste une lecture) - return numeric_matrix[row_idx, col_idx] + return self.numeric_matrix[row_idx, col_idx] # @property diff --git a/tools/statistique/carte_thermique2.py b/tools/statistique/carte_thermique2.py new file mode 100644 index 0000000..530234b --- /dev/null +++ b/tools/statistique/carte_thermique2.py @@ -0,0 +1,33 @@ +# Re-importer les bibliothèques après la réinitialisation de l'environnement +import matplotlib.pyplot as plt +import seaborn as sns +import pandas as pd + +# Données de probabilité de hausse +data = [ + [41.2, 45.2, 46.7, 49.4, 74.1, 67.8, 72.6, 77.2, 78.8, 75.5, 75.1], + [41.9, 40.1, 41.6, 47.9, 61.7, 58.3, 66.2, 78.7, 76.6, 79.0, 78.6], + [35.3, 38.6, 37.3, 45.9, 61.7, 67.8, 70.8, 81.0, 78.8, 78.0, 81.0], + [29.5, 31.2, 33.4, 39.8, 58.2, 61.7, 69.1, 75.9, 81.2, 78.5, 72.3], + [26.6, 30.1, 27.3, 34.6, 50.2, 58.0, 70.8, 73.6, 76.7, 73.6, 70.0], + [32.7, 29.5, 28.6, 28.6, 43.5, 56.2, 65.3, 73.0, 71.9, 66.4, 71.4], + [28.8, 27.1, 28.8, 26.2, 38.1, 46.7, 56.3, 65.4, 69.2, 71.2, 67.8], + [30.4, 24.2, 24.6, 28.9, 32.5, 42.2, 51.2, 63.3, 67.8, 63.8, 66.0], + [25.3, 24.7, 24.2, 24.7, 33.9, 44.4, 52.6, 63.8, 66.1, 67.0, 66.2], + [20.2, 21.6, 24.8, 29.7, 32.8, 39.7, 53.9, 56.9, 61.3, 62.6, 64.5], + [14.6, 18.4, 23.2, 28.5, 25.3, 30.3, 48.1, 52.8, 58.1, 59.3, 59.9], +] + +rows = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] +cols = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] + +df = pd.DataFrame(data, index=rows, columns=cols) + +# Affichage du heatmap +plt.figure(figsize=(12, 9)) +sns.heatmap(df, annot=True, fmt=".1f", cmap="coolwarm", cbar_kws={'label': 'Probabilité de hausse (%)'}) +plt.title("Probabilité de hausse pour futur_percent_3h") +plt.xlabel("mid_smooth_deriv1_1h_bin") +plt.ylabel("sma24_diff_1h_bin") +plt.tight_layout() +plt.show()