From 6af70531768304f2e5f232c3b9eb133558e7ba77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Delacotte?= Date: Mon, 12 May 2025 13:43:20 +0200 Subject: [PATCH] Zeus_8_3_2_B_4_2 changement calcul custom_exit --- Zeus_8_3_2_B_4_2.py | 135 +++++++++++++++++++++++++++----------------- 1 file changed, 84 insertions(+), 51 deletions(-) diff --git a/Zeus_8_3_2_B_4_2.py b/Zeus_8_3_2_B_4_2.py index 6f4143b..62ebc25 100644 --- a/Zeus_8_3_2_B_4_2.py +++ b/Zeus_8_3_2_B_4_2.py @@ -70,6 +70,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): "sma5_1h": { "color": "white" }, + "sma5_1d": { + "color": "blue" + }, "sma20": { "color": "yellow" }, @@ -95,8 +98,13 @@ class Zeus_8_3_2_B_4_2(IStrategy): }, "max12_1d": { "color": 'red' + }, + "min50": { + "color": 'green' + }, + "max50": { + "color": 'green' } - }, "subplots": { "Pct": { @@ -108,6 +116,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): }, "down_pct_1h": { "color": "red" + }, + "down_pct_1d": { + "color": "red" } }, "Rsi": { @@ -115,6 +126,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): "color": "pink" }, "rsi_1h": { + "color": "red" + }, + "rsi_1d": { "color": "blue" } }, @@ -122,7 +136,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): "rsi_diff_1h": { "color": "red" }, - "rsi_diff_2_1h": { + "rsi_diff_1d": { "color": "blue" }, }, @@ -178,7 +192,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): "last_count_of_buys": 0, 'base_stake_amount': 0, 'stop_buy': False, - 'last_date': 0 + 'last_date': 0, + 'stop': False, + 'max_profit': 0 } for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC", "BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"] @@ -218,12 +234,21 @@ class Zeus_8_3_2_B_4_2(IStrategy): # filled_buys = trade.select_filled_orders('buy') # count_buys = len(filled_buys) + minutes = 0 + if self.pairs[pair]['last_date'] != 0: + minutes = round((current_time - self.pairs[pair]['last_date']).total_seconds() / 60,0) + dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe) last_candle = dataframe.iloc[-1].squeeze() + last_candle_2 = dataframe.iloc[-2].squeeze() + last_candle_3 = dataframe.iloc[-3].squeeze() # last_candle_12 = dataframe.iloc[-13].squeeze() + # if (last_candle['close'] < self.pairs[pair]['last_sell'] * 0.99 or minutes > 60 * 5) & (self.pairs[pair]['stop']): + # print(f"restart {pair} last_sell={self.pairs[pair]['last_sell'] * 0.99} minutes={minutes}") + # self.pairs[pair]['stop'] = False # allow_to_buy = True #(not self.stop_all) #& (not self.all_down) - allow_to_buy = True #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry') + allow_to_buy = not self.pairs[pair]['stop'] #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry') self.trades = list() dispo = round(self.wallets.get_available_stake_amount()) @@ -238,10 +263,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): stake_amount = self.adjust_stake_amount(pair, last_candle) - minutes = 0 - if self.pairs[pair]['last_date'] != 0: - minutes = (current_time - self.pairs[pair]['last_date']).total_seconds() / 60.0 - self.log_trade( last_candle=last_candle, date=current_time, @@ -266,7 +287,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): allow_to_sell = (last_candle['percent'] < 0) - minutes = (current_time - trade.date_last_filled_utc).total_seconds() / 60.0 + minutes = round((current_time - trade.date_last_filled_utc).total_seconds() / 60, 0) if allow_to_sell: self.trades = list() @@ -274,13 +295,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): self.pairs[pair]['last_sell'] = rate self.pairs[pair]['last_trade'] = trade self.pairs[pair]['last_candle'] = last_candle + self.pairs[pair]['max_profit'] = 0 self.trades = list() dispo= round(self.wallets.get_available_stake_amount()) # print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} amount={amount} rate={rate} open_rate={trade.open_rate}") self.log_trade( last_candle=last_candle, date=current_time, - action="Sell " + str(minutes), + action="Sell " + str(round(minutes,0)), pair=pair, trade_type=exit_reason, rate=last_candle['close'], @@ -323,25 +345,33 @@ class Zeus_8_3_2_B_4_2(IStrategy): 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) pct_first = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3) + # if (last_candle['close'] > last_candle['max3_1d']) and \ + # (current_profit >= expected_profit or (last_candle['rsi'] >= 80 and current_profit > 0)) & (last_candle['percent'] < 0.0) \ + # and ((last_candle['rsi'] >= 75) or before_last_candle['rsi'] >= 75)\ + # and (count_of_buys <= 2): + # self.trades = list() + # # self.pairs[pair]['stop'] = True + # return 'rsi_' + str(count_of_buys) + if (last_candle['tendency'] in ('H++', 'H+')) and (last_candle['rsi'] < 80): # and (last_candle['tendency_1h'] in ('H++', 'H+')): # and (last_candle['tendency_1d'] in ('H++', 'H+')) : return None + # if (count_of_buys >= 4 and last_candle['sma5_diff_1h'] > 0): + # return None # if (last_candle['rsi_1d'] > 50) & (last_candle['percent12'] < 0.0): - if (last_candle['percent3'] < 0.0) & (current_profit > expected_profit): #last_candle['min_max200'] / 3): + 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): self.trades = list() return 'mx_' + str(count_of_buys) if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit): self.trades = list() return 'pft_' + str(count_of_buys) - if (current_profit >= expected_profit) & (last_candle['percent'] < 0.0) \ - and ((last_candle['rsi'] >= 75) or before_last_candle['rsi'] >= 75)\ - and (count_of_buys < 5): - self.trades = list() - return 'rsi_' + str(count_of_buys) # if (last_candle['percent3'] < -0.002) & (last_candle['percent12'] < 0) & ( # current_profit > last_candle['min_max200'] / 3): @@ -570,7 +600,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): # Compter les baisses consécutives self.calculateDownAndUp(dataframe, limit=0.0001) - dataframe = self.apply_regression_derivatives(dataframe, column='mid', window=24, degree=3) + # dataframe = self.apply_regression_derivatives(dataframe, column='mid', window=24, degree=3) # Normaliser les données de 'close' # normalized_close = self.min_max_scaling(dataframe['close']) @@ -582,7 +612,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): informative['hapercent'] = (informative['haclose'] - informative['haopen']) / informative['haclose'] informative = self.calculateTendency(informative, 3) - informative = self.apply_regression_derivatives(informative, column='mid', window=5, degree=3) + # informative = self.apply_regression_derivatives(informative, column='mid', window=5, degree=3) informative['volatility'] = talib.STDDEV(informative['close'], timeperiod=14) / informative['close'] informative['atr'] = (talib.ATR(informative['high'], informative['low'], informative['close'], timeperiod=14)) / informative['close'] informative['rsi'] = talib.RSI(informative['close']) #, timeperiod=7) @@ -590,6 +620,8 @@ class Zeus_8_3_2_B_4_2(IStrategy): informative['rsi_sum'] = (informative['rsi'].rolling(7).sum() - 350) / 7 informative['rsi_sum_diff'] = informative['rsi_sum'].diff() informative['rsi_diff_2'] = informative['rsi_diff'].diff() + informative['max12'] = talib.MAX(informative['close'], timeperiod=12) + informative['min12'] = talib.MIN(informative['close'], timeperiod=12) informative['sma5'] = talib.SMA(informative, timeperiod=5) informative['sma5_diff'] = 100 * informative['sma5'].diff() / informative['sma5'] @@ -616,10 +648,14 @@ class Zeus_8_3_2_B_4_2(IStrategy): ################### INFORMATIVE 1d informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d") informative = self.calculateTendency(informative, 3) + informative['volatility'] = talib.STDDEV(informative['close'], timeperiod=14) / informative['close'] + informative['atr'] = (talib.ATR(informative['high'], informative['low'], informative['close'], timeperiod=14)) / informative['close'] - informative = self.apply_regression_derivatives(informative, column='mid', window=5, degree=3) + # informative = self.apply_regression_derivatives(informative, column='mid', window=5, degree=3) informative['max12'] = talib.MAX(informative['close'], timeperiod=12) informative['min12'] = talib.MIN(informative['close'], timeperiod=12) + informative['max3'] = talib.MAX(informative['close'], timeperiod=3) + informative['min3'] = talib.MIN(informative['close'], timeperiod=3) informative['rsi'] = talib.RSI(informative['close']) #, timeperiod=7) informative['rsi_diff'] = informative['rsi'].diff() @@ -633,14 +669,11 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True) - dataframe['count_buys'] = 0 - dataframe['last_price'] = dataframe['close'] dataframe['first_price'] = dataframe['close'] - dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2 - dataframe['close01'] = dataframe.iloc[-1]['close'] * 1.01 - dataframe['amount'] = 0 - dataframe['limit'] = dataframe['close'] + # dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2 + # dataframe['close01'] = dataframe.iloc[-1]['close'] * 1.01 + # dataframe['limit'] = dataframe['close'] count_buys = 0 if self.dp: if self.dp.runmode.value in ('live', 'dry_run'): @@ -651,13 +684,12 @@ class Zeus_8_3_2_B_4_2(IStrategy): continue print(trade) filled_buys = trade.select_filled_orders('buy') - dataframe['count_buys'] = len(filled_buys) count = 0 amount = 0 for buy in filled_buys: if count == 0: dataframe['first_price'] = buy.price - dataframe['close01'] = buy.price * 1.01 + # dataframe['close01'] = buy.price * 1.01 # Order(id=2396, trade=1019, order_id=29870026652, side=buy, filled=0.00078, price=63921.01, # status=closed, date=2024-08-26 02:20:11) @@ -665,10 +697,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): print(buy) count = count + 1 amount += buy.price * buy.filled - dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2 + # dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2 count_buys = count - dataframe['limit'] = dataframe['last_price'] * (1 - self.baisse[count] / 100) - dataframe['amount'] = amount + # dataframe['limit'] = dataframe['last_price'] * (1 - self.baisse[count] / 100) + # dataframe['amount'] = amount print(f"amount= {amount}") # # trades = Trade.get_trades([Trade.is_open is False]).all() @@ -696,18 +728,18 @@ class Zeus_8_3_2_B_4_2(IStrategy): # dataframe['buy_level'] = dataframe['lowest_4_average'] * (1 - self.levels[count_buys] / 100) # ---------------------------------------------------------- # Calcul de la variation entre deux bougies successives - dataframe['price_change'] = dataframe['close'].diff() + # dataframe['price_change'] = dataframe['close'].diff() - # Marquer les bougies en baisse - dataframe['is_down'] = dataframe['price_change'] < 0 - - # Identifier les blocs consécutifs de baisses - # dataframe['drop_id'] = (dataframe['is_down'] != dataframe['is_down'].shift(1)).cumsum() - dataframe['drop_id'] = np.where(dataframe['is_down'], - (dataframe['is_down'] != dataframe['is_down'].shift(12)).cumsum(), np.nan) - - # Identifier uniquement les blocs de baisse - dataframe['drop_id'] = dataframe['drop_id'].where(dataframe['is_down']) + # # Marquer les bougies en baisse + # dataframe['is_down'] = dataframe['price_change'] < 0 + # + # # Identifier les blocs consécutifs de baisses + # # dataframe['drop_id'] = (dataframe['is_down'] != dataframe['is_down'].shift(1)).cumsum() + # dataframe['drop_id'] = np.where(dataframe['is_down'], + # (dataframe['is_down'] != dataframe['is_down'].shift(12)).cumsum(), np.nan) + # + # # Identifier uniquement les blocs de baisse + # dataframe['drop_id'] = dataframe['drop_id'].where(dataframe['is_down']) # # Grouper par les chutes détectées # drop_info = dataframe.groupby('drop_id').agg( # start=('close', 'first'), # Prix au début de la chute @@ -724,10 +756,10 @@ class Zeus_8_3_2_B_4_2(IStrategy): # ************** # Identifier le prix de début et de fin de chaque chute - drop_stats = dataframe.groupby('drop_id').agg( - start_price=('close', 'first'), # Prix au début de la chute - end_price=('close', 'last'), # Prix à la fin de la chute - ) + # drop_stats = dataframe.groupby('drop_id').agg( + # start_price=('close', 'first'), # Prix au début de la chute + # end_price=('close', 'last'), # Prix à la fin de la chute + # ) # Calculer l'amplitude en % # drop_stats['amplitude_pct'] = ((drop_stats['end_price'] - drop_stats['start_price']) / drop_stats[ @@ -745,8 +777,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): # if self.dp.runmode.value in ('backtest'): # self.test_signal_success(dataframe, 0.005) - if self.dp.runmode.value in ('backtest'): - dataframe.to_feather(f"user_data/data/binance/{metadata['pair'].replace('/', '_')}_df.feather") + dataframe['futur_price_1h'] = dataframe['close'].shift(-12) + dataframe['futur_price_2h'] = dataframe['close'].shift(-24) + dataframe['futur_price_3h'] = dataframe['close'].shift(-36) return dataframe @@ -757,8 +790,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe['down'].groupby((dataframe['down'] != dataframe['down'].shift()).cumsum()).cumcount() + 1) dataframe['up_count'] = dataframe['up'].astype(int) * ( dataframe['up'].groupby((dataframe['up'] != dataframe['up'].shift()).cumsum()).cumcount() + 1) - dataframe['down_tag'] = (dataframe['down_count'] < -7) - dataframe['up_tag'] = (dataframe['up_count'] > 7) # Créer une colonne vide dataframe['down_pct'] = self.calculateUpDownPct(dataframe, 'down_count') dataframe['up_pct'] = self.calculateUpDownPct(dataframe, 'up_count') @@ -887,6 +918,9 @@ class Zeus_8_3_2_B_4_2(IStrategy): dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.01, np.nan) + if self.dp.runmode.value in ('backtest'): + dataframe.to_feather(f"user_data/data/binance/{metadata['pair'].replace('/', '_')}_df.feather") + return dataframe def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: @@ -916,7 +950,7 @@ class Zeus_8_3_2_B_4_2(IStrategy): return None pair = trade.pair - if pair not in ('BTC/USDT', 'BTC/USDC', 'XRP/USDT', 'XRP/USDC'): + if pair not in ('BTC/USDT', 'BTC/USDC', 'XRP/USDT', 'XRP/USDC', 'ETH/USDT', 'ETH/USDC'): print(f"skip pair {pair}") return None count_of_buys = trade.nr_of_successful_entries @@ -926,7 +960,6 @@ class Zeus_8_3_2_B_4_2(IStrategy): # else: # condition = False # self.protection_nb_buy_lost.value - limit = last_candle['limit'] current_time_utc = current_time.astimezone(timezone.utc) open_date = trade.open_date.astimezone(timezone.utc)