From 340c651a8ac1acc4305eac2e9412bbb967d4d520 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Delacotte?= Date: Thu, 27 Nov 2025 20:17:50 +0100 Subject: [PATCH] Frictrade --- Frictrade.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/Frictrade.py b/Frictrade.py index d0f8a93..5ac5a0b 100644 --- a/Frictrade.py +++ b/Frictrade.py @@ -378,6 +378,10 @@ class Frictrade(IStrategy): dataframe['mid'] = dataframe['open'] + (dataframe['close'] - dataframe['open']) / 2 dataframe['sma5'] = dataframe['mid'].ewm(span=5, adjust=False).mean() #dataframe["mid"].rolling(window=5).mean() dataframe['sma5_deriv1'] = 1000 * (dataframe['sma5'] - dataframe['sma5'].shift(1)) / dataframe['sma5'].shift(1) + + dataframe['sma24'] = dataframe['mid'].ewm(span=24, adjust=False).mean() + dataframe['sma24_deriv1'] = 1000 * (dataframe['sma24'] - dataframe['sma24'].shift(1)) / dataframe['sma24'].shift(1) + dataframe['sma60'] = dataframe['mid'].ewm(span=60, adjust=False).mean() dataframe['sma60_deriv1'] = 1000 * (dataframe['sma60'] - dataframe['sma60'].shift(1)) / dataframe['sma60'].shift(1) @@ -386,7 +390,7 @@ class Frictrade(IStrategy): dataframe["sma5_sqrt"] = ( np.sqrt(np.abs(dataframe["sma5"] - dataframe["sma5"].shift(1))) - + np.sqrt(np.abs(dataframe["sma5"].shift(2) - dataframe["sma5"].shift(1))) + + np.sqrt(np.abs(dataframe["sma5"].shift(3) - dataframe["sma5"].shift(1))) ) dataframe["sma5_inv"] = ( (dataframe["sma5"].shift(2) >= dataframe["sma5"].shift(1)) @@ -405,6 +409,9 @@ class Frictrade(IStrategy): dataframe['max5'] = talib.MAX(dataframe['mid'], timeperiod=5) dataframe['min180'] = talib.MIN(dataframe['mid'], timeperiod=180) dataframe['max180'] = talib.MAX(dataframe['mid'], timeperiod=180) + dataframe['pct180'] = ((dataframe["mid"] - dataframe['min180'] ) / (dataframe['max180'] - dataframe['min180'] )) + + dataframe = self.rsi_trend_probability(dataframe) # ################### INFORMATIVE 1h informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe='1h') @@ -493,8 +500,9 @@ class Frictrade(IStrategy): def populate_buy_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: dataframe.loc[ ( - (dataframe['sma5_inv'] == 1) - # & (dataframe['max_rsi_24'] < 80) + # (dataframe['sma5_inv'] == 1) + ((dataframe['pct180'] < 0.5) | (dataframe['close'] < dataframe['sma60'])) + & (dataframe['hapercent'] > 0) # & ( # (dataframe['percent3'] <= -0.003) # | (dataframe['percent12'] <= -0.003) @@ -653,11 +661,10 @@ class Frictrade(IStrategy): self.printLog(exception) return None - if current_profit > dca_threshold and (increase >= dca_threshold and self.wallets.get_available_stake_amount() > 0) \ - and (last_candle['max_rsi_24'] < 80): + if current_profit > dca_threshold and (increase >= dca_threshold and self.wallets.get_available_stake_amount() > 0): try: self.pairs[pair]['previous_profit'] = profit - stake_amount = min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle)) + stake_amount = max(20, min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle))) if stake_amount > 0: self.pairs[pair]['has_gain'] += 1 @@ -751,13 +758,16 @@ class Frictrade(IStrategy): zone = int(position * 3) # 0 à 2 if zone == 0: - current_trailing_stop_positive = True + current_trailing_stop_positive = self.trailing_stop_positive current_trailing_stop_positive_offset = self.trailing_stop_positive_offset * 2 # if zone == 1: + if last_candle['sma24_deriv1'] > 0: # and last_candle['sma5_deriv1'] > -0.15: + return None # ----- 5) Calcul du trailing stop dynamique ----- # Exemple : offset=0.321 => stop à +24.8% + trailing_stop = max_profit * (1.0 - current_trailing_stop_positive) baisse = 0 if max_profit: @@ -781,12 +791,12 @@ class Frictrade(IStrategy): if current_trailing_only_offset_is_reached: # Max profit pas atteint ET perte < 2 * current_trailing_stop_positive if max_profit < min(2, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']))\ - and (baisse < 0.5 and max_profit > current_trailing_stop_positive_offset): #2 * current_trailing_stop_positive: + and (max_profit > current_trailing_stop_positive_offset): #2 * current_trailing_stop_positive: return None # ne pas activer le trailing encore # Sinon : trailing actif dès le début # ----- 6) Condition de vente ----- - if profit > 0 and profit <= trailing_stop: + if profit > 0 and profit <= trailing_stop and last_candle['mid'] < last_candle['sma5']: return f"stop_{count_of_buys}" return None