From 978f06299144b31dc65acb09880aa0de52a7b4bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Delacotte?= Date: Tue, 13 Jan 2026 16:29:24 +0100 Subject: [PATCH] optimisation --- FrictradeLearning.json | 2 +- FrictradeLearning.py | 85 ++++++++++++++++++++++++++++-------------- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/FrictradeLearning.json b/FrictradeLearning.json index 1562818..2e1108b 100644 --- a/FrictradeLearning.json +++ b/FrictradeLearning.json @@ -19,7 +19,7 @@ "protection": { "allow_decrease_rate": 0.4, "first_adjust_param": 0.005, - "max_steps": 45 + "max_steps": 30 }, "buy": { "hours_force": 44, diff --git a/FrictradeLearning.py b/FrictradeLearning.py index d363769..f8d0133 100644 --- a/FrictradeLearning.py +++ b/FrictradeLearning.py @@ -93,7 +93,7 @@ class FrictradeLearning(IStrategy): indic_1h_force_buy = CategoricalParameter(indicators, default="sma60_deriv1", space='buy') allow_decrease_rate = DecimalParameter(0.1, 0.8, decimals=1, default=0.4, space='protection', optimize=False, - load=False) + load=True) first_adjust_param = DecimalParameter(0.001, 0.01, decimals=3, default=0.005, space='protection', optimize=False, load=False) max_steps = IntParameter(10, 50, default=40, space='protection', optimize=True, load=True) @@ -114,7 +114,7 @@ class FrictradeLearning(IStrategy): use_custom_stoploss = False trailing_stop = False - trailing_stop_positive = 0.15 + trailing_stop_positive = 0.25 trailing_stop_positive_offset = 1 trailing_only_offset_is_reached = True @@ -192,6 +192,11 @@ class FrictradeLearning(IStrategy): # OFFSET_MIN = self.offset_min.value # OFFSET_MAX = self.offset_min.value + self.offset_max.value + # if self.pairs[pair]['has_gain'] > 0: + # return 0 + + # if self.pairs[pair]['has_gain']: + # stake = (stake - self.pairs[pair]['first_amount']) if last_candle['sma180_deriv1'] < 0.005: return stake / 200 @@ -266,9 +271,9 @@ class FrictradeLearning(IStrategy): buys=1, stake=round(stake_amount, 2) ) - else: - self.printLog( - f"{current_time} BUY triggered for {pair} (cooldown={cooldown} minutes={minutes} percent={round(last_candle['hapercent'], 4)}) but condition blocked") + # else: + # self.printLog( + # f"{current_time} BUY triggered for {pair} (cooldown={cooldown} minutes={minutes} percent={round(last_candle['hapercent'], 4)}) but condition blocked") return allow_to_buy @@ -302,7 +307,7 @@ class FrictradeLearning(IStrategy): val = self.pairs[pair]['first_price'] if self.pairs[pair]['first_price'] > 0 else last_candle['mid'] if self.pairs[pair]['last_ath'] == 0: - ath = max(val, self.get_last_ath_before_candle(last_candle['date'])) + ath = max(val, self.get_last_ath_before_candle(last_candle)) self.pairs[pair]['last_ath'] = ath ath = self.pairs[pair]['last_ath'] @@ -654,6 +659,8 @@ class FrictradeLearning(IStrategy): informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1d') informative['mid'] = informative['open'] + (informative['close'] - informative['open']) / 2 informative['rsi'] = talib.RSI(informative['mid'], timeperiod=5) + informative['min30'] = talib.MIN(informative['mid'], timeperiod=30) + informative['max30'] = talib.MAX(informative['mid'], timeperiod=30) # informative = self.rsi_trend_probability(informative) # informative = self.calculateRegression(informative, 'mid', lookback=15) # self.calculateConfiance(informative) @@ -956,7 +963,7 @@ class FrictradeLearning(IStrategy): # f"pct={(round(val - (ath * (1 - self.allow_decrease_rate.value))) / val, 4)}") # print(dca_thresholds) if self.pairs[pair]['last_ath'] == 0: - ath = max(val, self.get_last_ath_before_candle(last_candle['date'])) + ath = max(val, self.get_last_ath_before_candle(last_candle)) self.pairs[pair]['last_ath'] = ath if len(self.pairs[pair]['dca_thresholds']) == 0: self.calculateStepsDcaThresholds(last_candle, pair) @@ -1070,7 +1077,7 @@ class FrictradeLearning(IStrategy): & (dataframe['sma5_deriv2'] > 0) & (dataframe['rsi'] < 77) & (dataframe['heat_score_1h'] < 0.5) - & (dataframe['sma180_deriv1'] > 0) + # & (dataframe['sma180_deriv1'] > 0) # & (dataframe['open'] < dataframe['max180'] * 0.997) # & (dataframe['min180'].shift(3) == dataframe['min180']) , ['enter_long', 'enter_tag'] @@ -1209,7 +1216,7 @@ class FrictradeLearning(IStrategy): count = self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] return mises[count] if count < len(mises) else self.pairs[pair]['first_amount'] - ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle['date'])) + ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle)) full, mises, steps = self.calculateMises(pair, ath, last_candle['mid']) base_stake = mises[self.pairs[pair]['count_of_buys']] if self.pairs[pair]['count_of_buys'] < len( @@ -1217,7 +1224,7 @@ class FrictradeLearning(IStrategy): return base_stake def calculateMises(self, pair, ath, val): - # ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle['date'])) + # ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle)) self.pairs[pair]['last_ath'] = ath full = self.wallets.get_total_stake_amount() steps = self.calculateNumberOfSteps(val, ath, max_steps=self.max_steps.value) @@ -1313,7 +1320,7 @@ class FrictradeLearning(IStrategy): increase = - decline # FIN ########################## ALGO ATH - force = False #hours > self.hours_force.value and last_candle[self.indic_1h_force_buy.value] > 0 + force = hours > 12 #self.hours_force.value and last_candle[self.indic_1h_force_buy.value] > 0 condition = last_candle['percent'] > 0 \ and ((count_of_buys <= 4 and last_candle['sma24_deriv1'] > 0) or (count_of_buys > 4 and last_candle['sma60_deriv1'] > 0))\ and last_candle['close'] < self.pairs[pair]['first_price'] @@ -1373,7 +1380,7 @@ class FrictradeLearning(IStrategy): increase_dca_threshold = 0.003 if current_profit > increase_dca_threshold \ and (increase >= increase_dca_threshold and self.wallets.get_available_stake_amount() > 0) \ - and last_candle['sma5_deriv1'] > 0 and last_candle['sma5_deriv2'] > 0 and last_candle['max_rsi_12'] < 88: + and last_candle['sma5_deriv1'] > 0 and last_candle['sma5_deriv2'] > 0 and last_candle['max_rsi_12'] < 80: try: print(f"decline={decline} last_fill_price={last_fill_price} current_rate={current_rate}") @@ -1466,9 +1473,11 @@ class FrictradeLearning(IStrategy): current_trailing_only_offset_is_reached = self.trailing_only_offset_is_reached current_trailing_stop_positive_offset = self.trailing_stop_positive_offset - current_trailing_stop_positive_offset = self.dynamic_trailing_offset(pair, self.pairs[pair]['total_amount'], last_candle, price=current_rate, - ath=self.pairs[pair]['last_ath'], - count_of_buys=count_of_buys) + current_trailing_stop_positive_offset = self.dynamic_trailing_offset( + pair, self.pairs[pair]['total_amount'], last_candle, + price=current_rate, + ath=self.pairs[pair]['last_ath'], + count_of_buys=count_of_buys) # max_ = last_candle['max180'] # min_ = last_candle['min180'] @@ -1489,10 +1498,10 @@ class FrictradeLearning(IStrategy): # Exemple : offset=0.321 => stop à +24.8% trailing_stop = max_profit * (1.0 - current_trailing_stop_positive) - # baisse = 0 - # if max_profit: - # baisse = (max_profit - profit) / max_profit - + baisse = 0 + if max_profit: + baisse = (max_profit - profit) / max_profit + # print(f"baisse={baisse}") # if minutes % 1 == 0: # self.log_trade( # last_candle=last_candle, @@ -1506,15 +1515,19 @@ class FrictradeLearning(IStrategy): # buys=count_of_buys, # stake=0 # ) - if profit < 0: + if profit < 0.65: #5 or last_candle['rsi_1d'] < 30: return None if last_candle['max_rsi_24'] > 88 and last_candle['hapercent'] < 0\ and last_candle['sma5_deriv2'] < -0.1: return f"rsi_{count_of_buys}_{self.pairs[pair]['has_gain']}" - if last_candle['sma12_deriv1'] > 0: # and last_candle['rsi'] < 85: - return None + limit = max_profit * (1 - current_trailing_stop_positive) + # if profit < limit and baisse > 0.2: + # return f"lim_{count_of_buys}_{self.pairs[pair]['has_gain']}" + # if last_candle['ml_prob'] > 0.5: + # if last_candle['sma12_deriv1'] > 0: # and last_candle['rsi'] < 85: + # return None # if last_candle['sma24_deriv1'] > 0 : #and minutes < 180 and baisse < 30: # and last_candle['sma5_deriv1'] > -0.15: # if (minutes < 180): @@ -1525,16 +1538,21 @@ class FrictradeLearning(IStrategy): # ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? ----- if current_trailing_only_offset_is_reached and max_profit > current_trailing_stop_positive_offset: # Max profit pas atteint ET perte < 2 * current_trailing_stop_positive - if profit > max_profit * (1 - current_trailing_stop_positive): # 2 * current_trailing_stop_positive: + if profit > limit: # 2 * current_trailing_stop_positive: print( f"{current_time} trailing non atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} " - f"max={round(max_profit, 4)} offset={current_trailing_stop_positive_offset}") + f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}") return None # ne pas activer le trailing encore else: print( f"{current_time} trailing atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} " - f"max={round(max_profit, 4)} offset={current_trailing_stop_positive_offset}") + f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}") else: + # print( + # f"1 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} " + # f"limit={round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)}" + # f" baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}") + return None # Sinon : trailing actif dès le début @@ -1543,9 +1561,16 @@ class FrictradeLearning(IStrategy): self.pairs[pair]['force_buy'] = True print( f"{current_time} Condition de vente trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} " - f"{round(min(2, max_profit * (1 - current_trailing_stop_positive)), 4)} offset={current_trailing_stop_positive_offset}") + f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} " + f"baisse={round(baisse,2)}") return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}" + + print( + f"2 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} " + f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} " + f"baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}") + return None def informative_pairs(self): @@ -1643,9 +1668,9 @@ class FrictradeLearning(IStrategy): return pd.to_datetime(x, utc=True) # suppose self.btc_ath_history exists (liste de dict) - def get_last_ath_before_candle(self, date): - - candle_date = self.to_utc_ts(date) # ou to_utc_ts(last_candle.name) + def get_last_ath_before_candle(self, last_candle): + # return last_candle['max30_1d'] + candle_date = self.to_utc_ts(last_candle['date']) # ou to_utc_ts(last_candle.name) best = None for a in self.btc_ath_history: # getattr(self, "btc_ath_history", []): ath_date = self.to_utc_ts(a["date"]) @@ -2353,6 +2378,8 @@ class FrictradeLearning(IStrategy): and not c.startswith('price_change') and not c.startswith('price_score') and not c.startswith('heat_score') + and not c.startswith('min30_1d') + and not c.startswith('max30_1d') ] # Étape 3 : remplacer inf et NaN par 0 dataframe[usable_cols] = dataframe[usable_cols].replace([np.inf, -np.inf], 0).fillna(0)