synchronise HeikinAshi

This commit is contained in:
Jérôme Delacotte
2025-03-22 17:54:06 +01:00
parent 59daa1af70
commit 117d466722
3 changed files with 478 additions and 250 deletions

View File

@@ -39,28 +39,6 @@ def normalize(df):
df = (df - df.min()) / (df.max() - df.min())
return df
def get_limit_from_config(section, pair):
file_path = '/HOME/home/souti/freqtrade2/user_data/strategies/Zeus_8_3_2_B_4_2.txt'
# Créez un objet ConfigParser
config = configparser.ConfigParser()
try:
# Lisez le fichier avec les valeurs
config.read(file_path)
# Vérifiez si la section existe
if config.has_section(section):
# Obtenez les valeurs à partir de la section et de la clé (pair)
limit = config.get(section, pair)
return limit
else:
raise ValueError(f"La section '{section}' n'existe pas dans le fichier de configuration.")
except Exception as e:
print(f"Erreur lors de la lecture du fichier de configuration : {e}")
return None
class Zeus_8_3_2_B_4_2(IStrategy):
levels = [1, 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
@@ -198,14 +176,14 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# hard stoploss profit
sell_allow_decrease = DecimalParameter(0.005, 0.02, default=0.2, decimals=2, space='sell', optimize=True, load=True)
pHSL = DecimalParameter(-0.200, -0.040, default=-0.08, decimals=3, space='sell', optimize=False, load=True)
# profit threshold 1, trigger point, SL_1 is used
pPF_1 = DecimalParameter(0.008, 0.020, default=0.016, decimals=3, space='sell', optimize=True, load=True)
pSL_1 = DecimalParameter(0.008, 0.020, default=0.011, decimals=3, space='sell', optimize=True, load=True)
# profit threshold 2, SL_2 is used
pPF_2 = DecimalParameter(0.040, 0.100, default=0.080, decimals=3, space='sell', optimize=True, load=True)
pSL_2 = DecimalParameter(0.020, 0.070, default=0.040, decimals=3, space='sell', optimize=True, load=True)
# pHSL = DecimalParameter(-0.200, -0.040, default=-0.08, decimals=3, space='sell', optimize=False, load=True)
# # profit threshold 1, trigger point, SL_1 is used
# pPF_1 = DecimalParameter(0.008, 0.020, default=0.016, decimals=3, space='sell', optimize=True, load=True)
# pSL_1 = DecimalParameter(0.008, 0.020, default=0.011, decimals=3, space='sell', optimize=True, load=True)
#
# # profit threshold 2, SL_2 is used
# pPF_2 = DecimalParameter(0.040, 0.100, default=0.080, decimals=3, space='sell', optimize=True, load=True)
# pSL_2 = DecimalParameter(0.020, 0.070, default=0.040, decimals=3, space='sell', optimize=True, load=True)
def min_max_scaling(self, series: pd.Series) -> pd.Series:
"""Normaliser les données en les ramenant entre 0 et 100."""
@@ -223,18 +201,15 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# filled_buys = trade.select_filled_orders('buy')
# count_buys = len(filled_buys)
print('entry_tag' + str(entry_tag))
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
# last_candle_12 = dataframe.iloc[-13].squeeze()
limit = get_limit_from_config('Achats', pair)
# allow_to_buy = True #(not self.stop_all) #& (not self.all_down)
allow_to_buy = True # (rate <= float(limit)) | (entry_tag == 'force_entry')
# allow_to_buy = rate <= dataframe['lbp_3']
self.trades = list()
dispo = round(self.wallets.get_available_stake_amount())
logger.info(f"BUY {pair} allow_to_buy {allow_to_buy} limit={limit} Buy {entry_tag} {current_time} dispo={dispo}")
print(f"BUY {pair} {entry_tag} {current_time} allow_to_buy={allow_to_buy} dispo={dispo}")
return allow_to_buy
@@ -242,23 +217,17 @@ class Zeus_8_3_2_B_4_2(IStrategy):
time_in_force: str,
exit_reason: str, current_time, **kwargs, ) -> bool:
# allow_to_sell = (minutes > 30)
limit = get_limit_from_config('Ventes', pair)
dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
last_candle = dataframe.iloc[-1].squeeze()
allow_to_sell = (last_candle['percent'] < 0) # rate > float(limit)
string = ""
allow_to_sell = (last_candle['percent'] < 0)
if allow_to_sell:
self.trades = list()
logger.info('Sell ' + exit_reason + ' ' + str(current_time) + ' ' + pair + " dispo=" + str(
round(self.wallets.get_available_stake_amount())) # "+ str(amount) + ' ' + str(rate)
+ " open_rate=" + str(trade.open_rate) + " rate=" + str(rate) + " profit=" + str(
trade.calc_profit(rate, amount))
+ " " + string)
# del self.max_profit_pairs[pair]
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:
logger.info('Cancel Sell ' + exit_reason + ' ' + str(current_time) + ' ' + pair)
print('Cancel Sell ' + exit_reason + ' ' + str(current_time) + ' ' + pair)
return (allow_to_sell) | (exit_reason == 'force_exit')
def custom_stake_amount(self, pair: str, current_time: datetime, current_rate: float,
@@ -269,83 +238,10 @@ class Zeus_8_3_2_B_4_2(IStrategy):
current_candle = dataframe.iloc[-1].squeeze()
adjusted_stake_amount = self.adjust_stake_amount(pair, current_candle)
logger.info(f"{pair} adjusted_stake_amount{adjusted_stake_amount}")
# print(f"{pair} adjusted_stake_amount{adjusted_stake_amount}")
# Use default stake amount.
return adjusted_stake_amount
#
# def custom_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
# current_rate: float, current_profit: float, **kwargs) -> float:
#
# # # hard stoploss profit
# # HSL = self.pHSL.value
# # PF_1 = self.pPF_1.value
# # SL_1 = self.pSL_1.value
# # PF_2 = self.pPF_2.value
# # SL_2 = self.pSL_2.value
# #
# # # For profits between PF_1 and PF_2 the stoploss (sl_profit) used is linearly interpolated
# # # between the values of SL_1 and SL_2. For all profits above PL_2 the sl_profit value
# # # rises linearly with current profit, for profits below PF_1 the hard stoploss profit is used.
# #
# # if current_profit > PF_2:
# # sl_profit = SL_2 + (current_profit - PF_2)
# # elif current_profit > PF_1:
# # sl_profit = SL_1 + ((current_profit - PF_1) * (SL_2 - SL_1) / (PF_2 - PF_1))
# # else:
# # sl_profit = HSL
#
# #print(f"entry_tag={trade.entry_tag} max={trade.max_rate} min={trade.min_rate} ")
# if current_profit > 0.0125:
# sl_profit = 0.75 * current_profit # 75% du profit en cours
# else:
# sl_profit = self.pHSL.value # Hard stop-loss
# stoploss = stoploss_from_open(sl_profit, current_profit)
# return stoploss
#
# dataframe, _ = self.dp.get_analyzed_dataframe(pair, self.timeframe)
# last_candle = dataframe.iloc[-1].squeeze()
# limit = get_limit_from_config('Ventes', pair)
#
# print(pair + " " + str(current_rate) + " " + str(limit))
#
# #stop_loss = self.adjust_stop_loss(dataframe.iloc[-1])
#
# #if current_rate < float(limit):
# # return -1
#
# # "pHSL": -0.99,
# # "pPF_1": 0.022,
# # "pSL_1": 0.021,
# # "pPF_2": 0.08,
# # "pSL_2": 0.04,
# #
# # hard stoploss profit
# HSL = self.pHSL.value
# PF_1 = self.pPF_1.value
# SL_1 = self.pSL_1.value
# PF_2 = self.pPF_2.value
# SL_2 = self.pSL_2.value
#
# # For profits between PF_1 and PF_2 the stoploss (sl_profit) used is linearly interpolated
# # between the values of SL_1 and SL_2. For all profits above PL_2 the sl_profit value
# # rises linearly with current profit, for profits below PF_1 the hard stoploss profit is used.
#
# # 0.04
# if current_profit > PF_2:
# # 0.04 + (current_profit - 0.08)
# sl_profit = SL_2 + (current_profit - PF_2)
# # 0.022
# elif current_profit > PF_1:
# # 0.021 + ((current_profit - 0.022) * (0.04 - 0.021) / (0.08 - 0.022))
# sl_profit = SL_1 + ((current_profit - PF_1) * (SL_2 - SL_1) / (PF_2 - PF_1))
# else:
# sl_profit = HSL
#
# slfo = stoploss_from_open(sl_profit, current_profit)
# print('current_profit=' + str(current_profit) + ' stop from open=' + str(slfo))
# return slfo
def custom_exit(self, pair: str, trade: Trade, current_time, current_rate, current_profit, **kwargs):
@@ -360,12 +256,12 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# Calcul du prix cible basé sur l'ATR
atr_take_profit = trade.open_rate + (last_candle['atr'] * 2) # Prendre profit à 2x l'ATR
# logger.info(f"{pair} Custom exit atr_take_profit={atr_take_profit:.4f}")
# print(f"{pair} Custom exit atr_take_profit={atr_take_profit:.4f}")
# if current_rate >= atr_take_profit:
# return 'sell_atr_take_profit'
if (last_candle['percent3'] < -0.002) & (last_candle['percent12'] < 0) & (
current_profit > last_candle['min_max200'] / 2):
current_profit > last_candle['min_max200'] / 3):
self.trades = list()
return 'min_max200'
if (last_candle['percent12'] <= -0.01) & (current_profit >= expected_profit):
@@ -384,9 +280,6 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# Add all ta features
pair = metadata['pair']
dataframe['achats'] = get_limit_from_config('Achats', pair)
dataframe['ventes'] = get_limit_from_config('Ventes', pair)
heikinashi = qtpylib.heikinashi(dataframe)
dataframe['haopen'] = heikinashi['open']
dataframe['haclose'] = heikinashi['close']
@@ -546,27 +439,27 @@ class Zeus_8_3_2_B_4_2(IStrategy):
dataframe['amount'] = amount
print(f"amount= {amount}")
# trades = Trade.get_trades([Trade.is_open is False]).all()
trades = Trade.get_trades_proxy(is_open=False, pair=metadata['pair'])
if trades:
trade = trades[-1]
print('closed trade pair is : ')
print(trade)
dataframe['expected_profit'] = (1 + self.expectedProfit(pair, dataframe.iloc[-1])) * dataframe[
'last_price']
dataframe['lbp'] = dataframe['last_price']
dataframe['lbp_3'] = dataframe['lbp'] * 0.97 # 3
dataframe['lbp_6'] = dataframe['lbp'] * 0.94 # 6
dataframe['lbp_9'] = dataframe['lbp'] * 0.90 # 10
dataframe['lbp_12'] = dataframe['lbp'] * 0.85 # 15
dataframe['lbp_20'] = dataframe['lbp'] * 0.8 # 20
dataframe['fbp'] = trade.open_rate
# else:
# last_trade = self.get_trades(pair=pair).order_by('-close_date').first()
# filled_buys = last_trade.select_filled_orders('buy')
# print(last_trade)
# for buy in filled_buys:
# print(filled_buys)
# # trades = Trade.get_trades([Trade.is_open is False]).all()
# trades = Trade.get_trades_proxy(is_open=False, pair=metadata['pair'])
# if trades:
# trade = trades[-1]
# print('closed trade pair is : ')
# print(trade)
# dataframe['expected_profit'] = (1 + self.expectedProfit(pair, dataframe.iloc[-1])) * dataframe[
# 'last_price']
# dataframe['lbp'] = dataframe['last_price']
# dataframe['lbp_3'] = dataframe['lbp'] * 0.97 # 3
# dataframe['lbp_6'] = dataframe['lbp'] * 0.94 # 6
# dataframe['lbp_9'] = dataframe['lbp'] * 0.90 # 10
# dataframe['lbp_12'] = dataframe['lbp'] * 0.85 # 15
# dataframe['lbp_20'] = dataframe['lbp'] * 0.8 # 20
# dataframe['fbp'] = trade.open_rate
# # else:
# # last_trade = self.get_trades(pair=pair).order_by('-close_date').first()
# # filled_buys = last_trade.select_filled_orders('buy')
# # print(last_trade)
# # for buy in filled_buys:
# # print(filled_buys)
dataframe['buy_level'] = dataframe['lowest_4_average'] * (1 - self.levels[count_buys] / 100)
# ----------------------------------------------------------
@@ -615,7 +508,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
dataframe['amplitude_pct_60'] = dataframe['amplitude_pct'].rolling(60).sum()
# ----------------------------------------------------------
self.getBinanceOrderBook(pair, dataframe)
# self.getBinanceOrderBook(pair, dataframe)
return dataframe
@@ -641,9 +534,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
expected_profit = self.expectedProfit(pair, dataframe.iloc[-1])
# self.getBinanceOrderBook(pair, dataframe)
last_candle = dataframe.iloc[-1].squeeze()
# limit = last_candle['first_price'] * (1 - self.baisse[last_candle['count_buys']] / 100)
# self.updateLastValue(dataframe, 'expected_profit', expected_profit)
print("---------------" + pair + "----------------")
print('adjust stake amount ' + str(self.adjust_stake_amount(pair, dataframe.iloc[-1])))
# print('adjust exit price ' + str(self.adjust_exit_price(dataframe.iloc[-1])))
@@ -772,13 +663,7 @@ class Zeus_8_3_2_B_4_2(IStrategy):
& (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['lbp_3'])
# & (dataframe['haclose'] <= dataframe['lbp_3'])
# & (dataframe['haopen'] < buy_level)
# ), ['enter_long', 'enter_tag']] = (1, 'buy_lbp_3')
dataframe.loc[
(
(dataframe['close'] <= dataframe['lowest_4_average'] * 1.002)
@@ -801,38 +686,26 @@ class Zeus_8_3_2_B_4_2(IStrategy):
return dataframe
# def get_buy_level(self, pair, dataframe):
# limit = get_limit_from_config('Achats', pair)
#
# filled_buys = {}
# for trade in self.trades:
# if trade.pair != pair:
# continue
# filled_buys = trade.select_filled_orders('enter_long')
# print('populate_buy_trend filled_buys : ' + str(len(filled_buys)))
# # Affichez les valeurs
# print(pair, limit)
# # BUY_LEVELS = {
# # 'BTC/USDT': [int(btc_limit), 42600, 41000, 40000, 39000, 38000, 37000, 36000, 35000],
# # 'ETH/USDT': [int(eth_limit), 2290, 1900, 1800, 1700, 1600, 1500, 1400, 1300],
# # 'ETC/USDT': [int(eth_limit), 2290, 1900, 1800, 1700, 1600, 1500, 1400, 1300],
# # 'DOGE/USDT': [int(eth_limit), 2290, 1900, 1800, 1700, 1600, 1500, 1400, 1300],
# # # Ajoutez d'autres paires avec leurs niveaux d'achat ici...
# # }
# count_of_buys = len(filled_buys)
# buy_level = dataframe['lbp'] * (1 - self.levels[count_of_buys] / 100) # float(limit) #BUY_LEVELS.get(pair, [])[0] #dataframe['lbp_3'] #"
# return buy_level
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
return dataframe
def adjust_trade_position(self, trade: Trade, current_time: datetime,
current_rate: float, current_profit: float, min_stake: float,
max_stake: float, **kwargs):
# ne rien faire si ordre deja en cours
if trade.has_open_orders:
return None
if (self.wallets.get_available_stake_amount() < 50): # or trade.stake_amount >= max_stake:
return 0
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
# print(dataframe)
last_candle = dataframe.iloc[-1].squeeze()
last_candle_12 = dataframe.iloc[-13].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())
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
if (len(dataframe) < 1):
return None
@@ -851,25 +724,24 @@ class Zeus_8_3_2_B_4_2(IStrategy):
# else:
# condition = False
# self.protection_nb_buy_lost.value
# limits = ['lbp_3', 'lbp_6', 'lbp_9', 'lbp_12', 'lbp_20']
# limit = last_candle[limits[count_of_buys]]
limit = last_candle['limit']
stake_amount = min(200, self.adjust_stake_amount(pair, last_candle) * self.fibo[count_of_buys])
# print("Adjust " + trade.pair + " time=" + str(current_time) + ' rate=' + str(current_rate) + " buys=" + str(count_of_buys) + " limit=" + str(limit) + " stake=" + str(stake_amount))
# logger.info(
# f"Adjust price={trade.pair} buy={condition} rate={current_rate:.4f} buys={count_of_buys} limit={limit:.4f} stake={stake_amount:.4f}")
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
if (days_since_open > count_of_buys) & (0 < count_of_buys <= max_buys) & (current_rate <= limit) & (last_candle['enter_long'] == 1):
# if (days_since_open > count_of_buys) & (0 < count_of_buys <= max_buys) & (current_rate <= limit) & (last_candle['enter_long'] == 1):
limit_buy = 5
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):
try:
# This then calculates current safety order size
# stake_amount = stake_amount * pow(1.5, count_of_buys)
# print("Effective Adjust " + trade.pair + " time=" + str(current_time) + ' rate=' + str(current_rate) + " buys=" + str(count_of_buys) + " limit=" + str(limit) + " stake=" + str(stake_amount))
logger.info(
print(
f"Adjust {current_time} price={trade.pair} rate={current_rate:.4f} buys={count_of_buys} limit={limit:.4f} stake={stake_amount:.4f}")
return stake_amount
@@ -901,7 +773,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(75, base_stake_amount * percent_4))
adjusted_stake_amount = max(base_stake_amount / 2.5, min(100, base_stake_amount * percent_4))
# if pair in ('BTC/USDT', 'ETH/USDT'):
# if percent_4 > 0.5:
# adjusted_stake_amount = 300
@@ -927,17 +799,17 @@ class Zeus_8_3_2_B_4_2(IStrategy):
#
# return exit_price
def adjust_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
current_rate: float, current_profit: float, **kwargs) -> float:
dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
# print(dataframe)
last_candle = dataframe.iloc[-1].squeeze()
# Utiliser l'ATR pour ajuster le stoploss
atr_stoploss = current_rate - (last_candle['atr'] * 1.5) # Stoploss à 1.5x l'ATR
# Retourner le stoploss dynamique en pourcentage du prix actuel
return (atr_stoploss / current_rate) - 1
# def adjust_stoploss(self, pair: str, trade: 'Trade', current_time: datetime,
# current_rate: float, current_profit: float, **kwargs) -> float:
# dataframe, _ = self.dp.get_analyzed_dataframe(trade.pair, self.timeframe)
# # print(dataframe)
# last_candle = dataframe.iloc[-1].squeeze()
#
# # Utiliser l'ATR pour ajuster le stoploss
# atr_stoploss = current_rate - (last_candle['atr'] * 1.5) # Stoploss à 1.5x l'ATR
#
# # Retourner le stoploss dynamique en pourcentage du prix actuel
# return (atr_stoploss / current_rate) - 1
def expectedProfit(self, pair: str, dataframe: DataFrame):