From 48ceb7f460fa90d5cf1275374b011c5db12b656d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Delacotte?= Date: Sun, 5 Oct 2025 21:04:35 +0200 Subject: [PATCH] 20250101-20250714 1.61 440.619 --- Zeus_8_3_2_B_4_2.py | 144 +++++++++++++++++++++++++++++--------------- 1 file changed, 97 insertions(+), 47 deletions(-) diff --git a/Zeus_8_3_2_B_4_2.py b/Zeus_8_3_2_B_4_2.py index 4c2d481..307fffb 100644 --- a/Zeus_8_3_2_B_4_2.py +++ b/Zeus_8_3_2_B_4_2.py @@ -90,6 +90,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): "sma20": { "color": "yellow" }, + "sma60": { + "color": "green" + }, "bb_lowerband": { "color": "#da59a6"}, "bb_upperband": { @@ -125,7 +128,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): "color": "blue" } }, - "Rsi_deriv": { + }, + "Rsi_deriv1": { "rsi_deriv1_1h": { "color": "red" }, @@ -186,7 +190,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): 'last_palier_index': -1, 'total_amount': 0, 'has_gain': 0, - 'force_sell': False + 'force_sell': False, + 'force_buy': False } for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC", "BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"] @@ -330,9 +335,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): # # if count < 3: # allow_to_buy = False - - if not self.should_enter_trade(pair, last_candle, current_time): - allow_to_buy = False + force = self.pairs[pair]['force_buy'] + if self.pairs[pair]['force_buy']: + self.pairs[pair]['force_buy'] = False + allow_to_buy = True + else: + if not self.should_enter_trade(pair, last_candle, current_time): + allow_to_buy = False if allow_to_buy: self.trades = list() @@ -375,7 +384,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = dataframe.iloc[-1].squeeze() - allow_to_sell = (last_candle['percent'] < 0) + force = self.pairs[pair]['force_sell'] + allow_to_sell = (last_candle['percent'] < 0) #or force minutes = int(round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0)) @@ -446,11 +456,15 @@ class Zeus_8_3_2_B_4_2(IStrategy): count_of_buys = trade.nr_of_successful_entries - # baisse = self.pairs[pair]['max_profit'] - current_profit - # mx = self.pairs[pair]['max_profit'] / 5 + profit = round(current_profit * trade.stake_amount, 1) + self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], profit) + max_profit = self.pairs[pair]['max_profit'] + baisse = 0 + if profit > 0: + baisse = 100 * abs(max_profit - profit) / max_profit + mx = max_profit / 5 self.pairs[pair]['count_of_buys'] = count_of_buys - self.pairs[pair]['current_profit'] = current_profit - self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], current_profit) + self.pairs[pair]['current_profit'] = profit dispo = round(self.wallets.get_available_stake_amount()) hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0 @@ -466,14 +480,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): pair=pair, rate=last_candle['close'], trade_type='', - profit=round(current_profit * trade.stake_amount, 1), + profit=profit, buys='', stake=0 ) - if last_candle['mid_smooth_1h_deriv1'] > self.sma5_deriv1_1h_stop_sell.value \ - and last_candle['mid_smooth_1h_deriv2'] > self.sma5_deriv2_1h_stop_sell.value: - return None + # if last_candle['mid_smooth_1h_deriv1'] > self.sma5_deriv1_1h_stop_sell.value \ + # and last_candle['mid_smooth_1h_deriv2'] > self.sma5_deriv2_1h_stop_sell.value: + # return None # if (last_candle['mid_smooth_deriv1'] >= 0): # return None @@ -486,9 +500,31 @@ class Zeus_8_3_2_B_4_2(IStrategy): # if (current_profit > expected_profit) and last_candle['can_sell']: # return 'Can_' + pair_name + '_' + str(count_of_buys) - # if 1 <= count_of_buys <= 3: - if last_candle['mid_smooth_1h_deriv1'] < 0 and current_profit > expected_profit: + # if self.pairs[pair]['force_sell']: + # self.pairs[pair]['force_sell'] = False + # return 'Force' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + + # if profit > - 2 and last_candle['rsi_1h'] < 50 \ + # and (last_candle['sma20'] - before_last_candle['sma20'] < 0) \ + # and (last_candle['rsi_deriv1_1h'] < -4 and last_candle['rsi_deriv2_1h'] < -4) : + # self.pairs[pair]['force_sell'] = False + # return 'stoploss_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + + if baisse > 15 and profit > expected_profit: self.pairs[pair]['force_sell'] = False + self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 5) + return 'Baisse_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + # + # # if 1 <= count_of_buys <= 3: + # if last_candle['rsi_1h'] < 50 \ + # and last_candle['mid_smooth_1h_deriv1'] < 0 and profit > expected_profit \ + # and (last_candle['sma20'] - before_last_candle['sma20'] < 0) : + # self.pairs[pair]['force_sell'] = False + # return 'Drv3_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) + + if last_candle['mid_smooth_1h_deriv1'] < 0 and last_candle['rsi_1h'] < 50 and profit > expected_profit: + self.pairs[pair]['force_sell'] = False + self.pairs[pair]['force_buy'] = (self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] > 5) return 'Drv3_' + pair_name + '_' + str(count_of_buys) + '_' + str(self.pairs[pair]['has_gain']) # if 4 <= count_of_buys <= 6: @@ -556,7 +592,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): return if self.columns_logged % 10 == 0: self.printLog( - f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>10} | {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |" + f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>8} | {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |" f"Tdc|{'val':>6}|Distmax|s201d|s5_1d|s5_2d|s51h|s52h|smt1h|smt2h|" ) self.printLineLog() @@ -623,15 +659,15 @@ class Zeus_8_3_2_B_4_2(IStrategy): color_sma20 = GREEN if last_candle['sma20_deriv1_1d'] > 0 else RED color_sma5 = GREEN if last_candle['mid_smooth_5_deriv1_1d'] > 0 else RED color_sma5_2 = GREEN if last_candle['mid_smooth_5_deriv2_1d'] > 0 else RED - color_sma5_1h = GREEN if last_candle['sma5_deriv1_1h'] > 0 else RED - color_sma5_2h = GREEN if last_candle['sma5_deriv2_1h'] > 0 else RED + color_sma5_1h = GREEN if last_candle['sma60_deriv1'] > 0 else RED + color_sma5_2h = GREEN if last_candle['sma60_deriv2'] > 0 else RED color_smooth_1h = GREEN if last_candle['mid_smooth_1h_deriv1'] > 0 else RED color_smooth2_1h = GREEN if last_candle['mid_smooth_1h_deriv2'] > 0 else RED last_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round(self.pairs[pair]['last_max'],3) last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round(self.pairs[pair]['last_min'], 3) - profit = str(round(self.pairs[pair]['current_profit'], 2)) + '/' + str(profit) + profit = str(profit) + '/' + str(round(self.pairs[pair]['max_profit'], 2)) # 🟢 Dérivée 1 > 0 et dérivée 2 > 0: tendance haussière qui s’accélère. # 🟡 Dérivée 1 > 0 et dérivée 2 < 0: tendance haussière qui ralentit → essoufflement potentiel. @@ -649,7 +685,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): f"{round(val, 1) or '-' :>6}|" f"{dist_max:>7}|{color_sma20}{round(last_candle['sma20_deriv1_1d'], 2):>5}{RESET}" f"|{color_sma5}{round(last_candle['mid_smooth_5_deriv1_1d'], 2):>5}{RESET}|{color_sma5_2}{round(last_candle['mid_smooth_5_deriv2_1d'], 2):>5}{RESET}" - f"|{color_sma5_1h}{round(last_candle['sma5_deriv1_1h'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma5_deriv2_1h'], 2):>5}{RESET}" + f"|{color_sma5_1h}{round(last_candle['sma60_deriv1'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma60_deriv2'], 2):>5}{RESET}" f"|{color_smooth_1h}{round(last_candle['mid_smooth_1h_deriv1'], 2):>5}{RESET}|{color_smooth2_1h}{round(last_candle['mid_smooth_1h_deriv2'], 2):>5}{RESET}" # f"|{last_candle['min60_1d']}|{last_candle['max60_1d']}" ) @@ -712,9 +748,11 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe['sma5'] = talib.SMA(dataframe, timeperiod=5) dataframe['sma10'] = talib.SMA(dataframe, timeperiod=10) - self.calculeDerivees(dataframe, 'sma10') + self.calculeDerivees(dataframe, 'sma10', horizon=10) dataframe['sma20'] = talib.SMA(dataframe, timeperiod=20) - self.calculeDerivees(dataframe, 'sma20') + self.calculeDerivees(dataframe, 'sma20', horizon=20) + dataframe['sma60'] = talib.SMA(dataframe, timeperiod=60) + self.calculeDerivees(dataframe, 'sma60', horizon=60) dataframe['sma144'] = talib.SMA(dataframe, timeperiod=144) self.calculeDerivees(dataframe, 'sma144') @@ -728,14 +766,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe["mid_re_smooth_3"] = self.conditional_smoothing(dataframe['mid_smooth_3'].dropna(), threshold=0.0005).dropna() - self.calculeDerivees(dataframe, "mid_re_smooth_3") + self.calculeDerivees(dataframe, "mid_re_smooth_3", horizon=3) dataframe = self.calculateDerivation(dataframe, window=12, suffixe="_12") dataframe = self.calculateDerivation(dataframe, window=24, suffixe="_24", factor_1=1000, factor_2=10) # print(metadata['pair']) dataframe['rsi'] = talib.RSI(dataframe['close'], timeperiod=14) dataframe['max_rsi_12'] = talib.MAX(dataframe['rsi'], timeperiod=12) - self.calculeDerivees(dataframe, 'rsi') + self.calculeDerivees(dataframe, 'rsi', horizon=12) dataframe['max48'] = talib.MAX(dataframe['close'], timeperiod=48) dataframe['min36'] = talib.MIN(dataframe['close'], timeperiod=36) @@ -780,8 +818,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): informative['sma5'] = talib.SMA(informative, timeperiod=5) informative['sma24'] = talib.SMA(informative, timeperiod=24) - self.calculeDerivees(informative, 'sma5') - self.calculeDerivees(informative, 'sma24') + self.calculeDerivees(informative, 'sma5', horizon=5) + self.calculeDerivees(informative, 'sma24', horizon=24) # informative["mid_re_smooth"] = self.conditional_smoothing(informative['mid_smooth'].dropna(), threshold=0.0005).dropna() # self.calculeDerivees(informative, "mid_re_smooth") # self.calculateDownAndUp(informative, limit=0.0012) @@ -823,18 +861,17 @@ class Zeus_8_3_2_B_4_2(IStrategy): informative['max60'] = talib.MAX(informative['close'], timeperiod=period_1d) informative['min12'] = talib.MIN(informative['close'], timeperiod=12) informative['min60'] = talib.MIN(informative['close'], timeperiod=period_1d) - informative['volatility'] = talib.STDDEV(informative['close'], timeperiod=14) / informative['close'] - self.calculeDerivees(informative, 'volatility') informative["percent"] = (informative["close"] - informative["open"]) / informative["open"] - informative['rsi6'] = talib.RSI(informative['close'], timeperiod=6) - # self.calculeDerivees(informative, 'rsi') + informative['rsi'] = talib.RSI(informative['close'], timeperiod=6) + informative['rsi'] = informative['rsi'].rolling(6).mean() + self.calculeDerivees(informative, 'rsi', horizon=6) # informative['sma5'] = talib.SMA(informative, timeperiod=5) informative['sma20'] = talib.SMA(informative, timeperiod=20) - self.calculeDerivees(informative, 'sma5', factor_1=10, factor_2=1) - self.calculeDerivees(informative, 'sma20', factor_1=10, factor_2=1) + self.calculeDerivees(informative, 'sma5', factor_1=10, factor_2=1, horizon=5) + self.calculeDerivees(informative, 'sma20', factor_1=10, factor_2=1, horizon=20) informative = self.add_tendency_column(informative, "", "sma5") informative = self.add_tendency_column(informative, "", "sma20") @@ -861,6 +898,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): # print("##################") # self.calculateStats(informative, 'sma5_deriv1', 'futur_percent_3') + if self.dp.runmode.value in ('backtest'): + informative['futur_percent'] = 100 * (informative['close'].shift(-1) - informative['close']) / informative['close'] + # informative['futur_percent_3d'] = 100 * (informative['close'].shift(-3) - informative['close']) / informative['close'] + # + # self.calculateProbabilite2Index(informative, ['futur_percent_1d'], 'rsi_deriv1', 'rsi') + # # self.calculateProbabilite2Index(dataframe, ['futur_percent_3d'], 'rsi_deriv1', 'sma5') + + # informative['close_smooth'] = self.conditional_smoothing(informative['mid'].dropna(), threshold=0.0015).dropna() # informative['smooth'], informative['deriv1'], informative['deriv2'] = self.smooth_and_derivatives(informative['close_smooth']) # informative['deriv1'] = 100 * informative['deriv1'] / informative['mid'] @@ -937,7 +982,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): # dataframe['deriv2_1h'] = 1000 * dataframe['deriv2_1h'] / dataframe['mid_smooth_1h'] horizon_h = 12 - dataframe['sma5_1h'] = dataframe['sma5_1h'].rolling(window=horizon_h).mean() + # dataframe['sma5_1h'] = dataframe['sma5_1h'].rolling(window=horizon_h).mean() # dataframe['ema_volume'] = dataframe['ema_volume'].rolling(window=horizon_h).mean() # dataframe['sma24_1h'] = dataframe['sma24_1h'].rolling(window=horizon_h).mean() # dataframe['sma24_deriv1_1h'] = dataframe['sma24_deriv1_1h'].rolling(window=horizon_h).mean() @@ -961,6 +1006,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): # =============================== # Lissage des valeurs Journalières horizon_d = 12 * 5 * 24 + # dataframe['rsi_1h'] = dataframe['rsi_1h'].rolling(12).mean() + # dataframe['rsi_deriv1_1h'] = dataframe['rsi_deriv1_1h'].rolling(12).mean() + # dataframe['rsi_deriv2_1h'] = dataframe['rsi_deriv2_1h'].rolling(12).mean() + # dataframe['mid_smooth_1d'] = dataframe['mid_smooth_1d'].rolling(window=horizon_d * 5).mean() # dataframe["mid_smooth_deriv1_1d"] = dataframe["mid_smooth_1d"].rolling(horizon_d).mean().diff() / horizon_d # dataframe["mid_smooth_deriv2_1d"] = horizon_d * dataframe["mid_smooth_deriv1_1d"].rolling(horizon_d).mean().diff() @@ -988,13 +1037,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe['ema_volume'] = 20 * (dataframe['volume'] * dataframe['percent']) / ( abs(dataframe['volume'].shift(1)) + abs(dataframe['volume'].shift(2))) - self.calculeDerivees(dataframe, 'ema_volume', factor_1=10, factor_2=1) + self.calculeDerivees(dataframe, 'ema_volume', factor_1=10, factor_2=1, horizon=14) # if self.dp.runmode.value in ('backtest'): # print("##################") # print("# STAT DAY vs HOUR") # print("##################") - # self.calculateProbabilite2Index(dataframe, futur_cols=['futur_percent_3h'], indic_1='ema_volume', - # indic_2='mid_smooth_1h_deriv1') + # self.calculateProbabilite2Index(dataframe, futur_cols=['futur_percent_1d'], indic_1='sma5_deriv1_1d', + # indic_2='sma5_deriv2_1d') # dataframe['proba_hausse'] = dataframe.apply(lambda row: self.getProbaHausseEmaVolume(row), axis=1) @@ -1018,9 +1067,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): return dataframe - def calculeDerivees(self, dataframe, indic, factor_1=100, factor_2=10): - dataframe[f"{indic}_deriv1"] = factor_1 * dataframe[f"{indic}"].diff() / dataframe[f"{indic}"] - dataframe[f"{indic}_deriv2"] = factor_2 * dataframe[f"{indic}_deriv1"].diff() + def calculeDerivees(self, dataframe, indic, factor_1=100, factor_2=10, horizon=5): + dataframe[f"{indic}_deriv1"] = (factor_1 * dataframe[f"{indic}"].diff() / dataframe[f"{indic}"]).rolling(horizon).mean() + dataframe[f"{indic}_deriv2"] = (factor_2 * dataframe[f"{indic}_deriv1"].diff()).rolling(horizon).mean() def calculateDownAndUp(self, dataframe, limit=0.0001): dataframe['down'] = dataframe['mid_smooth_1h_deriv1'] < limit # dataframe['hapercent'] <= limit @@ -1418,7 +1467,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): try: if self.pairs[pair]['has_gain']: - self.pairs[pair]['force_sell'] = True; + self.pairs[pair]['force_sell'] = True # if 6 <= count_of_buys: # if not ((before_last_candle_24['sma24_deriv1_1h'] > before_last_candle_12['sma24_deriv1_1h']) @@ -2210,7 +2259,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): # if not pair.startswith('BTC'): dispo = round(self.wallets.get_available_stake_amount()) - if self.pairs[pair]['stop'] and last_candle['mid_smooth_5_deriv1_1d'] > -0.9 and last_candle['sma5_deriv1_1h'] > 0: + if self.pairs[pair]['stop'] and last_candle['mid_smooth_5_deriv1_1d'] > -0.9 and last_candle['sma5_deriv1_1d'] > 0 and last_candle['sma5_deriv2_1d'] > 0: self.pairs[pair]['stop'] = False self.log_trade( last_candle=last_candle, @@ -2225,8 +2274,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): stake=0 ) else: - if self.pairs[pair]['stop'] == False and last_candle['sma5_deriv1_1h'] < -0.2: + if self.pairs[pair]['stop'] == False and (last_candle['sma5_deriv1_1d'] < -0.2 or last_candle['sma5_deriv2_1d'] < -3): self.pairs[pair]['stop'] = True + # if self.pairs[pair]['current_profit'] > 0: + # self.pairs[pair]['force_sell'] = True self.log_trade( last_candle=last_candle, date=current_time, @@ -2235,7 +2286,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): pair=pair, rate=last_candle['close'], trade_type='', - profit=0, + profit=self.pairs[pair]['current_profit'], buys=self.pairs[pair]['count_of_buys'], stake=0 ) @@ -2243,7 +2294,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): if self.pairs[pair]['stop']: return False - if last_candle['sma5_deriv1_1h'] < -0.02: return False @@ -2256,8 +2306,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): if last_candle['mid_smooth_1h_deriv1'] < 0.0 and last_candle['mid_smooth_1h_deriv2'] < -0.0 and last_candle['sma5_deriv2_1h'] < 0: return False - if pair.startswith('BTC'): - return True # BTC toujours autorisé + # if pair.startswith('BTC'): + # return True # BTC toujours autorisé #return True