Ajout test_signal_success + changement calcul montant
This commit is contained in:
@@ -90,8 +90,11 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
"sma10": {
|
||||
"color": "blue"
|
||||
},
|
||||
"sma5_1h": {
|
||||
"min12_1d": {
|
||||
"color": "red"
|
||||
},
|
||||
"max12_1d": {
|
||||
"color": 'red'
|
||||
}
|
||||
|
||||
},
|
||||
@@ -174,7 +177,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
"last_trade": None,
|
||||
"last_count_of_buys": 0,
|
||||
'base_stake_amount': 0,
|
||||
'stop_buy': False
|
||||
'stop_buy': False,
|
||||
'last_date': 0
|
||||
}
|
||||
for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
|
||||
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"]
|
||||
@@ -234,10 +238,14 @@ 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,
|
||||
action="Buy" if allow_to_buy else "Canceled",
|
||||
action=("Buy" if allow_to_buy else "Canceled") + " " + str(minutes),
|
||||
pair=pair,
|
||||
rate=rate,
|
||||
dispo=dispo,
|
||||
@@ -258,6 +266,8 @@ 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
|
||||
|
||||
if allow_to_sell:
|
||||
self.trades = list()
|
||||
self.pairs[pair]['last_count_of_buys'] = trade.nr_of_successful_entries #self.pairs[pair]['count_of_buys']
|
||||
@@ -270,7 +280,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="Sell",
|
||||
action="Sell " + str(minutes),
|
||||
pair=pair,
|
||||
trade_type=exit_reason,
|
||||
rate=last_candle['close'],
|
||||
@@ -279,6 +289,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
)
|
||||
self.pairs[pair]['max_touch'] = 0
|
||||
self.pairs[pair]['last_buy'] = 0
|
||||
self.pairs[pair]['last_date'] = current_time
|
||||
|
||||
return (allow_to_sell) | (exit_reason == 'force_exit')
|
||||
|
||||
@@ -541,20 +552,20 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
dataframe['average_line_288'] = talib.MIDPOINT(dataframe['close'], timeperiod=288)
|
||||
dataframe['average_line_288_098'] = dataframe['average_line_288'] * 0.98
|
||||
dataframe['average_line_288_099'] = dataframe['average_line_288'] * 0.99
|
||||
# Sort the close prices to find the 4 lowest values
|
||||
sorted_close_prices = dataframe['close'].tail(576).sort_values()
|
||||
lowest_4 = sorted_close_prices.head(20)
|
||||
|
||||
dataframe['lowest_4_average'] = lowest_4.mean()
|
||||
# Propagate this mean value across the entire dataframe
|
||||
# dataframe['lowest_4_average'] = dataframe['lowest_4_average'].iloc[0]
|
||||
|
||||
# # Sort the close prices to find the 4 highest values
|
||||
sorted_close_prices = dataframe['close'].tail(288).sort_values(ascending=False)
|
||||
highest_4 = sorted_close_prices.head(20)
|
||||
|
||||
# # Calculate the mean of the 4 highest values
|
||||
dataframe['highest_4_average'] = highest_4.mean()
|
||||
# # Sort the close prices to find the 4 lowest values
|
||||
# sorted_close_prices = dataframe['close'].rolling(576).sort_values()
|
||||
# lowest_4 = sorted_close_prices.head(20)
|
||||
#
|
||||
# dataframe['lowest_4_average'] = lowest_4.mean()
|
||||
# # Propagate this mean value across the entire dataframe
|
||||
# # dataframe['lowest_4_average'] = dataframe['lowest_4_average'].iloc[0]
|
||||
#
|
||||
# # # Sort the close prices to find the 4 highest values
|
||||
# sorted_close_prices = dataframe['close'].rolling(288).sort_values(ascending=False)
|
||||
# highest_4 = sorted_close_prices.head(20)
|
||||
#
|
||||
# # # Calculate the mean of the 4 highest values
|
||||
# dataframe['highest_4_average'] = highest_4.mean()
|
||||
|
||||
# Compter les baisses consécutives
|
||||
self.calculateDownAndUp(dataframe, limit=0.0001)
|
||||
@@ -581,14 +592,24 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
informative['rsi_diff_2'] = informative['rsi_diff'].diff()
|
||||
|
||||
informative['sma5'] = talib.SMA(informative, timeperiod=5)
|
||||
informative['sma5_diff'] = 100 * informative['sma5'].diff() / informative['sma5']
|
||||
informative['sma5_pct'] = 100 * (informative['sma5'] - informative['sma5'].shift(1)) / informative['sma5']
|
||||
informative['sma5_diff_sum'] = (informative['sma5_pct'].rolling(5).sum()) / 5
|
||||
informative['sma5_diff2_sum'] = informative['sma5_diff_sum'].diff()
|
||||
|
||||
self.calculateDownAndUp(informative, limit=0.0012)
|
||||
|
||||
if self.dp.runmode.value in ('backtest'):
|
||||
self.test_signal_success(informative, percent=0.01, window_size=24)
|
||||
# if self.dp.runmode.value in ('backtest'):
|
||||
# self.test_signal_success(informative, percent=0.01, window_size=24)
|
||||
|
||||
# if self.dp.runmode.value in ('backtest'):
|
||||
# condition = (informative['sma5'].shift(2) > informative['sma5'].shift(1)) \
|
||||
# & (informative['sma5'].shift(1) < informative['sma5']) \
|
||||
# & (informative['down_pct'].shift(3) < -0.015)
|
||||
#
|
||||
# self.test_signal_success(informative, condition, percent=0.01, window_size=3)
|
||||
# self.test_signal_success(informative, condition, percent=0.01, window_size=5)
|
||||
# self.test_signal_success(informative, condition, percent=0.01, window_size=10)
|
||||
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1h", ffill=True)
|
||||
|
||||
@@ -597,6 +618,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
informative = self.calculateTendency(informative, 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['rsi'] = talib.RSI(informative['close']) #, timeperiod=7)
|
||||
informative['rsi_diff'] = informative['rsi'].diff()
|
||||
informative['rsi_sum'] = (informative['rsi'].rolling(7).sum() - 350) / 7
|
||||
@@ -607,26 +631,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
informative['sma5_diff_sum'] = (informative['sma5_pct'].rolling(5).sum()) / 5
|
||||
informative['sma5_diff2_sum'] = informative['sma5_diff_sum'].diff()
|
||||
|
||||
sorted_close_prices = informative['close'].tail(365).sort_values()
|
||||
lowest_4 = sorted_close_prices.head(4)
|
||||
informative['lowest_4'] = lowest_4.mean()
|
||||
|
||||
sorted_close_prices = informative['close'].tail(365).sort_values(ascending=False)
|
||||
highest_4 = sorted_close_prices.head(4)
|
||||
informative['highest_4'] = highest_4.mean()
|
||||
|
||||
last_14_days = informative.tail(14)
|
||||
|
||||
# Récupérer le minimum et le maximum de la colonne 'close' des 14 derniers jours
|
||||
min_14_days = last_14_days['close'].min()
|
||||
max_14_days = last_14_days['close'].max()
|
||||
informative['lowest'] = min_14_days
|
||||
informative['highest'] = max_14_days
|
||||
informative['pct_min_max'] = (max_14_days - min_14_days) / min_14_days
|
||||
informative['mid_min_max'] = min_14_days + (max_14_days - min_14_days) / 2
|
||||
informative['middle'] = informative['lowest_4'] + (informative['highest_4'] - informative['lowest_4']) / 2
|
||||
informative['mid_min_max_0.98'] = informative['mid_min_max'] * 0.98
|
||||
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1d", ffill=True)
|
||||
|
||||
dataframe['count_buys'] = 0
|
||||
@@ -726,14 +730,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
)
|
||||
|
||||
# Calculer l'amplitude en %
|
||||
drop_stats['amplitude_pct'] = ((drop_stats['end_price'] - drop_stats['start_price']) / drop_stats[
|
||||
'start_price']) * 100
|
||||
# drop_stats = drop_stats[drop_stats['amplitude_pct'] < -1]
|
||||
# Associer les amplitudes calculées à chaque drop_id dans dataframe
|
||||
dataframe = dataframe.merge(drop_stats[['amplitude_pct']], on='drop_id', how='left')
|
||||
# Remplir les lignes sans drop_id par 0
|
||||
dataframe['amplitude_pct'] = dataframe['amplitude_pct'].fillna(0)
|
||||
dataframe['amplitude_pct_60'] = dataframe['amplitude_pct'].rolling(60).sum()
|
||||
# drop_stats['amplitude_pct'] = ((drop_stats['end_price'] - drop_stats['start_price']) / drop_stats[
|
||||
# 'start_price']) * 100
|
||||
# # drop_stats = drop_stats[drop_stats['amplitude_pct'] < -1]
|
||||
# # Associer les amplitudes calculées à chaque drop_id dans dataframe
|
||||
# dataframe = dataframe.merge(drop_stats[['amplitude_pct']], on='drop_id', how='left')
|
||||
# # Remplir les lignes sans drop_id par 0
|
||||
# dataframe['amplitude_pct'] = dataframe['amplitude_pct'].fillna(0)
|
||||
# dataframe['amplitude_pct_60'] = dataframe['amplitude_pct'].rolling(60).sum()
|
||||
# ----------------------------------------------------------
|
||||
|
||||
# self.getBinanceOrderBook(pair, dataframe)
|
||||
@@ -844,14 +848,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
& (dataframe['up_count'] > 0)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'mnmx200')
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['close'].shift(2) <= dataframe['min200'])
|
||||
& (dataframe['pct_change'] < 0)
|
||||
& (dataframe['min200'].shift(2) == dataframe['min200'])
|
||||
& (dataframe['close'] < dataframe['lowest_4_average'])
|
||||
& (dataframe['up_count'] > 0)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'min200')
|
||||
# dataframe.loc[
|
||||
# (
|
||||
# (dataframe['close'].shift(2) <= dataframe['min200'])
|
||||
# & (dataframe['pct_change'] < 0)
|
||||
# & (dataframe['min200'].shift(2) == dataframe['min200'])
|
||||
# & (dataframe['close'] < dataframe['lowest_4_average'])
|
||||
# & (dataframe['up_count'] > 0)
|
||||
# ), ['enter_long', 'enter_tag']] = (1, 'min200')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
@@ -985,63 +989,30 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
|
||||
# Calculer le minimum des 14 derniers jours
|
||||
current_price = last_candle['close']
|
||||
|
||||
# trade = self.getTrade(pair)
|
||||
# if trade:
|
||||
# current_price = trade.open_rate
|
||||
base_stake_amount = self.config.get('stake_amount', 100) # Montant de base configuré
|
||||
|
||||
# Calculer le max des 14 derniers jours
|
||||
min_14_days_4 = last_candle['lowest_4_1d']
|
||||
max_14_days_4 = last_candle['highest_4_1d']
|
||||
percent_4 = 1 - (current_price - min_14_days_4) / (max_14_days_4 - min_14_days_4)
|
||||
factor_4 = 1 / ((current_price - min_14_days_4) / (max_14_days_4 - min_14_days_4))
|
||||
max_min_4 = max_14_days_4 / min_14_days_4
|
||||
|
||||
# min_14_days = dataframe['lowest_1d']
|
||||
# max_14_days = dataframe['highest_1d']
|
||||
# percent = 1 - (current_price - min_14_days) / (max_14_days - min_14_days)
|
||||
# factor = 1 / ((current_price - min_14_days) / (max_14_days - min_14_days))
|
||||
# max_min = max_14_days / min_14_days
|
||||
# Stack amount ajusté price=2473.47 min_max=0.15058074985054215 percent=0.8379141364642171 amount=20.0
|
||||
|
||||
first_price = self.pairs[pair]['first_buy']
|
||||
if (first_price == 0):
|
||||
first_price = last_candle['close']
|
||||
|
||||
last_max = last_candle['max200']
|
||||
if self.pairs[pair]['last_max'] > 0:
|
||||
last_max = self.pairs[pair]['last_max']
|
||||
last_count = self.pairs[pair]['last_count_of_buys']
|
||||
# factor = 1
|
||||
last_max = last_candle['max12_1d']
|
||||
# if self.pairs[pair]['last_max'] == 0:
|
||||
# self.pairs[pair]['last_max'] = last_candle['max12_1d']
|
||||
# print(f"last_max set to {last_max}")
|
||||
#
|
||||
# if last_max > 0:
|
||||
# pct = 100 * (last_max - first_price) / last_max
|
||||
#
|
||||
# if pct >= 20:
|
||||
# factor = 2
|
||||
# else:
|
||||
# if pct >= 15:
|
||||
# factor = 1.5
|
||||
# if self.pairs[pair]['last_max'] > 0:
|
||||
# last_max = self.pairs[pair]['last_max']
|
||||
# print(f"last_max is {last_max}")
|
||||
|
||||
pct = 5
|
||||
if last_max > 0:
|
||||
pct = 100 * (last_max - first_price) / last_max
|
||||
thresholds = [2, 10, 20, 30]
|
||||
factors = [0.5, 1.0, 1.5, 2.0]
|
||||
thresholds = [2, 5, 10, 20]
|
||||
factors = [1, 1.25, 1.5, 2.0]
|
||||
|
||||
factor = self.multi_step_interpolate(pct, thresholds, factors)
|
||||
# factor = self.interpolate_factor(pct, start_pct=5, end_pct=50, start_factor=0.8, end_factor=3.0)
|
||||
|
||||
adjusted_stake_amount = base_stake_amount * factor #max(base_stake_amount, min(100, base_stake_amount * percent_4))
|
||||
# if pair in ('BTC/USDT', 'ETH/USDT'):
|
||||
# if percent_4 > 0.5:
|
||||
# adjusted_stake_amount = 300
|
||||
|
||||
# adjusted_stake_amount_2 = max(base_stake_amount / 2.5, min(75, base_stake_amount * percent))
|
||||
|
||||
# print(f"Stack amount ajusté price={current_price} factor={factor} amount={adjusted_stake_amount:.4f}")
|
||||
# print(f"Stack amount ajusté price={current_price} max_min={max_min:.4f} min_14={min_14_days:.4f} max_14={max_14_days:.4f} factor={factor:.4f} percent={percent:.4f} amount={adjusted_stake_amount_2:.4f}")
|
||||
|
||||
return adjusted_stake_amount
|
||||
|
||||
@@ -1136,96 +1107,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
#
|
||||
# return adjusted_stake_amount
|
||||
|
||||
def analyze_conditions(self, pair: str, row: DataFrame):
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
|
||||
if dataframe is None or dataframe.empty:
|
||||
return
|
||||
if row is None or row.empty:
|
||||
return
|
||||
# Créer un tableau pour stocker les résultats de l'analyse
|
||||
results = []
|
||||
# row = dataframe.iloc[-1].squeeze()
|
||||
# result = {'triggered': False, 'conditions_failed': []}
|
||||
try:
|
||||
buy_level = row['buy_level']
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
return None
|
||||
# Première condition : 'buy_fractal'
|
||||
print('------------------------------------------------')
|
||||
print('Test buy fractal ' + pair + ' buy_level=' + str(buy_level))
|
||||
if not (
|
||||
(row['close'] <= (row['min200'] * 1.002)) and
|
||||
(row['percent_max_144'] <= -0.012) and
|
||||
(row['haopen'] < buy_level) and
|
||||
(row['open'] < row['average_line_288']) and
|
||||
(dataframe['min50'].shift(3).iloc[-1] == row['min50'])
|
||||
):
|
||||
failed_conditions = []
|
||||
if row['close'] > (row['min200'] * 1.002):
|
||||
print('close > min200 * 1.002')
|
||||
if row['percent_max_144'] > -0.012:
|
||||
print('percent_max_144 > -0.012')
|
||||
if row['haopen'] >= buy_level:
|
||||
print('haopen >= buy_level')
|
||||
if row['open'] >= row['average_line_288']:
|
||||
print('open >= average_line_288')
|
||||
if dataframe['min50'].shift(3).iloc[-1] != row['min50']:
|
||||
print('min50.shift(3) != min50')
|
||||
# result['conditions_failed'].append({'buy_fractal': failed_conditions})
|
||||
print('------------------------------------------------')
|
||||
print('Test buy_max_diff_015 ' + pair + ' buy_level=' + str(buy_level))
|
||||
# Deuxième condition : 'buy_max_diff_015'
|
||||
if not (
|
||||
(dataframe['max200_diff'].shift(4).iloc[-1] >= 0.015) and
|
||||
(row['close'] <= row['lowest_4_average'] * 1.002) and
|
||||
(row['close'] <= row['min200'] * 1.002) and
|
||||
(dataframe['max50_diff'].shift(4).iloc[-1] >= 0.01) and
|
||||
(row['haclose'] < row['bb_middleband']) and
|
||||
(row['close'] < buy_level) and
|
||||
(row['open'] < row['average_line_288']) and
|
||||
(dataframe['min50'].shift(3).iloc[-1] == row['min50'])
|
||||
):
|
||||
if dataframe['max200_diff'].shift(4).iloc[-1] < 0.015:
|
||||
print('max200_diff.shift(4) < 0.015')
|
||||
if row['close'] > row['lowest_4_average'] * 1.002:
|
||||
print('close > lowest_4_average * 1.002')
|
||||
if row['close'] > row['min200'] * 1.002:
|
||||
print('close > min200 * 1.002')
|
||||
if dataframe['max50_diff'].shift(4).iloc[-1] < 0.01:
|
||||
print('max50_diff.shift(4) < 0.01')
|
||||
if row['haclose'] >= row['bb_middleband']:
|
||||
print('haclose >= bb_middleband')
|
||||
if row['close'] >= buy_level:
|
||||
print('close >= buy_level')
|
||||
if row['open'] >= row['average_line_288']:
|
||||
print('open >= average_line_288')
|
||||
if dataframe['min50'].shift(3).iloc[-1] != row['min50']:
|
||||
print('min50.shift(3) != min50')
|
||||
print('------------------------------------------------')
|
||||
print('Test buy_min_max_200 ' + pair + ' buy_level=' + str(buy_level))
|
||||
if not (
|
||||
(row['close'] <= row['min200'] * 1.002)
|
||||
and (row['min_max200'] > 0.015)
|
||||
and (row['haopen'] < buy_level)
|
||||
and (row['open'] < row['average_line_288'])
|
||||
):
|
||||
if row['close'] > row['min200'] * 1.002:
|
||||
print('close > row[min200] * 1.002')
|
||||
if row['min_max200'] <= 0.015:
|
||||
print('row[min_max200] <= 0.015')
|
||||
if row['haopen'] < buy_level:
|
||||
print('row[haopen] < buy_level')
|
||||
if row['open'] < row['average_line_288']:
|
||||
print('row[open] >= row[average_line_288]')
|
||||
print('------------------------------------------------')
|
||||
|
||||
# Ajouter le résultat à la liste des résultats
|
||||
# results.append(result)
|
||||
|
||||
# print(result)
|
||||
|
||||
def getBinanceOrderBook(self, pair, dataframe: DataFrame):
|
||||
"""Fetch the order book (depth) from Binance."""
|
||||
# print(dataframe)
|
||||
@@ -1593,15 +1474,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
return df
|
||||
|
||||
def test_signal_success(self, df, percent=0.03, window_size=36):
|
||||
def test_signal_success(self, df, condition, percent=0.03, window_size=36):
|
||||
"""
|
||||
df : DataFrame avec colonnes ['close', 'high', ...]
|
||||
percent : hausse recherchée (ex: 0.03 pour +3%)
|
||||
window_size : nombre de bougies (ex: 36 pour 3h en 5m)
|
||||
"""
|
||||
# Exemple condition : RSI < 30 et EMA20 > SMA50
|
||||
condition = (df['down_count'] == 0) & (df['down_count'].shift(1) < 0) & (df['down_pct'].shift(1) < -3)
|
||||
|
||||
hits = 0
|
||||
total = 0
|
||||
|
||||
@@ -1616,7 +1495,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
future_highs = df.loc[future_idx, 'close']
|
||||
if (future_highs >= price_now * (1 + percent)).any():
|
||||
print(df.loc[future_idx])
|
||||
# print(f"{price_now} ==> {df.loc[future_idx]['close']}")
|
||||
hits += 1
|
||||
total += 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user