Calcul 20250101-20250714 737.222 159.166$
This commit is contained in:
@@ -307,7 +307,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# if count < 3:
|
||||
# allow_to_buy = False
|
||||
|
||||
if not self.should_enter_trade(pair, last_candle):
|
||||
if not self.should_enter_trade(pair, last_candle, current_time):
|
||||
allow_to_buy = False
|
||||
|
||||
if allow_to_buy:
|
||||
@@ -382,6 +382,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
self.pairs[pair]['last_buy'] = 0
|
||||
self.pairs[pair]['last_date'] = current_time
|
||||
self.pairs[pair]['last_palier_index'] = -1
|
||||
self.pairs[pair]['last_trade'] = trade
|
||||
self.pairs[pair]['current_trade'] = None
|
||||
|
||||
return (allow_to_sell) | (exit_reason == 'force_exit')
|
||||
|
||||
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
|
||||
@@ -413,6 +416,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
max_touch_before = self.pairs[pair]['max_touch']
|
||||
self.pairs[pair]['last_max'] = max(last_candle['close'], self.pairs[pair]['last_max'])
|
||||
self.pairs[pair]['last_min'] = min(last_candle['close'], self.pairs[pair]['last_min'])
|
||||
self.pairs[pair]['current_trade'] = trade
|
||||
|
||||
count_of_buys = trade.nr_of_successful_entries
|
||||
|
||||
@@ -434,23 +438,26 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# if (last_candle['sma20_deriv1'] < 0 and before_last_candle['sma20_deriv1'] >= 0) and (current_profit > expected_profit):
|
||||
# return 'Drv_' + str(count_of_buys)
|
||||
pair_name = self.getShortName(pair)
|
||||
if 1 <= count_of_buys <= 3:
|
||||
# if (current_profit > expected_profit) and last_candle['can_sell']:
|
||||
# return 'Can_' + pair_name + '_' + str(count_of_buys)
|
||||
|
||||
# if 1 <= count_of_buys <= 3:
|
||||
if ((before_last_candle_2['mid_smooth_3_deriv1'] <= before_last_candle['mid_smooth_3_deriv1'])
|
||||
& (before_last_candle['mid_smooth_3_deriv1'] >= last_candle['mid_smooth_3_deriv1'])) \
|
||||
and (current_profit > expected_profit):
|
||||
return 'Drv3_' + pair_name + '_' + str(count_of_buys)
|
||||
|
||||
if 4 <= count_of_buys <= 6:
|
||||
if ((before_last_candle_2['mid_smooth_12_deriv1'] <= before_last_candle['mid_smooth_12_deriv1'])
|
||||
& (before_last_candle['mid_smooth_12_deriv1'] >= last_candle['mid_smooth_12_deriv1'])) \
|
||||
and (current_profit > expected_profit):
|
||||
return 'Drv13_' + pair_name + '_' + str(count_of_buys)
|
||||
|
||||
if 7 <= count_of_buys:
|
||||
if ((before_last_candle_24['sma24_deriv1_1h'] <= before_last_candle_12['sma24_deriv1_1h'])
|
||||
& (before_last_candle_12['sma24_deriv1_1h'] >= last_candle['sma24_deriv1_1h'])) \
|
||||
and (current_profit > expected_profit):
|
||||
return 'Drv24_' + pair_name + '_' + str(count_of_buys)
|
||||
# if 4 <= count_of_buys <= 6:
|
||||
# if ((before_last_candle_2['mid_smooth_12_deriv1'] <= before_last_candle['mid_smooth_12_deriv1'])
|
||||
# & (before_last_candle['mid_smooth_12_deriv1'] >= last_candle['mid_smooth_12_deriv1'])) \
|
||||
# and (current_profit > expected_profit):
|
||||
# return 'Drv13_' + pair_name + '_' + str(count_of_buys)
|
||||
#
|
||||
# if 7 <= count_of_buys:
|
||||
# if ((before_last_candle_24['sma24_deriv1_1h'] <= before_last_candle_12['sma24_deriv1_1h'])
|
||||
# & (before_last_candle_12['sma24_deriv1_1h'] >= last_candle['sma24_deriv1_1h'])) \
|
||||
# and (current_profit > expected_profit):
|
||||
# return 'Drv24_' + pair_name + '_' + str(count_of_buys)
|
||||
|
||||
# if (baisse > mx) & (current_profit > expected_profit):
|
||||
# self.trades = list()
|
||||
@@ -507,7 +514,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
if self.columns_logged % 10 == 0:
|
||||
self.printLog(
|
||||
f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} |{'Rate':>8} | {'Dispo':>6} | {'Profit':>10} | {'Pct':>6} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>7}| {'last_max':>7}|{'Buys':>5}| {'Stake':>5} |"
|
||||
f"Tdc|{'val':>6}|Distmax|s201d|s5_1d|s5_2d|s5_1h|s5_2h|smt1h|smt2h|"
|
||||
f"Tdc|{'val':>6}|Distmax|s201d|s5_1d|s5_2d|s241h|s242h|smt1h|smt2h|"
|
||||
)
|
||||
self.printLineLog()
|
||||
df = pd.DataFrame.from_dict(self.pairs, orient='index')
|
||||
@@ -657,6 +664,8 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
dataframe["percent12"] = (dataframe["close"] - dataframe["open"].shift(12)) / dataframe["open"].shift(12)
|
||||
|
||||
dataframe = self.calculateDerivation(dataframe, window=3, suffixe="_3")
|
||||
# dataframe = self.calculateDerivation(dataframe, window=3, suffixe="_6")
|
||||
|
||||
dataframe["mid_re_smooth_3"] = self.conditional_smoothing(dataframe['mid_smooth_3'].dropna(),
|
||||
threshold=0.0005).dropna()
|
||||
self.calculeDerivees(dataframe, "mid_re_smooth_3")
|
||||
@@ -668,6 +677,10 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
self.calculeDerivees(dataframe, 'rsi')
|
||||
|
||||
dataframe['max48'] = talib.MAX(dataframe['close'], timeperiod=48)
|
||||
dataframe['min36'] = talib.MIN(dataframe['close'], timeperiod=36)
|
||||
dataframe['max36'] = talib.MAX(dataframe['close'], timeperiod=36)
|
||||
dataframe['pct36'] = 100 * (dataframe['max36'] - dataframe['min36']) / dataframe['min36']
|
||||
dataframe['maxpct36'] = talib.MAX(dataframe['pct36'], timeperiod=36)
|
||||
|
||||
# Bollinger Bands
|
||||
bollinger = qtpylib.bollinger_bands(qtpylib.typical_price(dataframe), window=20, stds=2)
|
||||
@@ -681,6 +694,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
dataframe["bb_width"] = ((dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_upperband"])
|
||||
# Normalization
|
||||
|
||||
dataframe['bb_upperband5'] = dataframe['bb_upperband'].rolling(window=5).mean()
|
||||
dataframe['bb_lowerband5'] = dataframe['bb_lowerband'].rolling(window=5).mean()
|
||||
|
||||
# dataframe = self.calculateRegression(dataframe, column='mid_smooth', window=24, degree=4, future_offset=12)
|
||||
# dataframe = self.calculateRegression(dataframe, column='mid_smooth_24', window=24, degree=4, future_offset=12)
|
||||
|
||||
@@ -724,10 +740,11 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# 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=4)
|
||||
period_1d = 60
|
||||
informative['max12'] = talib.MAX(informative['close'], timeperiod=12)
|
||||
informative['max60'] = talib.MAX(informative['close'], timeperiod=60)
|
||||
informative['max60'] = talib.MAX(informative['close'], timeperiod=period_1d)
|
||||
informative['min12'] = talib.MIN(informative['close'], timeperiod=12)
|
||||
informative['min60'] = talib.MIN(informative['close'], timeperiod=60)
|
||||
informative['min60'] = talib.MIN(informative['close'], timeperiod=period_1d)
|
||||
informative['volatility'] = talib.STDDEV(informative['close'], timeperiod=14) / informative['close']
|
||||
self.calculeDerivees(informative, 'volatility')
|
||||
|
||||
@@ -929,25 +946,71 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
pair = metadata['pair']
|
||||
|
||||
# self.getOpenTrades()
|
||||
expected_profit = self.expectedProfit(pair, dataframe.iloc[-1])
|
||||
# expected_profit = self.expectedProfit(pair, dataframe.iloc[-1])
|
||||
# self.getBinanceOrderBook(pair, dataframe)
|
||||
last_candle = dataframe.iloc[-1].squeeze()
|
||||
|
||||
# Calcul de la pente (différence entre deux bougies consécutives)
|
||||
dataframe['bb_ub_slope'] = dataframe['bb_upperband'].diff()
|
||||
|
||||
# Détection d'une inversion (changement de signe de la pente)
|
||||
# inversion = (
|
||||
# (dataframe['bb_ub_slope'].shift(1).rolling(5).apply(
|
||||
# lambda x: any(x[i] > 0 and x[i + 1] < 0 for i in range(len(x) - 1)))) == 1
|
||||
# )
|
||||
# On regarde si la bande supérieure a atteint un maximum il y a k bougies
|
||||
# lookback = 5
|
||||
# inversion = (dataframe['bb_upperband'] == dataframe['bb_upperband'].rolling(lookback).max())
|
||||
|
||||
# pente de la bb_upperband
|
||||
dataframe['bb_ub_slope'] = dataframe['bb_upperband5'].diff()
|
||||
|
||||
# é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']
|
||||
|
||||
# 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)
|
||||
dataframe['inversion_last5'] = inversion_last5
|
||||
|
||||
N = 24 # nombre minimum de bougies avant inversion
|
||||
rise_threshold = 1.0 # % de hausse à ne pas dépasser
|
||||
|
||||
# Calcul de la hausse minimale avant inversion
|
||||
def compute_rise(idx):
|
||||
if idx < N:
|
||||
return 0
|
||||
low_before = dataframe['close'].iloc[idx - N:idx].min() # min des N bougies avant inversion
|
||||
return (dataframe['close'].iloc[idx] / low_before - 1) * 100
|
||||
|
||||
rise = [compute_rise(i) for i in range(len(dataframe))]
|
||||
dataframe['rise_before_inversion'] = rise
|
||||
|
||||
# Filtre : inversion sans forte hausse avant
|
||||
valid_inversion = inversion_last5 & (dataframe['rise_before_inversion'] <= rise_threshold)
|
||||
|
||||
# dataframe.loc[
|
||||
# (
|
||||
# (dataframe['percent'] > 0)
|
||||
# & (dataframe['mid_smooth_deriv1'] >= dataframe['mid_smooth_deriv1'].shift(1))
|
||||
# ), ['enter_long', 'enter_tag']] = (1, 'down')
|
||||
|
||||
factor = 1.01
|
||||
if pair == "BTC/USDT" or pair == "BTC/USDC":
|
||||
factor = factor / 2
|
||||
dataframe.loc[
|
||||
(
|
||||
# (dataframe['deriv2_1h'].shift(2) >= dataframe['deriv2_1h'].shift(1))
|
||||
# & (dataframe['deriv2_1h'].shift(1) <= dataframe['deriv2_1h'])
|
||||
# (dataframe['deriv1_1h'] >= -0.01)
|
||||
# & (dataframe['deriv2_1h'] >= -0.00)
|
||||
(dataframe['mid_smooth_3_deriv1'].shift(2) >= dataframe['mid_smooth_3_deriv1'].shift(1))
|
||||
& (dataframe['mid_smooth_3_deriv1'].shift(1) <= dataframe['mid_smooth_3_deriv1'])
|
||||
& (dataframe['close'] < dataframe['max48'] * 0.995)
|
||||
|
||||
valid_inversion & inversion_last5
|
||||
& (dataframe['hapercent'] > 0)
|
||||
|
||||
# valid_inversion
|
||||
# ((dataframe['bb_cross_down'] < - 0.1)
|
||||
# | (dataframe['bb_cross_down'].shift(1) < - 0.1)
|
||||
# | (dataframe['bb_cross_down'].shift(2) < - 0.1)
|
||||
# | (dataframe['bb_cross_down'].shift(3) < - 0.1)
|
||||
# )
|
||||
# & (dataframe['hapercent'] > 0)
|
||||
# & (dataframe['close'] * factor < dataframe['bb_upperband5'])
|
||||
#
|
||||
#
|
||||
# (dataframe['mid_smooth_1h_deriv1'] >= 0)
|
||||
@@ -1126,7 +1189,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
print("skip dataframe")
|
||||
return None
|
||||
|
||||
if not self.should_enter_trade(pair, last_candle):
|
||||
if not self.should_enter_trade(pair, last_candle, current_time):
|
||||
return None
|
||||
|
||||
# if self.dp.runmode.value in ('dry_run'):
|
||||
@@ -1356,6 +1419,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
def getPct60D(self, pair, last_candle):
|
||||
return round((last_candle['max60_1d'] - last_candle['min60_1d']) / last_candle['max60_1d'], 4)
|
||||
|
||||
def getPctClose60D(self, pair, last_candle):
|
||||
if last_candle['close'] > last_candle['max60_1d']:
|
||||
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)
|
||||
|
||||
def getLimitBuy(self, pair, last_candle, first_pct):
|
||||
count_of_buys = self.pairs[pair]['count_of_buys']
|
||||
pct60 = self.getPct60D(pair, last_candle) # exemple 0.3 pour 30%
|
||||
@@ -1398,10 +1468,17 @@ 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
|
||||
base_stake_amount = self.config.get('stake_amount') # Montant de base configuré
|
||||
# pct60 = round(100 * self.getPctClose60D(pair, last_candle), 2)
|
||||
|
||||
|
||||
if not pair in ('BTC/USDT', 'BTC/USDC'):
|
||||
# factors = [1, 1.2, 1.3, 1.4]
|
||||
adjusted_stake_amount = base_stake_amount
|
||||
if self.pairs[pair]['count_of_buys'] == 0:
|
||||
pctClose60 = self.getPctClose60D(pair, last_candle)
|
||||
|
||||
adjusted_stake_amount = max(base_stake_amount / 5, base_stake_amount * (1 - pctClose60))
|
||||
else:
|
||||
adjusted_stake_amount = self.pairs[pair]['first_amount']
|
||||
else :
|
||||
first_price = self.pairs[pair]['first_buy']
|
||||
if (first_price == 0):
|
||||
@@ -1413,12 +1490,15 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
pct = 100 * (last_max - first_price) / last_max
|
||||
|
||||
factor = self.multi_step_interpolate(pct, self.thresholds, self.factors)
|
||||
adjusted_stake_amount = 0.7 * base_stake_amount * factor # max(base_stake_amount, min(100, base_stake_amount * percent_4))
|
||||
adjusted_stake_amount = base_stake_amount * factor # max(base_stake_amount, min(100, base_stake_amount * percent_4))
|
||||
|
||||
# pct = 100 * abs(self.getPctFirstBuy(pair, last_candle))
|
||||
#
|
||||
# factor = self.multi_step_interpolate(pct, self.thresholds, self.factors)
|
||||
|
||||
if self.pairs[pair]['count_of_buys'] == 0:
|
||||
self.pairs[pair]['first_amount'] = adjusted_stake_amount
|
||||
|
||||
return adjusted_stake_amount
|
||||
|
||||
def calculateAmountSliding(self, pair, last_candle):
|
||||
@@ -1465,11 +1545,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
return out_max - position * (out_max - out_min)
|
||||
|
||||
def expectedProfit(self, pair: str, last_candle: DataFrame):
|
||||
pct_to_max = 0.004
|
||||
max_60 = last_candle['max60_1d']
|
||||
if last_candle['close'] < max_60:
|
||||
pct_to_max = 0.25 * (max_60 - last_candle['close']) / max_60
|
||||
pct_to_max = 0.004 + 0.001 * self.pairs[pair]['count_of_buys']
|
||||
# pctClose60 = self.getPctClose60D(pair, last_candle)
|
||||
|
||||
# max_60 = last_candle['max60_1d']
|
||||
# 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)
|
||||
|
||||
# print(
|
||||
@@ -1984,7 +2066,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
print("Moyenne des valeurs par double-tranche :")
|
||||
print(pivot_mean.round(2))
|
||||
|
||||
def should_enter_trade(self, pair: str, last_candle) -> bool:
|
||||
def should_enter_trade(self, pair: str, last_candle, current_time) -> bool:
|
||||
|
||||
limit = 3
|
||||
|
||||
@@ -2013,9 +2095,15 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
max_nb_trades = 0
|
||||
total_non_btc = 0
|
||||
max_pair = ''
|
||||
limit_amount = 250
|
||||
max_amount = 0
|
||||
for p in non_btc_pairs:
|
||||
max_nb_trades = max(max_nb_trades, self.pairs[p]['count_of_buys'])
|
||||
max_amount = max(max_amount, self.pairs[p]['total_amount'])
|
||||
|
||||
for p in non_btc_pairs:
|
||||
if (max_nb_trades == self.pairs[p]['count_of_buys'] and max_nb_trades > limit):
|
||||
# if (max_amount == self.pairs[p]['total_amount'] and max_amount > limit_amount):
|
||||
max_pair = p
|
||||
total_non_btc += self.pairs[p]['count_of_buys']
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user