Calcul 20250101-20250714 735.207 106.112$ 26315.818

This commit is contained in:
Jérôme Delacotte
2025-09-21 20:27:37 +02:00
parent 845d2588d5
commit 39bd32370a
2 changed files with 100 additions and 72 deletions

View File

@@ -19,14 +19,13 @@
"buy": { "buy": {
"buy_horizon_predict_1h": 2 "buy_horizon_predict_1h": 2
}, },
"sell": { "sell": {},
"sell_allow_decrease": 0.2
},
"protection": { "protection": {
"protection_fibo": 9, "sma20_deriv1_1d_protection": -0.05,
"protection_percent_buy_lost": 3 "sma24_deriv1_1h_protection": -0.1,
"sma5_deriv1_1d_protection": -0.05
} }
}, },
"ft_stratparam_v": 1, "ft_stratparam_v": 1,
"export_time": "2025-05-24 18:29:22.477903+00:00" "export_time": "2025-09-16 18:26:35.356631+00:00"
} }

View File

@@ -42,6 +42,7 @@ MAGENTA = "\033[35m"
CYAN = "\033[36m" CYAN = "\033[36m"
RESET = "\033[0m" RESET = "\033[0m"
def pprint_df(dframe): def pprint_df(dframe):
print(tabulate(dframe, headers='keys', tablefmt='psql', showindex=False)) print(tabulate(dframe, headers='keys', tablefmt='psql', showindex=False))
@@ -210,9 +211,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
trades = list() trades = list()
max_profit_pairs = {} max_profit_pairs = {}
protection_percent_buy_lost = IntParameter(1, 10, default=5, space='protection') sma20_deriv1_1d_protection = DecimalParameter(-0.1, 0.0, default=-0.05, decimals=2, space='protection',
protection_fibo = IntParameter(1, 10, default=2, space='protection') optimize=True, load=True)
sell_allow_decrease = DecimalParameter(0.005, 0.02, default=0.2, decimals=2, space='sell', optimize=True, load=True) sma5_deriv1_1d_protection = DecimalParameter(-0.1, 0.0, default=-0.05, decimals=2, space='protection',
optimize=True, load=True)
sma24_deriv1_1h_protection = DecimalParameter(-1, 0.0, default=-0.05, decimals=1, space='protection', optimize=True,
load=True)
# sma5_deriv1_1d_protection = DecimalParameter(-0.1, 0.0, default=-0.05, decimals=2, space='protection', optimize=True, load=True)
# Récupération des labels ordonnés # Récupération des labels ordonnés
# labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5'] # labels = ['B5', 'B4', 'B3', 'B2', 'B1', 'N0', 'H1', 'H2', 'H3', 'H4', 'H5']
@@ -267,7 +273,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
} }
sma5_derive1_2_matrice_df = pd.DataFrame(sma5_derive1_2_matrice, index=index_labels) sma5_derive1_2_matrice_df = pd.DataFrame(sma5_derive1_2_matrice, index=index_labels)
# Extraction de la matrice numérique # Extraction de la matrice numérique
sma5_derive1_2_numeric_matrice = sma5_derive1_2_matrice_df.reindex(index=ordered_labels, columns=ordered_labels).values sma5_derive1_2_numeric_matrice = sma5_derive1_2_matrice_df.reindex(index=ordered_labels,
columns=ordered_labels).values
# paliers = {} # paliers = {}
@@ -296,7 +303,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# val = self.getProbaHausse144(last_candle) # val = self.getProbaHausse144(last_candle)
# 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 = not self.pairs[pair]['stop'] # and val > self.buy_val.value #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry') allow_to_buy = not self.pairs[pair][
'stop'] # and val > self.buy_val.value #not last_candle['tendency'] in ('B-', 'B--') # (rate <= float(limit)) | (entry_tag == 'force_entry')
# if allow_to_buy: # if allow_to_buy:
# poly_func, x_future, y_future, count = self.polynomial_forecast( # poly_func, x_future, y_future, count = self.polynomial_forecast(
@@ -428,7 +436,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
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) self.pairs[pair]['max_profit'] = max(self.pairs[pair]['max_profit'], current_profit)
if last_candle['sma20_deriv1_1d'] > 0 and last_candle['sma5_deriv1_1d'] > 0 and last_candle['mid_smooth_1h_deriv1'] > 0\ if last_candle['sma20_deriv1_1d'] > 0 and last_candle['sma5_deriv1_1d'] > 0 and last_candle[
'mid_smooth_1h_deriv1'] > 0 \
and last_candle['mid_smooth_1h_deriv2'] > 0: and last_candle['mid_smooth_1h_deriv2'] > 0:
return None return None
@@ -470,7 +479,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch']) self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
def getShortName(self, pair): def getShortName(self, pair):
return pair.replace("/USDT", '').replace("/USDC", '') return pair.replace("/USDT", '').replace("/USDC", '')
@@ -511,7 +519,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
def log_trade(self, action, pair, date, trade_type=None, rate=None, dispo=None, profit=None, buys=None, stake=None, def log_trade(self, action, pair, date, trade_type=None, rate=None, dispo=None, profit=None, buys=None, stake=None,
last_candle=None): last_candle=None):
# Afficher les colonnes une seule fois # Afficher les colonnes une seule fois
if self.config.get('runmode') == 'hyperopt': if self.config.get('runmode') == 'hyperopt' or self.dp.runmode.value in ('hyperopt'):
return return
if self.columns_logged % 10 == 0: if self.columns_logged % 10 == 0:
self.printLog( self.printLog(
@@ -521,7 +529,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
self.printLineLog() self.printLineLog()
df = pd.DataFrame.from_dict(self.pairs, orient='index') df = pd.DataFrame.from_dict(self.pairs, orient='index')
colonnes_a_exclure = ['last_candle', 'last_trade', 'last_palier_index', 'stop', colonnes_a_exclure = ['last_candle', 'last_trade', 'last_palier_index', 'stop',
'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys', 'base_stake_amount', 'stop_buy'] 'trade_info', 'last_date', 'expected_profit', 'last_count_of_buys',
'base_stake_amount', 'stop_buy']
df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure) df_filtered = df[df['count_of_buys'] > 0].drop(columns=colonnes_a_exclure)
# df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit'] # df_filtered = df_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
@@ -587,10 +596,12 @@ class Zeus_8_3_2_B_4_2(IStrategy):
color_smooth_1h = GREEN if last_candle['mid_smooth_1h_deriv1'] > 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 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_max = int(self.pairs[pair]['last_max']) if self.pairs[pair]['last_max'] > 1 else round(
last_min = int(self.pairs[pair]['last_min']) if self.pairs[pair]['last_min'] > 1 else round(self.pairs[pair]['last_min'], 3) 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(round(self.pairs[pair]['current_profit'], 2)) + '/' + str(profit)
self.printLog( self.printLog(
f"| {date:<16} |{action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} |{rate or '-':>9}| {dispo or '-':>6} " f"| {date:<16} |{action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} |{rate or '-':>9}| {dispo or '-':>6} "
@@ -600,10 +611,10 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# f"|{round(last_candle['mid_smooth_24_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_1h_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv1_1d'],3) or '-' :>6}|" # f"|{round(last_candle['mid_smooth_24_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_1h_deriv1'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv1_1d'],3) or '-' :>6}|"
# f"{round(last_candle['mid_smooth_24_deriv2'],3) or '-' :>6}|{round(last_candle['mid_smooth_1h_deriv2'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv2_1d'],3) or '-':>6}|" # f"{round(last_candle['mid_smooth_24_deriv2'],3) or '-' :>6}|{round(last_candle['mid_smooth_1h_deriv2'],3) or '-':>6}|{round(last_candle['mid_smooth_deriv2_1d'],3) or '-':>6}|"
f"{round(val, 1) or '-' :>6}|" f"{round(val, 1) or '-' :>6}|"
f"{dist_max:>7}|{color_sma20}{round(last_candle['sma20_deriv1_1d'],2):>5}{RESET}" f"{dist_max:>7}|{color_sma20}{round(last_candle['sma20_deriv1_1d'], 2):>5}{RESET}"
f"|{color_sma5}{round(last_candle['sma5_deriv1_1d'],2):>5}{RESET}|{color_sma5_2}{round(last_candle['sma5_deriv2_1d'],2):>5}{RESET}" f"|{color_sma5}{round(last_candle['sma5_deriv1_1d'], 2):>5}{RESET}|{color_sma5_2}{round(last_candle['sma5_deriv2_1d'], 2):>5}{RESET}"
f"|{color_sma5_1h}{round(last_candle['sma24_deriv1_1h'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma24_deriv2_1h'], 2):>5}{RESET}" f"|{color_sma5_1h}{round(last_candle['sma24_deriv1_1h'], 2):>5}{RESET}|{color_sma5_2h}{round(last_candle['sma24_deriv2_1h'], 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"|{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']}" # f"|{last_candle['min60_1d']}|{last_candle['max60_1d']}"
) )
@@ -827,8 +838,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# =============================== # ===============================
# lissage des valeurs horaires # lissage des valeurs horaires
dataframe['mid_smooth_1h'] = dataframe['mid'].rolling(window=6).mean() dataframe['mid_smooth_1h'] = dataframe['mid'].rolling(window=6).mean()
dataframe["mid_smooth_1h_deriv1"] = 100 * dataframe["mid_smooth_1h"].diff().rolling(window=6).mean() / dataframe['mid_smooth_1h'] dataframe["mid_smooth_1h_deriv1"] = 100 * dataframe["mid_smooth_1h"].diff().rolling(window=6).mean() / \
dataframe["mid_smooth_1h_deriv2"] = 10 * dataframe["mid_smooth_1h_deriv1"].diff().rolling(window=6).mean() dataframe['mid_smooth_1h']
dataframe["mid_smooth_1h_deriv2"] = 100 * dataframe["mid_smooth_1h_deriv1"].diff().rolling(window=6).mean()
dataframe['mid_smooth_5h'] = talib.EMA(dataframe, timeperiod=60) # dataframe['mid'].rolling(window=60).mean()
dataframe["mid_smooth_5h_deriv1"] = 100 * dataframe["mid_smooth_5h"].diff().rolling(window=60).mean() / \
dataframe['mid_smooth_5h']
dataframe["mid_smooth_5h_deriv2"] = 100 * dataframe["mid_smooth_5h_deriv1"].diff().rolling(window=60).mean()
# Compter les baisses / hausses consécutives # Compter les baisses / hausses consécutives
self.calculateDownAndUp(dataframe, limit=0.0001) self.calculateDownAndUp(dataframe, limit=0.0001)
@@ -908,14 +925,18 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# indic_1 = 'mid_smooth_1h_deriv1' # indic_1 = 'mid_smooth_1h_deriv1'
# indic_2 = 'mid_smooth_1h_deriv2' # indic_2 = 'mid_smooth_1h_deriv2'
# self.calculateProbabilite2Index(dataframe, futur_cols, indic_1, indic_2) # self.calculateProbabilite2Index(dataframe, futur_cols, indic_1, indic_2)
dataframe['can_sell'] = np.where((dataframe['mid_smooth_3'].shift(1) > dataframe['mid_smooth_3']), dataframe['close'], np.nan) dataframe['can_sell'] = np.where((dataframe['mid_smooth_3'].shift(1) > dataframe['mid_smooth_3']),
dataframe['close'], np.nan)
dataframe['can_buy'] = np.where((dataframe['mid_smooth_3'].shift(1) < dataframe['mid_smooth_3']), dataframe['close'], np.nan) dataframe['can_buy'] = np.where((dataframe['mid_smooth_3'].shift(1) < dataframe['mid_smooth_3']),
dataframe['close'], np.nan)
dataframe['perte_02'] = np.where((dataframe['percent3'] * 100 < -0.2), dataframe['close'], np.nan) dataframe['perte_02'] = np.where((dataframe['percent3'] * 100 < -0.2), dataframe['close'], np.nan)
dataframe['mid_smooth_1h_deriv2_inv'] = np.where((dataframe['mid_smooth_1h_deriv2'].shift(2) >= dataframe['mid_smooth_1h_deriv2'].shift(1)) dataframe['mid_smooth_1h_deriv2_inv'] = np.where(
& (dataframe['mid_smooth_1h_deriv2'].shift(1) <= dataframe['mid_smooth_1h_deriv2']), dataframe['close'], np.nan) (dataframe['mid_smooth_1h_deriv2'].shift(2) >= dataframe['mid_smooth_1h_deriv2'].shift(1))
& (dataframe['mid_smooth_1h_deriv2'].shift(1) <= dataframe['mid_smooth_1h_deriv2']), dataframe['close'],
np.nan)
return dataframe return dataframe
@@ -979,7 +1000,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# évènement "inversion vers le bas" (pente passe de >0 à <=0) sur chaque bougie # évènement "inversion vers le bas" (pente passe de >0 à <=0) sur chaque bougie
cross_down = (dataframe['bb_ub_slope'].shift(1) > 0) & (dataframe['bb_ub_slope'] <= 0) cross_down = (dataframe['bb_ub_slope'].shift(1) > 0) & (dataframe['bb_ub_slope'] <= 0)
dataframe['bb_cross_down'] = 10000 * cross_down * dataframe['bb_width'] \ dataframe['bb_cross_down'] = 10000 * cross_down * dataframe['bb_width'] \
* (dataframe['bb_lowerband'] - dataframe['bb_lowerband'].shift(1)) / dataframe['bb_lowerband'] * (dataframe['bb_lowerband'] - dataframe['bb_lowerband'].shift(1)) / dataframe[
'bb_lowerband']
# vrai si AU MOINS une inversion a eu lieu dans les 5 bougies *précédentes* (on exclut l'actuelle) # vrai si AU MOINS une inversion a eu lieu dans les 5 bougies *précédentes* (on exclut l'actuelle)
inversion_last5 = cross_down.shift(1).rolling(5, min_periods=1).max().astype(bool) inversion_last5 = cross_down.shift(1).rolling(5, min_periods=1).max().astype(bool)
@@ -1098,13 +1120,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
df[f"{indic_2}_bin"], bins_1d = pd.qcut(df[f"{indic_2}"], q=n, labels=self.labels, retbins=True, df[f"{indic_2}_bin"], bins_1d = pd.qcut(df[f"{indic_2}"], q=n, labels=self.labels, retbins=True,
duplicates='drop') duplicates='drop')
# Affichage formaté pour code Python # Affichage formaté pour code Python
print(f"Bornes des quantiles pour {indic_1} : [{', '.join([f'{b:.4f}' for b in bins_1h])}]") # print(f"Bornes des quantiles pour {indic_1} : [{', '.join([f'{b:.4f}' for b in bins_1h])}]")
print(f"Bornes des quantiles pour {indic_2} : [{', '.join([f'{b:.4f}' for b in bins_1d])}]") # print(f"Bornes des quantiles pour {indic_2} : [{', '.join([f'{b:.4f}' for b in bins_1d])}]")
# Agrégation # Agrégation
grouped = df.groupby([f"{indic_2}_bin", f"{indic_1}_bin"], observed=True)[futur_cols].agg(['mean', 'count']) grouped = df.groupby([f"{indic_2}_bin", f"{indic_1}_bin"], observed=True)[futur_cols].agg(['mean', 'count'])
# Affichage # Affichage
with pd.option_context('display.max_rows', None, 'display.max_columns', None): with pd.option_context('display.max_rows', None, 'display.max_columns', None):
print(grouped.round(4)) print(grouped.round(4))
# Ajout des probabilités de hausse # Ajout des probabilités de hausse
for col in futur_cols: for col in futur_cols:
df[f"{col}_is_up"] = df[col] > 0 df[f"{col}_is_up"] = df[col] > 0
@@ -1139,7 +1162,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
max_stake: float, **kwargs): max_stake: float, **kwargs):
# ne rien faire si ordre deja en cours # ne rien faire si ordre deja en cours
if trade.has_open_orders: if trade.has_open_orders:
print("skip open orders") # print("skip open orders")
return None return None
if (self.wallets.get_available_stake_amount() < 50): # or trade.stake_amount >= max_stake: if (self.wallets.get_available_stake_amount() < 50): # or trade.stake_amount >= max_stake:
return 0 return 0
@@ -1165,7 +1188,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
pct_first = 0 pct_first = 0
total_counts = sum(pair_data['count_of_buys'] for pair_data in self.pairs.values() if not pair in ('BTC/USDT', 'BTC/USDC')) total_counts = sum(
pair_data['count_of_buys'] for pair_data in self.pairs.values() if not pair in ('BTC/USDT', 'BTC/USDC'))
if self.pairs[pair]['first_buy']: if self.pairs[pair]['first_buy']:
pct_first = self.getPctFirstBuy(pair, last_candle) pct_first = self.getPctFirstBuy(pair, last_candle)
@@ -1181,17 +1205,17 @@ class Zeus_8_3_2_B_4_2(IStrategy):
if pair in ('BTC/USDT', 'BTC/USDC') or count_of_buys <= 2: if pair in ('BTC/USDT', 'BTC/USDC') or count_of_buys <= 2:
lim = - pct - (count_of_buys * 0.001) lim = - pct - (count_of_buys * 0.001)
#lim = self.getLimitBuy(pair, last_candle, pct) # lim = self.getLimitBuy(pair, last_candle, pct)
# lim = - (0.012 * (1 + round(count_of_buys / 5)) + 0.001 * (count_of_buys - 1)) # lim = - (0.012 * (1 + round(count_of_buys / 5)) + 0.001 * (count_of_buys - 1))
# lim = - (0.012 + 0.001 * (count_of_buys - 1) + (0.002 * count_of_buys if count_of_buys > 10 else 0.001 * count_of_buys if count_of_buys > 5 else 0)) # lim = - (0.012 + 0.001 * (count_of_buys - 1) + (0.002 * count_of_buys if count_of_buys > 10 else 0.001 * count_of_buys if count_of_buys > 5 else 0))
else: else:
pct = 0.05 pct = 0.05
lim = - pct - (count_of_buys * 0.001) lim = - pct - (count_of_buys * 0.001)
#lim = self.getLimitBuy(pair, last_candle, pct) # lim = self.getLimitBuy(pair, last_candle, pct)
if (len(dataframe) < 1): if (len(dataframe) < 1):
print("skip dataframe") # print("skip dataframe")
return None return None
if not self.should_enter_trade(pair, last_candle, current_time): if not self.should_enter_trade(pair, last_candle, current_time):
@@ -1305,15 +1329,15 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# > - 0.03 ==>Avg. stake amount 253.535 USDT │ Total trade volume 145312.936 USDT 284 │ 1.19 │ 1014.898 │ 50.74| 1 day, 17:54:00 │ 283 0 1 99.6 │ 0.684 USDT 0.02% │ # > - 0.03 ==>Avg. stake amount 253.535 USDT │ Total trade volume 145312.936 USDT 284 │ 1.19 │ 1014.898 │ 50.74| 1 day, 17:54:00 │ 283 0 1 99.6 │ 0.684 USDT 0.02% │
# > - 0.015 ==>Avg. stake amount 249.107 USDT │ Total trade volume 138186.861 USDT 275 │ 1.20 │ 901.976 │ 45.1 │ 1 day, 19:17:00 │ 274 0 1 99.6 │ 0.684 USDT 0.02% # > - 0.015 ==>Avg. stake amount 249.107 USDT │ Total trade volume 138186.861 USDT 275 │ 1.20 │ 901.976 │ 45.1 │ 1 day, 19:17:00 │ 274 0 1 99.6 │ 0.684 USDT 0.02%
condition = (last_candle['sma5_deriv1_1h'] > 0 or count_of_buys <= 5) #and \ condition = (last_candle['sma5_deriv1_1h'] > 0 or count_of_buys <= 5) # and \
#(last_candle['mid_smooth_1h_deriv1'] > 0 and last_candle['mid_smooth_1h_deriv1']) # (last_candle['mid_smooth_1h_deriv1'] > 0 and last_candle['mid_smooth_1h_deriv1'])
# last_candle['mid_smooth_1h_deriv1'] > - 0.05 #(last_candle['mid_smooth_3_deriv1'] > self.buy_mid_smooth_3_deriv1.value) and (last_candle['mid_smooth_24_deriv1'] > self.buy_mid_smooth_24_deriv1.value) # last_candle['mid_smooth_1h_deriv1'] > - 0.05 #(last_candle['mid_smooth_3_deriv1'] > self.buy_mid_smooth_3_deriv1.value) and (last_candle['mid_smooth_24_deriv1'] > self.buy_mid_smooth_24_deriv1.value)
# (last_candle['enter_long'] == 1 & (count_of_buys < 3)) \ # (last_candle['enter_long'] == 1 & (count_of_buys < 3)) \
# or ((before_last_candle['mid_re_smooth_3_deriv1'] <= 0) & (last_candle['mid_re_smooth_3_deriv1'] >= 0) & (3 <= count_of_buys < 6)) \ # or ((before_last_candle['mid_re_smooth_3_deriv1'] <= 0) & (last_candle['mid_re_smooth_3_deriv1'] >= 0) & (3 <= count_of_buys < 6)) \
# or ((before_last_candle['mid_smooth_1h_deriv1'] <= 0) & (last_candle['mid_smooth_1h_deriv1'] >= 0) & (6 <= count_of_buys)) # or ((before_last_candle['mid_smooth_1h_deriv1'] <= 0) & (last_candle['mid_smooth_1h_deriv1'] >= 0) & (6 <= count_of_buys))
limit_buy = 40 limit_buy = 40
if (count_of_buys < limit_buy) and condition and (pct_max < lim) : if (count_of_buys < limit_buy) and condition and (pct_max < lim):
try: try:
# if 6 <= count_of_buys: # if 6 <= count_of_buys:
# if not ((before_last_candle_24['sma24_deriv1_1h'] > before_last_candle_12['sma24_deriv1_1h']) # if not ((before_last_candle_24['sma24_deriv1_1h'] > before_last_candle_12['sma24_deriv1_1h'])
@@ -1367,7 +1391,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
return stake_amount return stake_amount
except Exception as exception: except Exception as exception:
print(exception) # print(exception)
return None return None
# if (count_of_buys >= 6): # if (count_of_buys >= 6):
# self.log_trade( # self.log_trade(
@@ -1400,7 +1424,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
dispo=dispo, dispo=dispo,
pair=trade.pair, pair=trade.pair,
rate=current_rate, rate=current_rate,
trade_type=str(round(pct_max,4)), trade_type=str(round(pct_max, 4)),
profit=round(current_profit, 4), # round(current_profit * trade.stake_amount, 2), profit=round(current_profit, 4), # round(current_profit * trade.stake_amount, 2),
buys=trade.nr_of_successful_entries + 1, buys=trade.nr_of_successful_entries + 1,
stake=round(stake_amount, 2) stake=round(stake_amount, 2)
@@ -1410,7 +1434,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
self.pairs[trade.pair]['last_candle'] = last_candle self.pairs[trade.pair]['last_candle'] = last_candle
return stake_amount return stake_amount
except Exception as exception: except Exception as exception:
print(exception) # print(exception)
return None return None
return None return None
@@ -1429,7 +1453,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
return 1 return 1
if last_candle['close'] < last_candle['min60_1d']: if last_candle['close'] < last_candle['min60_1d']:
return 0 return 0
return round((last_candle['close'] - last_candle['min60_1d']) / (last_candle['max60_1d'] - last_candle['min60_1d']), 4) return round(
(last_candle['close'] - last_candle['min60_1d']) / (last_candle['max60_1d'] - last_candle['min60_1d']), 4)
def getLimitBuy(self, pair, last_candle, first_pct): def getLimitBuy(self, pair, last_candle, first_pct):
count_of_buys = self.pairs[pair]['count_of_buys'] count_of_buys = self.pairs[pair]['count_of_buys']
@@ -1443,7 +1468,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
return lim return lim
# def getProbaHausseEmaVolume(self, last_candle): # def getProbaHausseEmaVolume(self, last_candle):
# value_1 = self.getValuesFromTable(self.ema_volume, last_candle['ema_volume']) # value_1 = self.getValuesFromTable(self.ema_volume, last_candle['ema_volume'])
# value_2 = self.getValuesFromTable(self.mid_smooth_1h_deriv1, last_candle['mid_smooth_1h_deriv1']) # value_2 = self.getValuesFromTable(self.mid_smooth_1h_deriv1, last_candle['mid_smooth_1h_deriv1'])
@@ -1475,7 +1499,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
base_stake_amount = self.config.get('stake_amount') # Montant de base configuré base_stake_amount = self.config.get('stake_amount') # Montant de base configuré
# pct60 = round(100 * self.getPctClose60D(pair, last_candle), 2) # pct60 = round(100 * self.getPctClose60D(pair, last_candle), 2)
if True: #not pair in ('BTC/USDT', 'BTC/USDC'): if True: # not pair in ('BTC/USDT', 'BTC/USDC'):
# factors = [1, 1.2, 1.3, 1.4] # factors = [1, 1.2, 1.3, 1.4]
if self.pairs[pair]['count_of_buys'] == 0: if self.pairs[pair]['count_of_buys'] == 0:
pctClose60 = self.getPctClose60D(pair, last_candle) pctClose60 = self.getPctClose60D(pair, last_candle)
@@ -1483,7 +1507,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
adjusted_stake_amount = max(base_stake_amount / 5, base_stake_amount * (1 - pctClose60)) adjusted_stake_amount = max(base_stake_amount / 5, base_stake_amount * (1 - pctClose60))
else: else:
adjusted_stake_amount = self.pairs[pair]['first_amount'] adjusted_stake_amount = self.pairs[pair]['first_amount']
else : else:
first_price = self.pairs[pair]['first_buy'] first_price = self.pairs[pair]['first_buy']
if (first_price == 0): if (first_price == 0):
first_price = last_candle['close'] first_price = last_candle['close']
@@ -1563,7 +1587,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# if last_candle['close'] < max_60: # if last_candle['close'] < max_60:
# pct_to_max = 0.25 * (max_60 - last_candle['close']) / max_60 # pct_to_max = 0.25 * (max_60 - last_candle['close']) / max_60
# pct_to_max = pct_to_max * (2 - pctClose60) # pct_to_max = pct_to_max * (2 - pctClose60)
expected_profit = max(0.004, pct_to_max) # 0.004 + 0.002 * self.pairs[pair]['count_of_buys'] #min(0.01, first_max) expected_profit = max(0.004,
pct_to_max) # 0.004 + 0.002 * self.pairs[pair]['count_of_buys'] #min(0.01, first_max)
# print( # print(
# f"Expected profit price={current_price:.4f} min_max={min_max:.4f} min_14={min_14_days:.4f} max_14={max_14_days:.4f} percent={percent:.4f} expected_profit={expected_profit:.4f}") # f"Expected profit price={current_price:.4f} min_max={min_max:.4f} min_14={min_14_days:.4f} max_14={max_14_days:.4f} percent={percent:.4f} expected_profit={expected_profit:.4f}")
@@ -2074,16 +2099,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
) )
# Résultat # Résultat
print("Moyenne des valeurs par double-tranche :") # print("Moyenne des valeurs par double-tranche :")
print(pivot_mean.round(2)) # print(pivot_mean.round(2))
def should_enter_trade(self, pair: str, last_candle, current_time) -> bool: def should_enter_trade(self, pair: str, last_candle, current_time) -> bool:
limit = 3 limit = 3
if pair.startswith('BTC'):
return True # BTC toujours autorisé
# Filtrer les paires non-BTC # Filtrer les paires non-BTC
non_btc_pairs = [p for p in self.pairs if not p.startswith('BTC')] non_btc_pairs = [p for p in self.pairs if not p.startswith('BTC')]
@@ -2103,7 +2125,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
max_pair = p max_pair = p
total_non_btc += self.pairs[p]['count_of_buys'] total_non_btc += self.pairs[p]['count_of_buys']
pct_max = self.getPctFirstBuy(pair, last_candle) #self.getPctLastBuy(pair, last_candle) pct_max = self.getPctFirstBuy(pair, last_candle) # self.getPctLastBuy(pair, last_candle)
val = self.getProbaHausseSma5d(last_candle) val = self.getProbaHausseSma5d(last_candle)
if val < 15: if val < 15:
@@ -2114,18 +2136,25 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# char="." # char="."
# print(f"should_enter_trade canceled all pairs decreased {'':{char}>{self.should_enter_trade_count}}") # print(f"should_enter_trade canceled all pairs decreased {'':{char}>{self.should_enter_trade_count}}")
# return False # return False
# if (last_candle['mid_smooth_1h_deriv1'] < -0.0 and last_candle['sma24_deriv1_1h'] < -0.0):
# return False
if self.pairs[pair]['count_of_buys'] >= 3: if self.pairs[pair]['count_of_buys'] >= 3:
if (last_candle['sma20_deriv1_1d'] < -0.05 and last_candle['sma5_deriv1_1d'] < -0.05)\ if (last_candle['sma20_deriv1_1d'] < self.sma20_deriv1_1d_protection.value
or (last_candle['sma5_deriv1_1d'] < -0.1 and last_candle['sma24_deriv1_1h'] < -0.1): and last_candle['sma5_deriv1_1d'] < self.sma5_deriv1_1d_protection.value \
and last_candle['sma24_deriv1_1h'] < self.sma24_deriv1_1h_protection.value):
# or (last_candle['sma5_deriv1_1d'] < -0.1 and last_candle['sma24_deriv1_1h'] < -0.1):
return False return False
if pair.startswith('BTC'):
return True # BTC toujours autorisé
self.should_enter_trade_count = 0 self.should_enter_trade_count = 0
# if max_pair != pair and self.pairs[pair]['total_amount'] > 300: # if max_pair != pair and self.pairs[pair]['total_amount'] > 300:
# return False # return False
if (max_pair != '') & (self.pairs[pair]['count_of_buys'] >= limit) : if (max_pair != '') & (self.pairs[pair]['count_of_buys'] >= limit):
trade = self.pairs[max_pair]['current_trade'] trade = self.pairs[max_pair]['current_trade']
current_time = current_time.astimezone(timezone.utc) current_time = current_time.astimezone(timezone.utc)
open_date = trade.open_date.astimezone(timezone.utc) open_date = trade.open_date.astimezone(timezone.utc)
@@ -2133,7 +2162,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
days_since_open = (current_time_utc - open_date).days days_since_open = (current_time_utc - open_date).days
pct_max_max = self.getPctFirstBuy(max_pair, last_candle) pct_max_max = self.getPctFirstBuy(max_pair, last_candle)
# print(f"days_since_open {days_since_open} max_pair={max_pair} pair={pair}") # print(f"days_since_open {days_since_open} max_pair={max_pair} pair={pair}")
return max_pair == pair or pct_max < - 0.25 or (pct_max_max < - 0.15 and max_pair != pair and days_since_open > 30) return max_pair == pair or pct_max < - 0.25 or (
pct_max_max < - 0.15 and max_pair != pair and days_since_open > 30)
else: else:
return True return True
@@ -2142,16 +2172,16 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# 1. Détection plateau # 1. Détection plateau
informative['rolling_min'] = informative['close'].rolling(plateau_duration).min() informative['rolling_min'] = informative['close'].rolling(plateau_duration).min()
informative['rolling_max'] = informative['close'].rolling(plateau_duration).max() informative['rolling_max'] = informative['close'].rolling(plateau_duration).max()
informative['plateau_amplitude'] = (informative['rolling_max'] - informative['rolling_min']) / informative['rolling_min'] informative['plateau_amplitude'] = (informative['rolling_max'] - informative['rolling_min']) / informative[
'rolling_min']
informative['plateau'] = informative['plateau_amplitude'] < plateau_tolerance informative['plateau'] = informative['plateau_amplitude'] < plateau_tolerance
# 2. Détection "fin de plateau" # 2. Détection "fin de plateau"
#informative['plateau_end'] = (informative['plateau'] & ~informative['plateau'].shift(-1).fillna(False).astype(bool)) # informative['plateau_end'] = (informative['plateau'] & ~informative['plateau'].shift(-1).fillna(False).astype(bool))
next_plateau = informative['plateau'].shift(-1) next_plateau = informative['plateau'].shift(-1)
next_plateau = next_plateau.fillna(False).astype(bool) next_plateau = next_plateau.fillna(False).astype(bool)
informative['plateau_end'] = informative['plateau'] & ~next_plateau informative['plateau_end'] = informative['plateau'] & ~next_plateau
# 3. Enregistrer dernier plateau (min/max) # 3. Enregistrer dernier plateau (min/max)
last_min = None last_min = None
last_max = None last_max = None
@@ -2182,4 +2212,3 @@ class Zeus_8_3_2_B_4_2(IStrategy):
informative['breakout_distance'] = [s[1] for s in last_status] informative['breakout_distance'] = [s[1] for s in last_status]
return informative return informative