Nouvelle version Zeus_8_3_2_B_4_2.py
This commit is contained in:
@@ -94,7 +94,27 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
columns_logged = False
|
||||
pairs = {
|
||||
pair: {
|
||||
"first_buy": 0,
|
||||
"last_max": 0,
|
||||
"trade_info": {},
|
||||
"max_touch": 0.0,
|
||||
"last_sell": 0.0,
|
||||
"last_buy": 0.0,
|
||||
'count_of_buys': 0,
|
||||
'current_profit': 0,
|
||||
'expected_profit': 0,
|
||||
"last_candle": {},
|
||||
"last_trade": None,
|
||||
"last_count_of_buys": 0,
|
||||
'base_stake_amount': 0,
|
||||
'stop_buy': False
|
||||
}
|
||||
for pair in ["BTC/USDC", "ETH/USDC", "DOGE/USDC", "XRP/USDC", "SOL/USDC",
|
||||
"BTC/USDT", "ETH/USDT", "DOGE/USDT", "XRP/USDT", "SOL/USDT"]
|
||||
}
|
||||
# 20 20 40 60 100 160 260 420
|
||||
# 50 50 100 300 500
|
||||
# fibo = [1, 1, 2, 3, 5, 8, 13, 21]
|
||||
@@ -209,7 +229,32 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
allow_to_buy = True # (rate <= float(limit)) | (entry_tag == 'force_entry')
|
||||
self.trades = list()
|
||||
dispo = round(self.wallets.get_available_stake_amount())
|
||||
print(f"BUY {pair} {entry_tag} {current_time} allow_to_buy={allow_to_buy} dispo={dispo}")
|
||||
|
||||
self.pairs[pair]['first_buy'] = rate
|
||||
self.pairs[pair]['last_buy'] = rate
|
||||
self.pairs[pair]['max_touch'] = last_candle['close']
|
||||
self.pairs[pair]['last_candle'] = last_candle
|
||||
self.pairs[pair]['count_of_buys'] = 1
|
||||
self.pairs[pair]['current_profit'] = 0
|
||||
|
||||
print(
|
||||
f"|{'-' * 18}+{'-' * 12}+{'-' * 5}+{'-' * 20}+{'-' * 14}+{'-' * 8}+{'-' * 10}+{'-' * 7}+{'-' * 13}+{'-' * 14}+{'-' * 14}+{'-' * 7}+{'-' * 12}|"
|
||||
)
|
||||
|
||||
stake_amount = self.adjust_stake_amount(pair, last_candle)
|
||||
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="START BUY",
|
||||
pair=pair,
|
||||
rate=rate,
|
||||
dispo=dispo,
|
||||
profit=0,
|
||||
trade_type=entry_tag,
|
||||
buys=1,
|
||||
stake=round(stake_amount, 2)
|
||||
)
|
||||
|
||||
return allow_to_buy
|
||||
|
||||
@@ -223,11 +268,27 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
allow_to_sell = (last_candle['percent'] < 0)
|
||||
|
||||
if allow_to_sell:
|
||||
self.trades = list()
|
||||
self.pairs[pair]['last_count_of_buys'] = self.pairs[pair]['count_of_buys']
|
||||
self.pairs[pair]['last_sell'] = rate
|
||||
self.pairs[pair]['last_trade'] = trade
|
||||
self.pairs[pair]['last_candle'] = last_candle
|
||||
self.trades = list()
|
||||
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}")
|
||||
else:
|
||||
print('Cancel Sell ' + exit_reason + ' ' + str(current_time) + ' ' + pair)
|
||||
# print(f"Sell {pair} {current_time} {exit_reason} dispo={dispo} amount={amount} rate={rate} open_rate={trade.open_rate}")
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="Sell",
|
||||
pair=pair,
|
||||
trade_type=exit_reason,
|
||||
rate=last_candle['close'],
|
||||
dispo=dispo,
|
||||
profit=round(trade.calc_profit(rate, amount), 2)
|
||||
)
|
||||
self.pairs[pair]['max_touch'] = 0
|
||||
self.pairs[pair]['last_buy'] = 0
|
||||
|
||||
return (allow_to_sell) | (exit_reason == 'force_exit')
|
||||
|
||||
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
|
||||
@@ -247,26 +308,39 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
|
||||
last_candle = dataframe.iloc[-1].squeeze()
|
||||
before_last_candle = dataframe.iloc[-2].squeeze()
|
||||
|
||||
# self.analyze_conditions(pair, dataframe)
|
||||
|
||||
# print("---------------" + pair + "----------------")
|
||||
expected_profit = self.expectedProfit(pair, last_candle)
|
||||
|
||||
# Calcul du prix cible basé sur l'ATR
|
||||
atr_take_profit = trade.open_rate + (last_candle['atr'] * 2) # Prendre profit à 2x l'ATR
|
||||
max_touch_before = self.pairs[pair]['max_touch']
|
||||
self.pairs[pair]['last_max'] = max(last_candle['haclose'], self.pairs[pair]['last_max'])
|
||||
|
||||
# print(f"{pair} Custom exit atr_take_profit={atr_take_profit:.4f}")
|
||||
# if current_rate >= atr_take_profit:
|
||||
# return 'sell_atr_take_profit'
|
||||
count_of_buys = trade.nr_of_successful_entries
|
||||
|
||||
if (last_candle['percent3'] < -0.002) & (last_candle['percent12'] < 0) & (
|
||||
current_profit > last_candle['min_max200'] / 3):
|
||||
self.pairs[pair]['count_of_buys'] = count_of_buys
|
||||
self.pairs[pair]['current_profit'] = current_profit
|
||||
pct_first = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
|
||||
|
||||
# if (last_candle['rsi_1d'] > 50) & (last_candle['percent12'] < 0.0):
|
||||
if (last_candle['percent3'] < 0.0) & (current_profit > last_candle['min_max200'] / 3):
|
||||
self.trades = list()
|
||||
return 'min_max200'
|
||||
return 'mx_' + str(count_of_buys)
|
||||
if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit):
|
||||
self.trades = list()
|
||||
return 'profit'
|
||||
return 'profit_' + 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):
|
||||
self.trades = list()
|
||||
return 'rsi_' + str(count_of_buys)
|
||||
|
||||
# if (last_candle['percent3'] < -0.002) & (last_candle['percent12'] < 0) & (
|
||||
# current_profit > last_candle['min_max200'] / 3):
|
||||
# self.trades = list()
|
||||
# return 'mnmx_' + str(count_of_buys)
|
||||
# if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit):
|
||||
# self.trades = list()
|
||||
# return 'profit_' + str(count_of_buys)
|
||||
self.pairs[pair]['max_touch'] = max(last_candle['haclose'], self.pairs[pair]['max_touch'])
|
||||
|
||||
def informative_pairs(self):
|
||||
# get access to all pairs available in whitelist.
|
||||
@@ -276,6 +350,63 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
|
||||
return informative_pairs
|
||||
|
||||
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':
|
||||
return
|
||||
if self.columns_logged % 30 == 0:
|
||||
# print(
|
||||
# f"|{'-' * 18}+{'-' * 12}+{'-' * 12}+{'-' * 20}+{'-' * 14}+{'-' * 8}+{'-' * 10}+{'-' * 7}+{'-' * 13}+{'-' * 14}+{'-' * 14}+{'-' * 7}+{'-' * 12}|"
|
||||
# )
|
||||
print(
|
||||
f"| {'Date':<16} | {'Action':<10} |{'Pair':<5}| {'Trade Type':<18} | {'Rate':>12} | {'Dispo':>6} | {'Profit':>8} | {'Pct':>5} | {'max_touch':>11} | {'last_lost':>12} | {'last_max':>12} | {'Buys':>5} | {'Stake':>10} |"
|
||||
)
|
||||
print(
|
||||
f"|{'-' * 18}+{'-' * 12}+{'-' * 5}+{'-' * 20}+{'-' * 14}+{'-' * 8}+{'-' * 10}+{'-' * 7}+{'-' * 13}+{'-' * 14}+{'-' * 14}+{'-' * 7}+{'-' * 12}|"
|
||||
)
|
||||
self.columns_logged += 1
|
||||
date = str(date)[:16] if date else "-"
|
||||
limit = None
|
||||
# if buys is not None:
|
||||
# limit = round(last_rate * (1 - self.fibo[buys] / 100), 4)
|
||||
|
||||
rsi = ''
|
||||
rsi_pct = ''
|
||||
# if last_candle is not None:
|
||||
# if (not np.isnan(last_candle['rsi_1d'])) and (not np.isnan(last_candle['rsi_1h'])):
|
||||
# rsi = str(int(last_candle['rsi_1d'])) + " " + str(int(last_candle['rsi_1h']))
|
||||
# if (not np.isnan(last_candle['rsi_pct_1d'])) and (not np.isnan(last_candle['rsi_pct_1h'])):
|
||||
# rsi_pct = str(int(10000 * last_candle['bb_mid_pct_1d'])) + " " + str(
|
||||
# int(last_candle['rsi_pct_1d'])) + " " + str(int(last_candle['rsi_pct_1h']))
|
||||
|
||||
# first_rate = self.percent_threshold.value
|
||||
# last_rate = self.threshold.value
|
||||
# action = self.color_line(action, action)
|
||||
sma5_1d = ''
|
||||
sma5_1h = ''
|
||||
|
||||
sma5 = str(sma5_1d) + ' ' + str(sma5_1h)
|
||||
|
||||
last_lost = round((last_candle['haclose'] - self.pairs[pair]['max_touch']) / self.pairs[pair]['max_touch'], 3)
|
||||
|
||||
max_touch = '' #round(last_candle['max12_1d'], 1) #round(self.pairs[pair]['max_touch'], 1)
|
||||
pct_max = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3) # round(100 * self.pairs[pair]['current_profit'], 1)
|
||||
|
||||
if trade_type is not None:
|
||||
if np.isnan(last_candle['rsi_1d']):
|
||||
string = ' '
|
||||
else:
|
||||
string = (str(int(last_candle['rsi_1d']))) + " " + str(int(last_candle['rsi_diff_1d']))
|
||||
trade_type = trade_type \
|
||||
+ " " + string \
|
||||
+ " " + str(int(last_candle['rsi_1h'])) \
|
||||
+ " " + str(int(last_candle['rsi_diff_1h']))
|
||||
|
||||
print(
|
||||
f"| {date:<16} | {action:<10} | {pair[0:3]:<3} | {trade_type or '-':<18} | {rate or '-':>12} | {dispo or '-':>6} | {profit or '-':>8} | {pct_max or '-':>5} | {max_touch or '-':>11} | {last_lost or '-':>12} | {round(self.pairs[pair]['last_max'], 2) or '-':>12} | {buys or '-':>5} | {stake or '-':>10} |"
|
||||
)
|
||||
|
||||
def populate_indicators(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
# Add all ta features
|
||||
pair = metadata['pair']
|
||||
@@ -333,7 +464,9 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
(dataframe["close"] - dataframe["bb_lowerband"]) /
|
||||
(dataframe["bb_upperband"] - dataframe["bb_lowerband"])
|
||||
)
|
||||
|
||||
dataframe["bb_width"] = (
|
||||
(dataframe["bb_upperband"] - dataframe["bb_lowerband"]) / dataframe["bb_upperband"]
|
||||
)
|
||||
# Normalization
|
||||
|
||||
dataframe['average_line'] = dataframe['close'].mean()
|
||||
@@ -357,18 +490,18 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# # Calculate the mean of the 4 highest values
|
||||
dataframe['highest_4_average'] = highest_4.mean()
|
||||
|
||||
# # Propagate this mean value across the entire dataframe
|
||||
# dataframe['highest_4_average'] = dataframe['highest_4_average'].iloc[0]
|
||||
|
||||
dataframe['volatility'] = talib.STDDEV(dataframe['close'], timeperiod=144) / dataframe['close']
|
||||
dataframe['atr'] = talib.ATR(dataframe['high'], dataframe['low'], dataframe['close'], timeperiod=144) / \
|
||||
dataframe['close']
|
||||
# dataframe['pct_average'] = (dataframe['highest_4_average'] - dataframe['close']) / dataframe['lowest_4_average']
|
||||
# dataframe['highest_4_average_1'] = dataframe['highest_4_average'] * 0.99
|
||||
# dataframe['highest_4_average_2'] = dataframe['highest_4_average'] * 0.98
|
||||
# dataframe['highest_4_average_3'] = dataframe['highest_4_average'] * 0.97
|
||||
# dataframe['highest_4_average_4'] = dataframe['highest_4_average'] * 0.96
|
||||
# dataframe['highest_4_average_5'] = dataframe['highest_4_average'] * 0.95
|
||||
# Compter les baisses consécutives
|
||||
dataframe['down'] = dataframe['hapercent'] <= 0.001
|
||||
dataframe['up'] = dataframe['hapercent'] >= 0.0001
|
||||
dataframe['down_count'] = - dataframe['down'].astype(int) * (
|
||||
dataframe['down'].groupby((dataframe['down'] != dataframe['down'].shift()).cumsum()).cumcount() + 1)
|
||||
dataframe['up_count'] = dataframe['up'].astype(int) * (
|
||||
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
|
||||
dataframe['down_pct'] = self.calculateUpDownPct(dataframe, 'down_count')
|
||||
dataframe['up_pct'] = self.calculateUpDownPct(dataframe, 'up_count')
|
||||
|
||||
# Normaliser les données de 'close'
|
||||
# normalized_close = self.min_max_scaling(dataframe['close'])
|
||||
@@ -376,10 +509,21 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1h")
|
||||
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['rsi'] = talib.RSI(informative['close'], length=7)
|
||||
informative['rsi_diff'] = informative['rsi'] - informative['rsi'].shift(1)
|
||||
|
||||
informative['sma5'] = talib.SMA(informative, timeperiod=5)
|
||||
informative['sma5_pct'] = 100 * (informative['sma5'] - informative['sma5'].shift(1)) / informative['sma5']
|
||||
dataframe = merge_informative_pair(dataframe, informative, self.timeframe, "1h", ffill=True)
|
||||
|
||||
################### INFORMATIVE 1d
|
||||
informative = self.dp.get_pair_dataframe(pair=metadata['pair'], timeframe="1d")
|
||||
informative['rsi'] = talib.RSI(informative['close'], length=7)
|
||||
informative['rsi_diff'] = informative['rsi'] - informative['rsi'].shift(1)
|
||||
|
||||
informative['sma5'] = talib.SMA(informative, timeperiod=5)
|
||||
informative['sma5_pct'] = 100 * (informative['sma5'] - informative['sma5'].shift(1)) / informative['sma5']
|
||||
|
||||
sorted_close_prices = informative['close'].tail(365).sort_values()
|
||||
lowest_4 = sorted_close_prices.head(4)
|
||||
informative['lowest_4'] = lowest_4.mean()
|
||||
@@ -461,7 +605,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# # for buy in filled_buys:
|
||||
# # print(filled_buys)
|
||||
|
||||
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
|
||||
dataframe['price_change'] = dataframe['close'].diff()
|
||||
@@ -540,71 +684,20 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# print('adjust exit price ' + str(self.adjust_exit_price(dataframe.iloc[-1])))
|
||||
print('calcul expected_profit ' + str(expected_profit))
|
||||
|
||||
buy_level = dataframe['buy_level'] # self.get_buy_level(pair, dataframe)
|
||||
buy_level = dataframe['average_line_50'] #dataframe['buy_level'] # self.get_buy_level(pair, dataframe)
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['close'] <= dataframe['min200'] * 1.002)
|
||||
& (dataframe['percent_max_144'] <= -0.012)
|
||||
& (dataframe['haopen'] < buy_level)
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
& (dataframe['min50'].shift(3) == dataframe['min50'])
|
||||
), ['buy', 'enter_tag']] = (1, 'buy_fractal')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['max200_diff'].shift(4) >= 0.015)
|
||||
& (dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
|
||||
& (dataframe['close'] <= dataframe['min200'] * 1.002)
|
||||
& (dataframe['max50_diff'].shift(4) >= 0.01)
|
||||
& (dataframe['haclose'] < dataframe['bb_middleband'])
|
||||
& (dataframe['close'] < buy_level)
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
& (dataframe['min50'].shift(3) == dataframe['min50'])
|
||||
), ['buy', 'enter_tag']] = (1, 'buy_max_diff_015')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['max200_diff'] >= 0.018)
|
||||
& (dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
|
||||
& (dataframe['max50_diff'] >= 0.009)
|
||||
& (dataframe['close'] <= dataframe['min200'] * 1.002)
|
||||
& (dataframe['haclose'] < dataframe['bb_middleband'])
|
||||
& (dataframe['close'] < buy_level)
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
& (dataframe['min50'].shift(3) == dataframe['min50'])
|
||||
), ['buy', 'enter_tag']] = (1, 'buy_max_diff_018')
|
||||
|
||||
# dataframe.loc[
|
||||
# (
|
||||
# (dataframe['max200_diff'] >= 0.018)
|
||||
# & (dataframe['open'] < dataframe['average_line_288'])
|
||||
# & (dataframe['close'] < dataframe['min12'] * 1.002)
|
||||
# & (dataframe['min12'].shift(2) == dataframe['min12'])
|
||||
# ), ['buy', 'enter_tag']] = (1, 'buy_min_max200')
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['max200_diff'] >= 0.025)
|
||||
& (dataframe['percent12'] < -0.002)
|
||||
& (dataframe['pct_change'] < 0)
|
||||
# & (dataframe['pct_change'] < 0)
|
||||
& (dataframe['open'] < dataframe['average_line_288_099'])
|
||||
& (dataframe['open'] < dataframe['average_line_50'])
|
||||
& (dataframe['count_buys'] == 0 |
|
||||
((dataframe['count_buys'] > 0) & (dataframe['close'] <= dataframe['limit']))
|
||||
)
|
||||
& (dataframe['percent'] >= -0.0005)
|
||||
& (dataframe['min12'].shift(2) == dataframe['min12'])
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_min_max200_2')
|
||||
dataframe.loc[
|
||||
(
|
||||
((dataframe['count_buys'] > 0) & (dataframe['close'] <= dataframe['limit']))
|
||||
& (dataframe['close'] < dataframe['min200'] * 1.002)
|
||||
# & (dataframe['percent'] >= -0.0005)
|
||||
& (
|
||||
(dataframe['min12'].shift(2) == dataframe['min12']) |
|
||||
(dataframe['min200'].shift(60) >= dataframe['min200'] * 1.03)
|
||||
)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_count_buy')
|
||||
& (dataframe['min12'].shift(2) == dataframe['min12'])
|
||||
& (dataframe['up_count'] > 0)
|
||||
& (dataframe["bb_width"] > 0.01)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'mx200')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
@@ -626,51 +719,20 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
| (dataframe['percent12'] < -0.022)
|
||||
| (dataframe['percent24'] < -0.022)
|
||||
)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_0_percent12')
|
||||
dataframe.loc[
|
||||
(
|
||||
# (dataframe['percent12'] < -0.015)
|
||||
((dataframe['count_buys'] > 0) & (dataframe['close'] <= dataframe['limit']))
|
||||
& (dataframe['open'] < dataframe['average_line_50'])
|
||||
& (dataframe['close'] < dataframe['min12'] * 1.002)
|
||||
& (dataframe['min12'].shift(2) == dataframe['min12'])
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_percent12')
|
||||
& (dataframe['up_count'] > 0)
|
||||
& (dataframe["bb_width"] > 0.01)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'pct12')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['percent_max_144'] <= -0.02)
|
||||
& (dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
|
||||
& (dataframe['haopen'] < buy_level)
|
||||
& (dataframe['min50'].shift(3) == dataframe['min50'])
|
||||
& (dataframe['close'] <= dataframe['min50'] * 1.002)
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_percent_max_144')
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['close'] <= dataframe['min200'] * 1.002)
|
||||
& (dataframe["bb_width"] > 0.01)
|
||||
& (dataframe['min_max200'] > 0.015)
|
||||
& (dataframe['pct_change'] < 0)
|
||||
# & (dataframe['pct_change'] < 0)
|
||||
& (dataframe['haopen'] < buy_level)
|
||||
& (dataframe['open'] < dataframe['average_line_288'])
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_min_max_200')
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['percent_max_144'] <= -0.02)
|
||||
& (dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
|
||||
& (dataframe['close_02'] < dataframe['max144'])
|
||||
& (dataframe['haopen'] < buy_level)
|
||||
& (dataframe['close'] <= dataframe['average_line_288_099'])
|
||||
& (dataframe['min50'].shift(3) == dataframe['min50'])
|
||||
& (dataframe['close'] <= dataframe['min50'] * 1.002)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_close_02')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
|
||||
& (dataframe['haopen'] >= dataframe['average_line_288_098'])
|
||||
& (dataframe['haclose'] <= dataframe['average_line_288_098'])
|
||||
& (dataframe['haopen'] < buy_level)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_average_line_288_098')
|
||||
& (dataframe['up_count'] > 0)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'mnmx200')
|
||||
dataframe.loc[
|
||||
(
|
||||
(dataframe['close'].shift(2) <= dataframe['min200'])
|
||||
@@ -680,7 +742,18 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
& (dataframe['count_buys'] == 0 |
|
||||
((dataframe['count_buys'] > 0) & (dataframe['close'] <= dataframe['limit']))
|
||||
)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'buy_min200')
|
||||
& (dataframe['up_count'] > 0)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'min200')
|
||||
|
||||
dataframe.loc[
|
||||
(
|
||||
# (dataframe['rsi_1h'] < 70)
|
||||
# & (dataframe['rsi_diff_1h'] > -5)
|
||||
(dataframe["bb_width"] > 0.01)
|
||||
& (dataframe['down_count'].shift(1) < - 6)
|
||||
& (dataframe['down_count'] == 0)
|
||||
& (dataframe['down_pct'].shift(1) <= -0.5)
|
||||
), ['enter_long', 'enter_tag']] = (1, 'down')
|
||||
|
||||
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.01, np.nan)
|
||||
|
||||
@@ -701,7 +774,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
|
||||
last_candle = dataframe.iloc[-1].squeeze()
|
||||
# prépare les données
|
||||
count_of_buys = trade.nr_of_successful_entries
|
||||
current_time = current_time.astimezone(timezone.utc)
|
||||
open_date = trade.open_date.astimezone(timezone.utc)
|
||||
dispo = round(self.wallets.get_available_stake_amount())
|
||||
@@ -712,12 +784,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
pair = trade.pair
|
||||
if pair not in ('BTC/USDT', 'DOGE/USDT', 'ETH/USDT'):
|
||||
return None
|
||||
max_buys = 7
|
||||
|
||||
filled_buys = trade.select_filled_orders('buy')
|
||||
count_of_buys = len(filled_buys)
|
||||
if count_of_buys >= max_buys:
|
||||
return None
|
||||
count_of_buys = trade.nr_of_successful_entries
|
||||
|
||||
# if 'buy' in last_candle:
|
||||
# condition = (last_candle['buy'] == 1)
|
||||
@@ -725,43 +792,58 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# condition = False
|
||||
# self.protection_nb_buy_lost.value
|
||||
limit = last_candle['limit']
|
||||
stake_amount = min(200, self.adjust_stake_amount(pair, last_candle) * self.fibo[count_of_buys])
|
||||
|
||||
current_time_utc = current_time.astimezone(timezone.utc)
|
||||
open_date = trade.open_date.astimezone(timezone.utc)
|
||||
days_since_open = (current_time_utc - open_date).days
|
||||
pct_first = round((last_candle['close'] - self.pairs[pair]['first_buy']) / self.pairs[pair]['first_buy'], 3)
|
||||
pct_max = round((last_candle['close'] - self.pairs[trade.pair]['last_buy']) / self.pairs[trade.pair]['last_buy'], 4)
|
||||
|
||||
pct = 0.012
|
||||
stake_amount = min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle) - 20 * pct_first / pct) #min(200, self.adjust_stake_amount(pair, last_candle) * self.fibo[count_of_buys])
|
||||
|
||||
# if (days_since_open > count_of_buys) & (0 < count_of_buys <= max_buys) & (current_rate <= limit) & (last_candle['enter_long'] == 1):
|
||||
limit_buy = 5
|
||||
limit_buy = 20
|
||||
if (count_of_buys < limit_buy) \
|
||||
and ((last_candle['enter_long'] == 1) or last_candle['percent48'] < - 0.03) \
|
||||
and (current_profit < -0.015 * count_of_buys) \
|
||||
and (last_candle['enter_long'] == 1):
|
||||
and ((last_candle['enter_long'] == 1) or last_candle['percent48'] < - 0.03) \
|
||||
and (last_candle['enter_long'] == 1) \
|
||||
and (pct_max < - pct - (count_of_buys * 0.001)):
|
||||
try:
|
||||
|
||||
# This then calculates current safety order size
|
||||
# stake_amount = stake_amount * pow(1.5, count_of_buys)
|
||||
print(
|
||||
f"Adjust {current_time} price={trade.pair} rate={current_rate:.4f} buys={count_of_buys} limit={limit:.4f} stake={stake_amount:.4f}")
|
||||
|
||||
trade_type = last_candle['enter_tag'] if last_candle['enter_long'] == 1 else 'pct48'
|
||||
self.log_trade(
|
||||
last_candle=last_candle,
|
||||
date=current_time,
|
||||
action="Loss -",
|
||||
dispo=dispo,
|
||||
pair=trade.pair,
|
||||
rate=current_rate,
|
||||
trade_type=trade_type,
|
||||
profit=round(current_profit, 4), # round(current_profit * trade.stake_amount, 2),
|
||||
buys=trade.nr_of_successful_entries + 1,
|
||||
stake=round(stake_amount, 2)
|
||||
)
|
||||
self.pairs[trade.pair]['last_buy'] = current_rate
|
||||
self.pairs[trade.pair]['max_touch'] = last_candle['close']
|
||||
self.pairs[trade.pair]['last_candle'] = last_candle
|
||||
return stake_amount
|
||||
except Exception as exception:
|
||||
print(exception)
|
||||
return None
|
||||
return None
|
||||
|
||||
def adjust_stake_amount(self, pair: str, dataframe: DataFrame):
|
||||
def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
|
||||
# Calculer le minimum des 14 derniers jours
|
||||
current_price = dataframe['close']
|
||||
current_price = last_candle['close']
|
||||
|
||||
# trade = self.getTrade(pair)
|
||||
# if trade:
|
||||
# current_price = trade.open_rate
|
||||
base_stake_amount = self.config.get('stake_amount', 50) # Montant de base configuré
|
||||
base_stake_amount = self.config.get('stake_amount', 100) # Montant de base configuré
|
||||
|
||||
# Calculer le max des 14 derniers jours
|
||||
min_14_days_4 = dataframe['lowest_4_1d']
|
||||
max_14_days_4 = dataframe['highest_4_1d']
|
||||
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
|
||||
@@ -773,7 +855,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# max_min = max_14_days / min_14_days
|
||||
# Stack amount ajusté price=2473.47 min_max=0.15058074985054215 percent=0.8379141364642171 amount=20.0
|
||||
|
||||
adjusted_stake_amount = max(base_stake_amount / 2.5, min(100, base_stake_amount * percent_4))
|
||||
adjusted_stake_amount = 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
|
||||
@@ -1236,3 +1318,13 @@ class Zeus_8_3_2_B_4_2(IStrategy):
|
||||
# print(asks_with_sma)
|
||||
|
||||
return asks_with_sma, bids_with_sma
|
||||
|
||||
def calculateUpDownPct(self, dataframe, key):
|
||||
down_pct_values = np.full(len(dataframe), np.nan)
|
||||
# Remplir la colonne avec les bons calculs
|
||||
for i in range(len(dataframe)):
|
||||
shift_value = abs(int(dataframe[key].iloc[i])) # Récupérer le shift actuel
|
||||
if i - shift_value > 1: # Vérifier que le shift ne dépasse pas l'index
|
||||
down_pct_values[i] = 100 * (dataframe['close'].iloc[i] - dataframe['close'].iloc[i - shift_value]) / \
|
||||
dataframe['close'].iloc[i - shift_value]
|
||||
return down_pct_values
|
||||
|
||||
69
tools/chute.py
Normal file
69
tools/chute.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import pandas as pd
|
||||
|
||||
|
||||
def detect_btc_crashes_and_rebounds(df, drop_threshold=-10, rebound_threshold=5):
|
||||
"""
|
||||
Identifie les plus grosses chutes du BTC et le rebond suivant.
|
||||
|
||||
Paramètres :
|
||||
- df : DataFrame contenant une colonne 'close' avec les prix du BTC.
|
||||
- drop_threshold : Seuil de chute en % (ex: -10 pour une chute > 10%).
|
||||
- rebound_threshold : Seuil de rebond en % après la chute.
|
||||
|
||||
Retourne :
|
||||
- Une liste des chutes avec le pourcentage de rebond correspondant.
|
||||
"""
|
||||
df['return'] = df['close'].pct_change() * 100 # Variation en %
|
||||
crashes = []
|
||||
|
||||
in_crash = False
|
||||
crash_start, crash_end, bottom, rebound_end = None, None, None, None
|
||||
|
||||
for i in range(1, len(df)):
|
||||
change = df.loc[i, 'return']
|
||||
|
||||
# Début d'une chute
|
||||
if change < drop_threshold and not in_crash:
|
||||
crash_start = i - 1
|
||||
in_crash = True
|
||||
|
||||
# En pleine chute, trouver le creux
|
||||
if in_crash:
|
||||
if bottom is None or df.loc[i, 'close'] < df.loc[bottom, 'close']:
|
||||
bottom = i
|
||||
|
||||
# Fin de la chute et début du rebond
|
||||
if in_crash and change > 0:
|
||||
crash_end = i
|
||||
|
||||
# Identifier un rebond
|
||||
if in_crash and crash_end:
|
||||
rebound_percent = (df.loc[i, 'close'] - df.loc[bottom, 'close']) / df.loc[bottom, 'close'] * 100
|
||||
if rebound_percent > rebound_threshold:
|
||||
rebound_end = i
|
||||
crashes.append({
|
||||
'crash_start': df.index[crash_start],
|
||||
'crash_end': df.index[crash_end],
|
||||
'bottom': df.index[bottom],
|
||||
'rebound_end': df.index[rebound_end],
|
||||
'drop_percent': (df.loc[bottom, 'close'] - df.loc[crash_start, 'close']) / df.loc[
|
||||
crash_start, 'close'] * 100,
|
||||
'rebound_percent': rebound_percent
|
||||
})
|
||||
in_crash = False # Reset pour détecter une nouvelle chute
|
||||
|
||||
return crashes
|
||||
|
||||
import yfinance as yf
|
||||
|
||||
df = yf.download("BTC-USD", start="2020-01-01", end="2025-01-01", interval="1d")
|
||||
df.to_csv("btc_prices.csv")
|
||||
print("Données enregistrées !")
|
||||
|
||||
|
||||
# Exemple d'utilisation avec un DataFrame BTC (OHLCV)
|
||||
df = pd.read_csv("btc_prices.csv", parse_dates=["date"], index_col="date")
|
||||
crashes = detect_btc_crashes_and_rebounds(df)
|
||||
|
||||
for crash in crashes:
|
||||
print(crash)
|
||||
Reference in New Issue
Block a user