Calcul 20250101-20250714 735.207 106.112$ 26315.818
This commit is contained in:
@@ -19,14 +19,13 @@
|
||||
"buy": {
|
||||
"buy_horizon_predict_1h": 2
|
||||
},
|
||||
"sell": {
|
||||
"sell_allow_decrease": 0.2
|
||||
},
|
||||
"sell": {},
|
||||
"protection": {
|
||||
"protection_fibo": 9,
|
||||
"protection_percent_buy_lost": 3
|
||||
"sma20_deriv1_1d_protection": -0.05,
|
||||
"sma24_deriv1_1h_protection": -0.1,
|
||||
"sma5_deriv1_1d_protection": -0.05
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
@@ -42,6 +42,7 @@ MAGENTA = "\033[35m"
|
||||
CYAN = "\033[36m"
|
||||
RESET = "\033[0m"
|
||||
|
||||
|
||||
def pprint_df(dframe):
|
||||
print(tabulate(dframe, headers='keys', tablefmt='psql', showindex=False))
|
||||
|
||||
@@ -210,9 +211,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
trades = list()
|
||||
max_profit_pairs = {}
|
||||
|
||||
protection_percent_buy_lost = IntParameter(1, 10, default=5, space='protection')
|
||||
protection_fibo = IntParameter(1, 10, default=2, space='protection')
|
||||
sell_allow_decrease = DecimalParameter(0.005, 0.02, default=0.2, decimals=2, space='sell', optimize=True, load=True)
|
||||
sma20_deriv1_1d_protection = DecimalParameter(-0.1, 0.0, default=-0.05, decimals=2, 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)
|
||||
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
|
||||
# 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)
|
||||
# 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 = {}
|
||||
|
||||
@@ -296,7 +303,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# val = self.getProbaHausse144(last_candle)
|
||||
|
||||
# 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:
|
||||
# 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]['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:
|
||||
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'])
|
||||
|
||||
|
||||
def getShortName(self, pair):
|
||||
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,
|
||||
last_candle=None):
|
||||
# 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
|
||||
if self.columns_logged % 10 == 0:
|
||||
self.printLog(
|
||||
@@ -521,7 +529,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
self.printLineLog()
|
||||
df = pd.DataFrame.from_dict(self.pairs, orient='index')
|
||||
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_filtered["first_buy", "last_max", "max_touch", "last_sell","last_buy", 'count_of_buys', 'current_profit']
|
||||
|
||||
@@ -587,8 +596,10 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
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)
|
||||
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)
|
||||
|
||||
@@ -827,8 +838,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# ===============================
|
||||
# lissage des valeurs horaires
|
||||
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_deriv2"] = 10 * dataframe["mid_smooth_1h_deriv1"].diff().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_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
|
||||
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_2 = 'mid_smooth_1h_deriv2'
|
||||
# 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['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'].shift(1) <= dataframe['mid_smooth_1h_deriv2']), 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'].shift(1) <= dataframe['mid_smooth_1h_deriv2']), dataframe['close'],
|
||||
np.nan)
|
||||
|
||||
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
|
||||
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_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)
|
||||
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,
|
||||
duplicates='drop')
|
||||
# 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_2} : [{', '.join([f'{b:.4f}' for b in bins_1d])}]")
|
||||
# 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])}]")
|
||||
# Agrégation
|
||||
grouped = df.groupby([f"{indic_2}_bin", f"{indic_1}_bin"], observed=True)[futur_cols].agg(['mean', 'count'])
|
||||
# Affichage
|
||||
with pd.option_context('display.max_rows', None, 'display.max_columns', None):
|
||||
print(grouped.round(4))
|
||||
|
||||
# Ajout des probabilités de hausse
|
||||
for col in futur_cols:
|
||||
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):
|
||||
# ne rien faire si ordre deja en cours
|
||||
if trade.has_open_orders:
|
||||
print("skip open orders")
|
||||
# print("skip open orders")
|
||||
return None
|
||||
if (self.wallets.get_available_stake_amount() < 50): # or trade.stake_amount >= max_stake:
|
||||
return 0
|
||||
@@ -1165,7 +1188,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
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']:
|
||||
pct_first = self.getPctFirstBuy(pair, last_candle)
|
||||
@@ -1191,7 +1215,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# lim = self.getLimitBuy(pair, last_candle, pct)
|
||||
|
||||
if (len(dataframe) < 1):
|
||||
print("skip dataframe")
|
||||
# print("skip dataframe")
|
||||
return None
|
||||
|
||||
if not self.should_enter_trade(pair, last_candle, current_time):
|
||||
@@ -1367,7 +1391,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
return stake_amount
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
# print(exception)
|
||||
return None
|
||||
# if (count_of_buys >= 6):
|
||||
# self.log_trade(
|
||||
@@ -1410,7 +1434,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
self.pairs[trade.pair]['last_candle'] = last_candle
|
||||
return stake_amount
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
# print(exception)
|
||||
return None
|
||||
|
||||
return None
|
||||
@@ -1429,7 +1453,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
return 1
|
||||
if last_candle['close'] < last_candle['min60_1d']:
|
||||
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):
|
||||
count_of_buys = self.pairs[pair]['count_of_buys']
|
||||
@@ -1443,7 +1468,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
return lim
|
||||
|
||||
|
||||
# def getProbaHausseEmaVolume(self, last_candle):
|
||||
# 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'])
|
||||
@@ -1563,7 +1587,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# if 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)
|
||||
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(
|
||||
# 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
|
||||
print("Moyenne des valeurs par double-tranche :")
|
||||
print(pivot_mean.round(2))
|
||||
# print("Moyenne des valeurs par double-tranche :")
|
||||
# print(pivot_mean.round(2))
|
||||
|
||||
def should_enter_trade(self, pair: str, last_candle, current_time) -> bool:
|
||||
|
||||
limit = 3
|
||||
|
||||
if pair.startswith('BTC'):
|
||||
return True # BTC toujours autorisé
|
||||
|
||||
# Filtrer les paires non-BTC
|
||||
non_btc_pairs = [p for p in self.pairs if not p.startswith('BTC')]
|
||||
|
||||
@@ -2114,12 +2136,19 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# char="."
|
||||
# print(f"should_enter_trade canceled all pairs decreased {'':{char}>{self.should_enter_trade_count}}")
|
||||
# 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 (last_candle['sma20_deriv1_1d'] < -0.05 and last_candle['sma5_deriv1_1d'] < -0.05)\
|
||||
or (last_candle['sma5_deriv1_1d'] < -0.1 and last_candle['sma24_deriv1_1h'] < -0.1):
|
||||
if (last_candle['sma20_deriv1_1d'] < self.sma20_deriv1_1d_protection.value
|
||||
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
|
||||
|
||||
if pair.startswith('BTC'):
|
||||
return True # BTC toujours autorisé
|
||||
|
||||
self.should_enter_trade_count = 0
|
||||
|
||||
# if max_pair != pair and self.pairs[pair]['total_amount'] > 300:
|
||||
@@ -2133,7 +2162,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
days_since_open = (current_time_utc - open_date).days
|
||||
pct_max_max = self.getPctFirstBuy(max_pair, last_candle)
|
||||
# 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:
|
||||
return True
|
||||
|
||||
@@ -2142,7 +2172,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# 1. Détection plateau
|
||||
informative['rolling_min'] = informative['close'].rolling(plateau_duration).min()
|
||||
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
|
||||
|
||||
# 2. Détection "fin de plateau"
|
||||
@@ -2151,7 +2182,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
next_plateau = next_plateau.fillna(False).astype(bool)
|
||||
informative['plateau_end'] = informative['plateau'] & ~next_plateau
|
||||
|
||||
|
||||
# 3. Enregistrer dernier plateau (min/max)
|
||||
last_min = 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]
|
||||
|
||||
return informative
|
||||
|
||||
|
||||
Reference in New Issue
Block a user