Zeus_8_3_2_B_4_2 changement calcul custom_exit

This commit is contained in:
Jérôme Delacotte
2025-05-12 13:43:20 +02:00
parent c719a887d5
commit 6af7053176

View File

@@ -70,6 +70,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
"sma5_1h": { "sma5_1h": {
"color": "white" "color": "white"
}, },
"sma5_1d": {
"color": "blue"
},
"sma20": { "sma20": {
"color": "yellow" "color": "yellow"
}, },
@@ -95,8 +98,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
}, },
"max12_1d": { "max12_1d": {
"color": 'red' "color": 'red'
},
"min50": {
"color": 'green'
},
"max50": {
"color": 'green'
} }
}, },
"subplots": { "subplots": {
"Pct": { "Pct": {
@@ -108,6 +116,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
}, },
"down_pct_1h": { "down_pct_1h": {
"color": "red" "color": "red"
},
"down_pct_1d": {
"color": "red"
} }
}, },
"Rsi": { "Rsi": {
@@ -115,6 +126,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
"color": "pink" "color": "pink"
}, },
"rsi_1h": { "rsi_1h": {
"color": "red"
},
"rsi_1d": {
"color": "blue" "color": "blue"
} }
}, },
@@ -122,7 +136,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
"rsi_diff_1h": { "rsi_diff_1h": {
"color": "red" "color": "red"
}, },
"rsi_diff_2_1h": { "rsi_diff_1d": {
"color": "blue" "color": "blue"
}, },
}, },
@@ -178,7 +192,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
"last_count_of_buys": 0, "last_count_of_buys": 0,
'base_stake_amount': 0, 'base_stake_amount': 0,
'stop_buy': False, '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", for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"] "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') # filled_buys = trade.select_filled_orders('buy')
# count_buys = len(filled_buys) # 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) dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze() 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() # 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 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() self.trades = list()
dispo = round(self.wallets.get_available_stake_amount()) 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) 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( self.log_trade(
last_candle=last_candle, last_candle=last_candle,
date=current_time, date=current_time,
@@ -266,7 +287,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
allow_to_sell = (last_candle['percent'] < 0) 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: if allow_to_sell:
self.trades = list() 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_sell'] = rate
self.pairs[pair]['last_trade'] = trade self.pairs[pair]['last_trade'] = trade
self.pairs[pair]['last_candle'] = last_candle self.pairs[pair]['last_candle'] = last_candle
self.pairs[pair]['max_profit'] = 0
self.trades = list() self.trades = list()
dispo= round(self.wallets.get_available_stake_amount()) 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}") # print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} amount={amount} rate={rate} open_rate={trade.open_rate}")
self.log_trade( self.log_trade(
last_candle=last_candle, last_candle=last_candle,
date=current_time, date=current_time,
action="Sell " + str(minutes), action="Sell " + str(round(minutes,0)),
pair=pair, pair=pair,
trade_type=exit_reason, trade_type=exit_reason,
rate=last_candle['close'], 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]['count_of_buys'] = count_of_buys
self.pairs[pair]['current_profit'] = current_profit 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) 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): if (last_candle['tendency'] in ('H++', 'H+')) and (last_candle['rsi'] < 80):
# and (last_candle['tendency_1h'] in ('H++', 'H+')): # and (last_candle['tendency_1h'] in ('H++', 'H+')):
# and (last_candle['tendency_1d'] in ('H++', 'H+')) : # and (last_candle['tendency_1d'] in ('H++', 'H+')) :
return None 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['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() self.trades = list()
return 'mx_' + str(count_of_buys) return 'mx_' + str(count_of_buys)
if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit): if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit):
self.trades = list() self.trades = list()
return 'pft_' + str(count_of_buys) 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) & ( # if (last_candle['percent3'] < -0.002) & (last_candle['percent12'] < 0) & (
# current_profit > last_candle['min_max200'] / 3): # 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 # Compter les baisses consécutives
self.calculateDownAndUp(dataframe, limit=0.0001) 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' # Normaliser les données de 'close'
# normalized_close = self.min_max_scaling(dataframe['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['hapercent'] = (informative['haclose'] - informative['haopen']) / informative['haclose']
informative = self.calculateTendency(informative, 3) 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['volatility'] = talib.STDDEV(informative['close'], timeperiod=14) / informative['close']
informative['atr'] = (talib.ATR(informative['high'], informative['low'], 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) 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'] = (informative['rsi'].rolling(7).sum() - 350) / 7
informative['rsi_sum_diff'] = informative['rsi_sum'].diff() informative['rsi_sum_diff'] = informative['rsi_sum'].diff()
informative['rsi_diff_2'] = informative['rsi_diff'].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'] = talib.SMA(informative, timeperiod=5)
informative['sma5_diff'] = 100 * informative['sma5'].diff() / informative['sma5'] 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 1d
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d") informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d")
informative = self.calculateTendency(informative, 3) 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['max12'] = talib.MAX(informative['close'], timeperiod=12)
informative['min12'] = talib.MIN(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'] = talib.RSI(informative['close']) #, timeperiod=7)
informative['rsi_diff'] = informative['rsi'].diff() 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 = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True)
dataframe['count_buys'] = 0
dataframe['last_price'] = dataframe['close'] dataframe['last_price'] = dataframe['close']
dataframe['first_price'] = dataframe['close'] dataframe['first_price'] = dataframe['close']
dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2 # dataframe['mid_price'] = (dataframe['last_price'] + dataframe['first_price']) / 2
dataframe['close01'] = dataframe.iloc[-1]['close'] * 1.01 # dataframe['close01'] = dataframe.iloc[-1]['close'] * 1.01
dataframe['amount'] = 0 # dataframe['limit'] = dataframe['close']
dataframe['limit'] = dataframe['close']
count_buys = 0 count_buys = 0
if self.dp: if self.dp:
if self.dp.runmode.value in ('live', 'dry_run'): if self.dp.runmode.value in ('live', 'dry_run'):
@@ -651,13 +684,12 @@ class Zeus_8_3_2_B_4_2(IStrategy):
continue continue
print(trade) print(trade)
filled_buys = trade.select_filled_orders('buy') filled_buys = trade.select_filled_orders('buy')
dataframe['count_buys'] = len(filled_buys)
count = 0 count = 0
amount = 0 amount = 0
for buy in filled_buys: for buy in filled_buys:
if count == 0: if count == 0:
dataframe['first_price'] = buy.price 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, # 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) # status=closed, date=2024-08-26 02:20:11)
@@ -665,10 +697,10 @@ class Zeus_8_3_2_B_4_2(IStrategy):
print(buy) print(buy)
count = count + 1 count = count + 1
amount += buy.price * buy.filled 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 count_buys = count
dataframe['limit'] = dataframe['last_price'] * (1 - self.baisse[count] / 100) # dataframe['limit'] = dataframe['last_price'] * (1 - self.baisse[count] / 100)
dataframe['amount'] = amount # dataframe['amount'] = amount
print(f"amount= {amount}") print(f"amount= {amount}")
# # trades = Trade.get_trades([Trade.is_open is False]).all() # # 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) # dataframe['buy_level'] = dataframe['lowest_4_average'] * (1 - self.levels[count_buys] / 100)
# ---------------------------------------------------------- # ----------------------------------------------------------
# Calcul de la variation entre deux bougies successives # 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 # # Marquer les bougies en baisse
dataframe['is_down'] = dataframe['price_change'] < 0 # dataframe['is_down'] = dataframe['price_change'] < 0
#
# Identifier les blocs consécutifs de baisses # # Identifier les blocs consécutifs de baisses
# dataframe['drop_id'] = (dataframe['is_down'] != dataframe['is_down'].shift(1)).cumsum() # # dataframe['drop_id'] = (dataframe['is_down'] != dataframe['is_down'].shift(1)).cumsum()
dataframe['drop_id'] = np.where(dataframe['is_down'], # dataframe['drop_id'] = np.where(dataframe['is_down'],
(dataframe['is_down'] != dataframe['is_down'].shift(12)).cumsum(), np.nan) # (dataframe['is_down'] != dataframe['is_down'].shift(12)).cumsum(), np.nan)
#
# Identifier uniquement les blocs de baisse # # Identifier uniquement les blocs de baisse
dataframe['drop_id'] = dataframe['drop_id'].where(dataframe['is_down']) # dataframe['drop_id'] = dataframe['drop_id'].where(dataframe['is_down'])
# # Grouper par les chutes détectées # # Grouper par les chutes détectées
# drop_info = dataframe.groupby('drop_id').agg( # drop_info = dataframe.groupby('drop_id').agg(
# start=('close', 'first'), # Prix au début de la chute # 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 # Identifier le prix de début et de fin de chaque chute
drop_stats = dataframe.groupby('drop_id').agg( # drop_stats = dataframe.groupby('drop_id').agg(
start_price=('close', 'first'), # Prix au début de la chute # start_price=('close', 'first'), # Prix au début de la chute
end_price=('close', 'last'), # Prix à la fin de la chute # end_price=('close', 'last'), # Prix à la fin de la chute
) # )
# Calculer l'amplitude en % # Calculer l'amplitude en %
# drop_stats['amplitude_pct'] = ((drop_stats['end_price'] - drop_stats['start_price']) / drop_stats[ # 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'): # if self.dp.runmode.value in ('backtest'):
# self.test_signal_success(dataframe, 0.005) # self.test_signal_success(dataframe, 0.005)
if self.dp.runmode.value in ('backtest'): dataframe['futur_price_1h'] = dataframe['close'].shift(-12)
dataframe.to_feather(f"user_data/data/binance/{metadata['pair'].replace('/', '_')}_df.feather") dataframe['futur_price_2h'] = dataframe['close'].shift(-24)
dataframe['futur_price_3h'] = dataframe['close'].shift(-36)
return dataframe 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['down'].groupby((dataframe['down'] != dataframe['down'].shift()).cumsum()).cumcount() + 1)
dataframe['up_count'] = dataframe['up'].astype(int) * ( dataframe['up_count'] = dataframe['up'].astype(int) * (
dataframe['up'].groupby((dataframe['up'] != dataframe['up'].shift()).cumsum()).cumcount() + 1) 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 # Créer une colonne vide
dataframe['down_pct'] = self.calculateUpDownPct(dataframe, 'down_count') dataframe['down_pct'] = self.calculateUpDownPct(dataframe, 'down_count')
dataframe['up_pct'] = self.calculateUpDownPct(dataframe, 'up_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) 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 return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> 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 return None
pair = trade.pair 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}") print(f"skip pair {pair}")
return None return None
count_of_buys = trade.nr_of_successful_entries count_of_buys = trade.nr_of_successful_entries
@@ -926,7 +960,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# else: # else:
# condition = False # condition = False
# self.protection_nb_buy_lost.value # self.protection_nb_buy_lost.value
limit = last_candle['limit']
current_time_utc = current_time.astimezone(timezone.utc) current_time_utc = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc) open_date = trade.open_date.astimezone(timezone.utc)