diff --git a/Empty.json b/Empty.json index 6d39cca..b19c874 100644 --- a/Empty.json +++ b/Empty.json @@ -14,15 +14,16 @@ "trailing_only_offset_is_reached": false }, "max_open_trades": { - "max_open_trades": 20 + "max_open_trades": 1 }, "buy": { - "buy_deriv1_sma12d": -0.06, - "buy_deriv1_sma5d": -0.01, - "buy_deriv1_sma60": -0.003, - "buy_deriv2_sma12d": 0.0, - "buy_deriv2_sma5d": -0.07, - "buy_deriv2_sma60": -0.004 + "buy_deriv1_sma12d": -0.05, + "buy_deriv1_sma5d": -0.03, + "buy_deriv1_sma60": 0.0, + "buy_deriv2_sma12d": 0.0, + "buy_deriv2_sma5d": -0.07, + "buy_deriv2_sma60": -0.003, + "buy_longue": 200 }, "protection": { "drop_from_last_entry": 0.0 @@ -34,5 +35,5 @@ } }, "ft_stratparam_v": 1, - "export_time": "2026-02-25 18:15:42.432169+00:00" + "export_time": "2026-02-26 20:23:41.717021+00:00" } \ No newline at end of file diff --git a/Empty.py b/Empty.py index a1563ab..0235d35 100644 --- a/Empty.py +++ b/Empty.py @@ -36,6 +36,7 @@ CYAN = "\033[36m" RESET = "\033[0m" timeperiods = [3, 5, 12, 24, 36, 48, 60] +long_timeperiods = [80, 100, 120, 140, 160, 180, 200] sma_indicators = list() score_indicators = list() @@ -256,9 +257,6 @@ def condition_generator(dataframe, operator, indicator, crossed_indicator, real_ return condition, dataframe # ######################################################################################################################### - - - # This class is a sample. Feel free to customize it. class Empty(IStrategy): @@ -366,13 +364,15 @@ class Empty(IStrategy): } } - buy_deriv1_sma60 = DecimalParameter(-0.005, 0.005, decimals=3, default=0, space='buy') - buy_deriv1_sma5d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy') - buy_deriv1_sma12d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy') + buy_deriv1_sma60 = DecimalParameter(-0.005, 0.005, decimals=3, default=0, space='buy', optimize=False, load=True) + buy_deriv1_sma5d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy', optimize=False, load=True) + buy_deriv1_sma12d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy', optimize=False, load=True) - buy_deriv2_sma60 = DecimalParameter(-0.005, 0.005, decimals=3, default=0, space='buy') - buy_deriv2_sma5d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy') - buy_deriv2_sma12d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy') + buy_deriv2_sma60 = DecimalParameter(-0.005, 0.005, decimals=3, default=0, space='buy', optimize=False, load=True) + buy_deriv2_sma5d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy', optimize=False, load=True) + buy_deriv2_sma12d = DecimalParameter(-0.07, 0.07, decimals=2, default=0, space='buy', optimize=False, load=True) + + buy_longue = CategoricalParameter(long_timeperiods, default=120, space='buy') # Buy Hyperoptable Parameters/Spaces. # buy_crossed_indicator0 = CategoricalParameter(god_genes_with_timeperiod, default="ADD-20", space='buy') @@ -851,7 +851,8 @@ class Empty(IStrategy): informative[f"sma{timeperiod}"] = informative['mid'].ewm(span=timeperiod, adjust=False).mean() self.calculeDerivees(informative, f"sma{timeperiod}", timeframe=self.timeframe, ema_period=timeperiod) - informative[f"sma200"] = informative['mid'].ewm(span=200, adjust=False).mean() + for timeperiod in long_timeperiods: + informative[f"sma{timeperiod}"] = informative['mid'].ewm(span=timeperiod, adjust=False).mean() informative['rsi'] = talib.RSI(informative['close'], timeperiod=14) self.calculeDerivees(informative, f"rsi", timeframe=self.timeframe, ema_period=14) informative['max_rsi_12'] = talib.MAX(informative['rsi'], timeperiod=12) @@ -874,6 +875,11 @@ class Empty(IStrategy): dataframe['max_rsi_12'] = talib.MAX(dataframe['rsi'], timeperiod=12) dataframe['max_rsi_24'] = talib.MAX(dataframe['rsi'], timeperiod=24) + dataframe["dist_sma200_1d"] = ( + (dataframe["close_1d"] - dataframe["sma200_1d"]) + / dataframe["sma200_1d"] + ) + # récupérer le dernier trade fermé trades = Trade.get_trades_proxy(pair=pair,is_open=False) if trades: @@ -953,7 +959,9 @@ class Empty(IStrategy): # conditions.append(dataframe['percent12'] < 0.01) # conditions.append(dataframe['percent5'] < 0.01) conditions.append(dataframe['max_rsi_24'] < 80) - conditions.append((dataframe['max_rsi_12_1d'] < 65))\ + + dynamic_rsi_threshold = 70 + 15 * np.tanh(dataframe["dist_sma200_1d"] * 5) + conditions.append((dataframe['max_rsi_12_1d'] < dynamic_rsi_threshold)) # | ( # (dataframe['sma5_deriv1'] > 0) & (dataframe['sma12_deriv1'] > 0) & (dataframe['sma24_deriv1'] > 0) & ( # dataframe['sma48_deriv1'] > 0) & (dataframe['sma60_deriv1'] > 0) & (dataframe['sma5_deriv1_1d'] > 0)) @@ -962,7 +970,10 @@ class Empty(IStrategy): conditions.append(dataframe[f"close"] > dataframe['sma60']) conditions.append(((dataframe[f"range_pos"] < 0.05) ) | ((dataframe['sma12_deriv1'] > 0) & (dataframe['sma12_deriv2'] > 0))) - conditions.append(dataframe['close_1d'] > dataframe['sma200_1d']) + conditions.append( + (dataframe['close_1d'] > dataframe[f'sma{self.buy_longue.value}_1d']) + | (dataframe['sma60_inv_1d'] == -1) + ) # print(f"BUY indicators tested \n" # f"{self.buy_indicator0.value} {self.buy_crossed_indicator0.value} {self.buy_operator0.value} {self.buy_real_num0.value} \n" diff --git a/Empty.txt b/Empty.txt index bdb4590..20872b5 100644 --- a/Empty.txt +++ b/Empty.txt @@ -3,97 +3,177 @@ Même si le CAGR bouge légèrement, tout le reste s’améliore fortement. 📊 Comparaison claire -Metric Avant Maintenant -Trades 95 53 -CAGR 21.38% 22.45% -Profit Factor 1.89 2.85 -SQN 1.87 2.38 -Winrate 48% 62% -Max DD 21.97% 7.37% -DD duration 309 jours 28 jours -Calmar 7.08 22.51 +Metric Avant Maintenant +Trades 95 53 +CAGR 21.38% 22.45% +Profit Factor 1.89 2.85 +SQN 1.87 2.38 +Winrate 48% 62% +Max DD 21.97% 7.37% +DD duration 309 jours 28 jours +Calmar 7.08 22.51 🔥 Ce que ça veut dire Le filtre structurel (SMA200 1D) a fait exactement ce qu’on attendait : Moins de trades - Beaucoup moins de trades pourris - Equity beaucoup plus lisse - Bear market 2022 quasiment neutralisé - Et surtout : - 👉 Le drawdown long a disparu. - C’est LE point critique. - 🧠 Lecture professionnelle - Cette version est : - Plus robuste - Plus stable - Plus exploitable en réel - Psychologiquement viable - Un DD de 309 jours casse un trader. Un DD de 28 jours est gérable. 🎯 Ce qui est très intéressant Regarde ça : - Worst trade passe de -4.55% → -4.10% - Profit factor explose à 2.85 - Expectancy 24.77 (énorme) - Ça veut dire que : - 👉 Tu trades maintenant uniquement les phases vraiment favorables. - 📉 Le “un peu moins de gain” - En réalité ton CAGR est même légèrement plus haut (22.45 vs 21.38). - Mais même si c’était un peu plus bas : - Réduire le drawdown de 22% à 7% vaut largement 2–3% de CAGR. - Toujours. -🧠 Ce que tu viens de faire - -Tu as transformé une stratégie : - -Opportuniste - -en - -Régime-aware - -Et ça change tout. +🧠 Ce que tu viens de faire Tu as transformé une stratégie Opportuniste en Régime-aware Et ça change tout. ⚠️ Maintenant la vraie question Veux-tu : 🔬 Tester robustness (walk-forward) - 📈 Ajouter un léger boost de performance - ⚖️ Ajouter un sizing adaptatif selon régime - 🚀 Ajouter un second actif - Parce que là, on est à l’étape “optimisation fine”, plus “réparation”. +============================================================================= +Bon. + +Là on va parler sérieusement 😄 +Parce que tes résultats ne sont pas mauvais du tout. + +📊 Lecture objective de ton backtest +✅ Points très solides +CAGR 35% sur 4 ans → très correct +Max DD 10.6% → excellent +Profit factor 1.86 → bon edge +Calmar 29 → extrêmement bon (drawdown très maîtrisé) +Max underwater 11% → propre +Pas d’explosion du risk + +Franchement, c’est une stratégie saine. + +⚠️ Le vrai problème + +Regarde ces deux chiffres : +Sharpe : 0.21 +Sortino : 1.31 +Sharpe très bas → equity curve irrégulière +Sortino correct → pertes contrôlées + +Ce que ça dit : + +Tu gagnes bien… mais de manière irrégulière. + +🎯 Ce qui saute aux yeux +92 trades en 4 ans +Ça fait : +23 trades par an +C’est extrêmement peu. +Donc : +Quelques gros trades font la perf +Beaucoup de périodes mortes +Equity plate pendant longtemps +Ce n’est pas un problème technique. C’est un problème structurel. +🧠Ce que ton système est en réalité Ce n’est pas un trend following classique. + +C’est Un breakout / impulsion filtrée daily + +Regarde : +Best trade : +48% +Avg winner duration : 6 jours +Certains winners : 85 jours +Tu attrapes des swings longs. +Et tu survis entre deux cycles. + +C’est cohérent. +🚨 Pourquoi tu as l’impression que rien n’améliore ? +Parce que tu es déjà dans un bon équilibre. +Quand une stratégie est : +Stable +Faible DD +PF proche de 2 + +👉 Les gains d’optimisation deviennent marginaux. + +Tu n’es plus dans la phase “je corrige une erreur”. +Tu es dans la phase “je modifie l’ADN”. + +🔍 Ce que je vois comme axe réel d’amélioration + +Pas le stoploss. +Pas le RSI adaptatif. + +Le vrai levier est ici : +Winrate = 48.9% +Tu es pile à l’équilibre. +Si tu passes à 55% avec même RR, +ta courbe devient radicalement plus stable. +🎯 La vraie question + +Tes losers durent : +1d 12h en moyenne. +Tes winners : +6d 12h. +Donc ton edge vient du R:R, pas du winrate. + +💡 Deux directions possibles +OPTION 1 — Rendre le système plus agressif +Plus d’entrées +Plus de trades +Légèrement plus de DD + +Sharpe augmente + +→ Transformer ton système en semi-trend. + +OPTION 2 — Assumer que c’est un cycle catcher + +Et optimiser : +La sortie en fin de cycle +Le trailing dynamique +La protection en marché neutre +🎯 Analyse importante +Market change : +44% +Toi : +247% + +Tu as largement surperformé le marché. + +Donc ton edge est réel. + +💬 Question importante + +Tu veux : + +A) Maximiser le CAGR +B) Maximiser la stabilité (Sharpe > 1) +C) Réduire encore le drawdown +D) Multiplier les trades + +Parce que selon ton objectif, on ne touche pas aux mêmes leviers. + +Et là tu es à un point où chaque modification change la philosophie du système. SUMMARY METRICS ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ @@ -104,51 +184,51 @@ Parce que là, on est à l’étape “optimisation fine”, plus “réparation │ Trading Mode │ Spot │ │ Max open trades │ 1 │ │ │ │ -│ Total/Daily Avg Trades │ 53 / 0.04 │ +│ Total/Daily Avg Trades │ 92 / 0.06 │ │ Starting balance │ 1000 USDT │ -│ Final balance │ 2312.665 USDT │ -│ Absolute profit │ 1312.665 USDT │ -│ Total profit % │ 131.27% │ -│ CAGR % │ 22.45% │ -│ Sortino │ 1.81 │ -│ Sharpe │ 0.22 │ -│ Calmar │ 22.51 │ -│ SQN │ 2.38 │ -│ Profit factor │ 2.85 │ -│ Expectancy (Ratio) │ 24.77 (0.70) │ -│ Avg. daily profit │ 0.869 USDT │ -│ Avg. stake amount │ 1534.128 USDT │ -│ Total trade volume │ 164258.371 USDT │ +│ Final balance │ 3474.507 USDT │ +│ Absolute profit │ 2474.507 USDT │ +│ Total profit % │ 247.45% │ +│ CAGR % │ 35.10% │ +│ Sortino │ 1.31 │ +│ Sharpe │ 0.21 │ +│ Calmar │ 29.34 │ +│ SQN │ 1.76 │ +│ Profit factor │ 1.86 │ +│ Expectancy (Ratio) │ 26.90 (0.44) │ +│ Avg. daily profit │ 1.638 USDT │ +│ Avg. stake amount │ 2413.03 USDT │ +│ Total trade volume │ 447365.827 USDT │ │ │ │ -│ Best Pair │ BTC/USDT 131.27% │ -│ Worst Pair │ BTC/USDT 131.27% │ -│ Best trade │ BTC/USDT 38.19% │ -│ Worst trade │ BTC/USDT -4.10% │ -│ Best day │ 422.364 USDT │ -│ Worst day │ -51.652 USDT │ -│ Days win/draw/lose │ 33 / 901 / 19 │ -│ Min/Max/Avg. Duration Winners │ 1d 03:00 / 28d 16:00 / 5d 13:35 │ -│ Min/Max/Avg. Duration Losers │ 0d 01:00 / 6d 10:00 / 1d 13:21 │ -│ Max Consecutive Wins / Loss │ 9 / 3 │ +│ Best Pair │ BTC/USDT 247.45% │ +│ Worst Pair │ BTC/USDT 247.45% │ +│ Best trade │ BTC/USDT 48.98% │ +│ Worst trade │ BTC/USDT -5.61% │ +│ Best day │ 806.579 USDT │ +│ Worst day │ -137.268 USDT │ +│ Days win/draw/lose │ 44 / 1328 / 47 │ +│ Min/Max/Avg. Duration Winners │ 1d 03:00 / 85d 12:00 / 6d 12:21 │ +│ Min/Max/Avg. Duration Losers │ 0d 02:00 / 5d 12:00 / 1d 12:28 │ +│ Max Consecutive Wins / Loss │ 4 / 4 │ │ Rejected Entry signals │ 0 │ │ Entry/Exit Timeouts │ 0 / 0 │ │ │ │ -│ Min balance │ 1003.126 USDT │ -│ Max balance │ 2361.69 USDT │ -│ Max % of account underwater │ 8.27% │ -│ Absolute drawdown │ 116.751 USDT (7.37%) │ -│ Drawdown duration │ 28 days 14:00:00 │ -│ Profit at drawdown start │ 583.353 USDT │ -│ Profit at drawdown end │ 466.603 USDT │ -│ Drawdown start │ 2024-04-09 07:00:00 │ -│ Drawdown end │ 2024-05-07 21:00:00 │ +│ Min balance │ 981.947 USDT │ +│ Max balance │ 3630.59 USDT │ +│ Max % of account underwater │ 11.64% │ +│ Absolute drawdown │ 359.078 USDT (10.66%) │ +│ Drawdown duration │ 86 days 03:00:00 │ +│ Profit at drawdown start │ 2367.463 USDT │ +│ Profit at drawdown end │ 2008.385 USDT │ +│ Drawdown start │ 2025-01-19 22:00:00 │ +│ Drawdown end │ 2025-04-16 01:00:00 │ │ Market change │ 44.09% │ └───────────────────────────────┴─────────────────────────────────┘ Backtested 2022-01-01 00:00:00 -> 2026-02-20 00:00:00 | Max open trades : 1 - STRATEGY SUMMARY -┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━┓ -┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃ -┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━┩ -│ Empty │ 53 │ 1.76 │ 1312.665 │ 131.27 │ 4 days, 1:16:00 │ 33 0 20 62.3 │ 116.751 USDT 7.37% │ -└──────────┴────────┴──────────────┴─────────────────┴──────────────┴─────────────────┴────────────────────────┴─────────────────────┘ + STRATEGY SUMMARY +┏━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┓ +┃ Strategy ┃ Trades ┃ Avg Profit % ┃ Tot Profit USDT ┃ Tot Profit % ┃ Avg Duration ┃ Win Draw Loss Win% ┃ Drawdown ┃ +┡━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━┩ +│ Empty │ 92 │ 1.62 │ 2474.507 │ 247.45 │ 3 days, 23:07:00 │ 45 0 47 48.9 │ 359.078 USDT 10.66% │ +└──────────┴────────┴──────────────┴─────────────────┴──────────────┴──────────────────┴────────────────────────┴──────────────────────┘