TEST HYPEROPTS

This commit is contained in:
Jérôme Delacotte
2026-03-07 15:36:28 +01:00
parent 5ce48130f4
commit 2885cf05b1
5 changed files with 1547 additions and 125 deletions

View File

@@ -14,12 +14,7 @@
"trailing_only_offset_is_reached": false "trailing_only_offset_is_reached": false
}, },
"max_open_trades": { "max_open_trades": {
"max_open_trades": 20 "max_open_trades": 1
},
"protection": {
"b30_indicateur": "sma36",
"baisse": 0.3,
"drop_from_last_entry": -0.03
}, },
"buy": { "buy": {
"buy_deriv1_sma12d": -0.04, "buy_deriv1_sma12d": -0.04,
@@ -30,17 +25,25 @@
"buy_deriv2_sma60": -0.001, "buy_deriv2_sma60": -0.001,
"buy_longue": 160, "buy_longue": 160,
"buy_longue_derive": "sma80_deriv1_1d", "buy_longue_derive": "sma80_deriv1_1d",
"start_bear_deriv1": -0.004, "start_bear_deriv1": 0.003,
"start_bear_deriv2": 0.002, "start_bear_deriv2": 0.003,
"start_bear_indicator": "sma80", "start_bear_indicator": "sma24",
"start_bull_deriv1": 0.001, "start_bull_deriv1": -0.005,
"start_bull_deriv2": -0.002, "start_bull_deriv2": 0.0,
"start_bull_indicator": "sma120" "start_bull_indicator": "sma3"
},
"protection": {
"drop_from_last_entry": -0.03,
"mises": 1
}, },
"sell": { "sell": {
"sell_score_indicator": "sma24_score" "b30_indicateur": "sma36",
"baisse": 0.25,
"sell_force_sell": -0.169,
"sell_indicator": "sma3",
"sell_score_indicator": "sma3_score"
} }
}, },
"ft_stratparam_v": 1, "ft_stratparam_v": 1,
"export_time": "2026-02-28 17:28:20.867470+00:00" "export_time": "2026-03-07 11:58:51.712499+00:00"
} }

View File

@@ -216,8 +216,12 @@ class Empty(IStrategy):
# baisses = list() # baisses = list()
# for i in range(0, 0.5, 0.05): # for i in range(0, 0.5, 0.05):
# baisses.append(i) # baisses.append(i)
baisse = DecimalParameter(0, 0.5, decimals=2, default=0.3, space='protection', optimize=True, load=True) mises = IntParameter(1, 10, default=1, space='protection')
b30_indicateur = CategoricalParameter(sma_indicators_h, default="sma36", space='protection', optimize=True, load=True) sell_force_sell = DecimalParameter(-0.2, 0, decimals=3, default=-0.02, space='sell')
sell_indicator = CategoricalParameter(sma_indicators, default="sma36", space='sell', optimize=True, load=True)
baisse = DecimalParameter(0.1, 0.5, decimals=2, default=0.3, space='sell', optimize=True, load=True)
b30_indicateur = CategoricalParameter(sma_indicators_h, default="sma36", space='sell', optimize=True, load=True)
# lost_indicator = CategoricalParameter(sma_deriv1_indicators, default="sma5_deriv1", space='protection') # lost_indicator = CategoricalParameter(sma_deriv1_indicators, default="sma5_deriv1", space='protection')
@@ -250,10 +254,10 @@ class Empty(IStrategy):
# sl_max = self.wallets.get_available_stake_amount() / 2 # sl_max = self.wallets.get_available_stake_amount() / 2
# #
# amount = sl_min + (1 - range_pos) * (sl_max - sl_min) # amount = sl_min + (1 - range_pos) * (sl_max - sl_min)
if last_candle['enter_tag'] == 'fall': if last_candle['enter_tag'] in ['fall', 'bear', 'Force', 'Range-']:
amount = self.wallets.get_available_stake_amount() / 5 amount = self.wallets.get_available_stake_amount() / 5
else: else:
amount = self.wallets.get_available_stake_amount() # / (2 * self.pairs[pair]['count_of_lost'] + 1) amount = self.wallets.get_available_stake_amount() / self.mises.value # / (2 * self.pairs[pair]['count_of_lost'] + 1)
# factor = 1 # factor = 1
# #
@@ -364,6 +368,8 @@ class Empty(IStrategy):
last_candle_2 = dataframe.iloc[-2].squeeze() last_candle_2 = dataframe.iloc[-2].squeeze()
last_candle_3 = dataframe.iloc[-3].squeeze() last_candle_3 = dataframe.iloc[-3].squeeze()
if entry_tag == 'Range-':
self.pairs[pair]['count_of_lost'] = 0
if entry_tag == 'Force': if entry_tag == 'Force':
if self.pairs[pair]['count_of_lost'] >= 1: if self.pairs[pair]['count_of_lost'] >= 1:
self.pairs[pair]['count_of_lost'] = 0 self.pairs[pair]['count_of_lost'] = 0
@@ -546,15 +552,15 @@ class Empty(IStrategy):
# buys=count_of_buys, # buys=count_of_buys,
# stake=0 # stake=0
# ) # )
# if self.pairs[pair]['current_trade'].enter_tag == 'fall': if self.pairs[pair]['current_trade'].enter_tag in ['bear', 'Force', 'Range-']:
# if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60'] and self.wallets.get_available_stake_amount() < 50: if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60'] and self.wallets.get_available_stake_amount() < 50:
# self.pairs[pair]['force_sell'] = True self.pairs[pair]['force_sell'] = True
# return 'sma60' return 'smaBF'
# else: else:
if current_profit < self.sell_force_sell.value \
if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60']: and last_candle[f"close"] <= last_candle[self.sell_indicator.value]:
self.pairs[pair]['force_sell'] = True self.pairs[pair]['force_sell'] = True
return 'sma60' return 'sma'
if profit > max(5, expected_profit) and \ if profit > max(5, expected_profit) and \
(baisse > self.baisse.value and last_candle[f"close"] <= last_candle[self.b30_indicateur.value]) \ (baisse > self.baisse.value and last_candle[f"close"] <= last_candle[self.b30_indicateur.value]) \
@@ -743,8 +749,8 @@ class Empty(IStrategy):
# ##################################################################################### # #####################################################################################
# CA MONTE !! # CA MONTE !!
# ##################################################################################### # #####################################################################################
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv1_1d" ] > self.start_bull_deriv1.value) conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv1_1d" ] > self.start_bull_deriv1.value)
# conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv2_1d"] > self.start_bull_deriv2.value) conditions.append(dataframe[f"{self.start_bull_indicator.value}_deriv2_1d"] > self.start_bull_deriv2.value)
conditions.append(dataframe['sma12_deriv1'] > self.buy_deriv1_sma60.value) conditions.append(dataframe['sma12_deriv1'] > self.buy_deriv1_sma60.value)
conditions.append(dataframe['sma5_deriv1_1d'] > self.buy_deriv1_sma5d.value) conditions.append(dataframe['sma5_deriv1_1d'] > self.buy_deriv1_sma5d.value)
conditions.append(dataframe['sma12_deriv1_1d'] > self.buy_deriv1_sma12d.value) conditions.append(dataframe['sma12_deriv1_1d'] > self.buy_deriv1_sma12d.value)
@@ -791,11 +797,11 @@ class Empty(IStrategy):
conditions.append(dataframe['mid_smooth12'] > dataframe['mid_smooth12'].shift(1)) conditions.append(dataframe['mid_smooth12'] > dataframe['mid_smooth12'].shift(1))
conditions.append(dataframe['sma100_deriv1_1d'] > 0) conditions.append(dataframe['sma100_deriv1_1d'] > 0)
conditions.append(dataframe[f"range_pos"] < 0.01) conditions.append(dataframe[f"range_pos"] < 0.01)
if conditions: # if conditions:
dataframe.loc[ # dataframe.loc[
reduce(lambda x, y: x & y, conditions), # reduce(lambda x, y: x & y, conditions),
['enter_long', 'enter_tag'] # ['enter_long', 'enter_tag']
] = (1, 'dist') # ] = (1, 'dist')
# ##################################################################################### # #####################################################################################
# CA BAISSE !! # CA BAISSE !!
@@ -866,16 +872,17 @@ class Empty(IStrategy):
conditions.append(dataframe['sma12_deriv1_1d'] > 0.0) conditions.append(dataframe['sma12_deriv1_1d'] > 0.0)
conditions.append(dataframe['sma24_deriv1_1d'] > 0.0) conditions.append(dataframe['sma24_deriv1_1d'] > 0.0)
conditions.append(dataframe['sma100_deriv1_1d'] > 0.0) conditions.append(dataframe['sma100_deriv1_1d'] > 0.0)
conditions.append(dataframe[f"range_pos"] < 0.025)
# conditions.append(dataframe['sma12_deriv1_1d'] > 0.0) # conditions.append(dataframe['sma12_deriv1_1d'] > 0.0)
# # conditions.append(dataframe['close_1d'] < dataframe[f'sma{self.buy_longue.value}_1d']) # # conditions.append(dataframe['close_1d'] < dataframe[f'sma{self.buy_longue.value}_1d'])
# # conditions.append(dataframe['has_cross_min'].rolling(6).max() == 1) # # conditions.append(dataframe['has_cross_min'].rolling(6).max() == 1)
# # conditions.append(dataframe['mid_smooth5'] > dataframe['mid_smooth5'].shift(1)) # # conditions.append(dataframe['mid_smooth5'] > dataframe['mid_smooth5'].shift(1))
# conditions.append(dataframe['min12'] == dataframe['min12'].shift(3)) # conditions.append(dataframe['min12'] == dataframe['min12'].shift(3))
# conditions.append((dataframe['percent24'] < -0.025) | (dataframe['percent12'] < -0.025)) # conditions.append((dataframe['percent24'] < -0.025) | (dataframe['percent12'] < -0.025))
dataframe.loc[ # dataframe.loc[
reduce(lambda x, y: x & y, conditions), # reduce(lambda x, y: x & y, conditions),
['enter_long', 'enter_tag'] # ['enter_long', 'enter_tag']
] = (1, 'Rise') # ] = (1, 'Rise')
# conditions = list() # conditions = list()
# conditions.append(dataframe['has_cross_min_6'] == True) # conditions.append(dataframe['has_cross_min_6'] == True)
@@ -885,6 +892,14 @@ class Empty(IStrategy):
# ['enter_long', 'enter_tag'] # ['enter_long', 'enter_tag']
# ] = (1, 'Force') # ] = (1, 'Force')
# conditions = list()
# conditions.append(dataframe['range_pos'] < -0.03)
# conditions.append(dataframe['min36'] == dataframe['min36'].shift(3))
# dataframe.loc[
# reduce(lambda x, y: x & y, conditions),
# ['enter_long', 'enter_tag']
# ] = (1, 'Range-')
return dataframe return dataframe
def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame: def populate_sell_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:

46
Empty5m.json Normal file
View File

@@ -0,0 +1,46 @@
{
"strategy_name": "Empty5m",
"params": {
"roi": {
"0": 5
},
"stoploss": {
"stoploss": -1.0
},
"trailing": {
"trailing_stop": false,
"trailing_stop_positive": null,
"trailing_stop_positive_offset": 0.0,
"trailing_only_offset_is_reached": false
},
"max_open_trades": {
"max_open_trades": 1
},
"buy": {
"buy_longue_derive": "sma60_deriv1_1h",
"buy_deriv1_sma12d": 0.0002,
"buy_deriv1_sma5d": -0.0006,
"buy_deriv1_sma60": -0.0003,
"buy_longue": 180,
"start_bear_deriv1": 0.005,
"start_bear_deriv2": -0.003,
"start_bear_indicator": "sma60",
"start_bull_deriv1": -0.001,
"start_bull_deriv2": 0.0,
"start_bull_indicator": "sma12"
},
"protection": {
"drop_from_last_entry": -0.03,
"mises_bear": 5,
"mises_bull": 1
},
"sell": {
"b30_indicateur": "sma24",
"baisse": 0.14,
"sell_force_sell": -0.135,
"sell_indicator": "sma12"
}
},
"ft_stratparam_v": 1,
"export_time": "2026-03-07 14:31:15.874478+00:00"
}

1317
Empty5m.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -852,28 +852,28 @@ class FrictradeLearning(IStrategy):
short_pair = self.getShortName(pair) short_pair = self.getShortName(pair)
# path=f"user_data/strategies/plots/{short_pair}/" # path=f"user_data/strategies/plots/{short_pair}/"
self.model = joblib.load(f"{self.path}/{short_pair}_rf_model.pkl") # self.model = joblib.load(f"{self.path}/{short_pair}_rf_model.pkl")
#
# Préparer les features pour la prédiction # # Préparer les features pour la prédiction
features = dataframe[self.model_indicators].fillna(0) # features = dataframe[self.model_indicators].fillna(0)
#
# Prédiction : probabilité que le prix monte # # Prédiction : probabilité que le prix monte
#
# Affichage des colonnes intérressantes dans le model # # Affichage des colonnes intérressantes dans le model
features_pruned, kept_features = self.prune_features( # features_pruned, kept_features = self.prune_features(
model=self.model, # model=self.model,
dataframe=dataframe, # dataframe=dataframe,
feature_columns=self.model_indicators, # feature_columns=self.model_indicators,
importance_threshold=0.005 # enlever features < % importance # importance_threshold=0.005 # enlever features < % importance
) # )
#
probs = self.model.predict_proba(features)[:, 1] # probs = self.model.predict_proba(features)[:, 1]
#
# Sauvegarder la probabilité pour lanalyse # # Sauvegarder la probabilité pour lanalyse
dataframe['ml_prob'] = probs # dataframe['ml_prob'] = probs
#
if False and self.dp.runmode.value in ('backtest'): # if False and self.dp.runmode.value in ('backtest'):
self.inspect_model(self.model) # self.inspect_model(self.model)
# #
# absolute_min = dataframe['absolute_min'].min() # absolute_min = dataframe['absolute_min'].min()
@@ -910,6 +910,9 @@ class FrictradeLearning(IStrategy):
horizon = 180 horizon = 180
self.calculateScores(dataframe, horizon) self.calculateScores(dataframe, horizon)
dataframe['cross_sma60'] = qtpylib.crossed_below(dataframe["sma12"], dataframe['sma60'])
# val = 90000 # val = 90000
# steps = 12 # steps = 12
# [0.018, 0.022, 0.025, 0.028, 0.032, 0.035, 0.038, 0.042, 0.045, 0.048, 0.052, 0.055] # [0.018, 0.022, 0.025, 0.028, 0.032, 0.035, 0.038, 0.042, 0.045, 0.048, 0.052, 0.055]
@@ -1066,22 +1069,34 @@ class FrictradeLearning(IStrategy):
# threshold = 0.4 #self.buy_threshold # ex: 0.80 or 1.10 depending on your model # threshold = 0.4 #self.buy_threshold # ex: 0.80 or 1.10 depending on your model
# 20% des signaux les plus forts # 20% des signaux les plus forts
threshold = np.percentile(dataframe["ml_prob"], 80) # threshold = np.percentile(dataframe["ml_prob"], 80)
# Buy = prediction > threshold # Buy = prediction > threshold
dataframe["buy"] = 0 dataframe["buy"] = 0
# dataframe.loc[
# # (dataframe["ml_prob"].shift(1) < dataframe["ml_prob"])
# (dataframe['sma60_deriv1'] > -0.0000)
# & (dataframe['sma12_deriv1'] > 0)
# & (dataframe['sma12'] < dataframe['sma60'])
# # & (dataframe['rsi'] < 77)
# # & (dataframe['heat_score_1h'] < 0.5)
# # & (dataframe['sma180_deriv1'] > 0)
# # & (dataframe['open'] < dataframe['max180'] * 0.997)
# # & (dataframe['min180'].shift(3) == dataframe['min180'])
# , ['enter_long', 'enter_tag']
# ] = (1, f"future")
dataframe.loc[ dataframe.loc[
(dataframe["ml_prob"].shift(1) < dataframe["ml_prob"]) # (dataframe["ml_prob"].shift(1) < dataframe["ml_prob"])
& (dataframe['sma24_deriv1'] > 0) (
& (dataframe['sma5_deriv1'] > 0) (dataframe['close'].shift(3) < dataframe['min180'].shift(3)) |
& (dataframe['sma5_deriv2'] > 0) (dataframe['close'].shift(4) < dataframe['min180'].shift(4)) |
& (dataframe['rsi'] < 77) (dataframe['close'].shift(5) < dataframe['min180'].shift(5))
& (dataframe['heat_score_1h'] < 0.5) )
# & (dataframe['sma180_deriv1'] > 0) & (dataframe['hapercent'] > 0)
# & (dataframe['open'] < dataframe['max180'] * 0.997)
# & (dataframe['min180'].shift(3) == dataframe['min180'])
, ['enter_long', 'enter_tag'] , ['enter_long', 'enter_tag']
] = (1, f"future") ] = (1, f"min180")
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.01, np.nan) dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.01, np.nan)
return dataframe return dataframe
@@ -1210,18 +1225,14 @@ class FrictradeLearning(IStrategy):
return max(round(y), 1) # évite les valeurs négatives return max(round(y), 1) # évite les valeurs négatives
def adjust_stake_amount(self, pair: str, last_candle: DataFrame): def adjust_stake_amount(self, pair: str, last_candle: DataFrame):
if (self.pairs[pair]['first_amount'] > 0):
if self.pairs[pair]['first_amount'] > 0: amount = min(self.wallets.get_available_stake_amount(), self.pairs[pair]['first_amount'])
mises = self.pairs[pair]['mises'] else:
count = self.pairs[pair]['count_of_buys'] - self.pairs[pair]['has_gain'] if last_candle['enter_tag'] in ['fall', 'bear', 'Force', 'Range-']:
return mises[count] if count < len(mises) else self.pairs[pair]['first_amount'] amount = self.wallets.get_available_stake_amount() / 5
else:
ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle)) amount = self.wallets.get_available_stake_amount() / 3# / (2 * self.pairs[pair]['count_of_lost'] + 1)
full, mises, steps = self.calculateMises(pair, ath, last_candle['mid']) return min(amount, self.wallets.get_available_stake_amount())
base_stake = mises[self.pairs[pair]['count_of_buys']] if self.pairs[pair]['count_of_buys'] < len(
mises) else full / (steps * 2)
return base_stake
def calculateMises(self, pair, ath, val): def calculateMises(self, pair, ath, val):
# ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle)) # ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle))
@@ -1515,8 +1526,19 @@ class FrictradeLearning(IStrategy):
# buys=count_of_buys, # buys=count_of_buys,
# stake=0 # stake=0
# ) # )
if profit < 0.65: #5 or last_candle['rsi_1d'] < 30:
return None if current_profit < - 0.02 and last_candle[f"close"] <= last_candle['sma60']:
self.pairs[pair]['force_sell'] = True
return 'sma60'
if profit > 5 and \
(baisse > 0.25 and last_candle[f"close"] <= last_candle['sma24']) \
and last_candle['hapercent'] <0 :
self.pairs[pair]['force_sell'] = True
return 'B30'
if profit > 0 and last_candle['cross_sma60']: #5 or last_candle['rsi_1d'] < 30:
return 'Cross'
if last_candle['max_rsi_24'] > 88 and last_candle['hapercent'] < 0\ if last_candle['max_rsi_24'] > 88 and last_candle['hapercent'] < 0\
and last_candle['sma5_deriv2'] < -0.1: and last_candle['sma5_deriv2'] < -0.1:
@@ -1535,44 +1557,48 @@ class FrictradeLearning(IStrategy):
# if (minutes > 1440 and last_candle['sma60_deriv1'] > 0) : # if (minutes > 1440 and last_candle['sma60_deriv1'] > 0) :
# return None # return None
# ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? ----- # # ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? -----
if current_trailing_only_offset_is_reached and max_profit > current_trailing_stop_positive_offset: # if current_trailing_only_offset_is_reached and max_profit > current_trailing_stop_positive_offset:
# Max profit pas atteint ET perte < 2 * current_trailing_stop_positive # # Max profit pas atteint ET perte < 2 * current_trailing_stop_positive
if profit > limit: # 2 * current_trailing_stop_positive: # if profit > limit: # 2 * current_trailing_stop_positive:
print( # print(
f"{current_time} trailing non atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} " # f"{current_time} trailing non atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} "
f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}") # f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}")
return None # ne pas activer le trailing encore # return None # ne pas activer le trailing encore
else: # else:
print( # print(
f"{current_time} trailing atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} " # f"{current_time} trailing atteint trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} "
f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}") # f"max={round(max_profit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} baisse={round(baisse,2)}")
else: # else:
# print( # # print(
# f"1 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} " # # f"1 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
# f"limit={round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)}" # # f"limit={round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)}"
# f" baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}") # # f" baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}")
#
# return None
# # Sinon : trailing actif dès le début
#
# # ----- 6) Condition de vente -----
# if 0 < profit <= trailing_stop: # and last_candle['mid'] < last_candle['sma5']: # and profit > current_trailing_stop_positive_offset:
# self.pairs[pair]['force_buy'] = True
# print(
# f"{current_time} Condition de vente trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
# f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} "
# f"baisse={round(baisse,2)}")
#
# return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}"
return None # print(
# Sinon : trailing actif dès le début # f"2 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
# f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} "
# ----- 6) Condition de vente ----- # f"baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}")
if 0 < profit <= trailing_stop: # and last_candle['mid'] < last_candle['sma5']: # and profit > current_trailing_stop_positive_offset:
self.pairs[pair]['force_buy'] = True
print(
f"{current_time} Condition de vente trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} "
f"baisse={round(baisse,2)}")
return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}"
return None
print( print(
f"2 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} " f"2 - {current_time} trailing_stop={round(trailing_stop, 4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} " f"{round(limit, 4)} offset={round(current_trailing_stop_positive_offset, 4)} "
f"baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}") f"baisse={round(baisse,2)} {round(last_candle['sma180_deriv1'], 4)} {round(last_candle['sma60_deriv1'], 4)} {round(last_candle['sma24_deriv1'], 4)}")
return None
def informative_pairs(self): def informative_pairs(self):
# get access to all pairs available in whitelist. # get access to all pairs available in whitelist.
pairs = self.dp.current_whitelist() pairs = self.dp.current_whitelist()
@@ -2440,6 +2466,21 @@ class FrictradeLearning(IStrategy):
# d2s_col = f"{name}{suffixe}_deriv2_smooth" # d2s_col = f"{name}{suffixe}_deriv2_smooth"
tendency_col = f"{name}{suffixe}_state" tendency_col = f"{name}{suffixe}_state"
d1_col = f"{name}{suffixe}_deriv1"
d2_col = f"{name}{suffixe}_deriv2"
tendency_col = f"{name}{suffixe}_state"
series = dataframe[f"{name}{suffixe}"]
d1 = series.diff()
d2 = d1.diff()
pmin = int(ema_period / 3)
cond_bas = (d1.rolling(pmin).mean() > d1.rolling(ema_period).mean())
cond_haut = (d1.rolling(pmin).mean() < d1.rolling(ema_period).mean())
dataframe[d1_col] = (dataframe[name] - dataframe[name].shift(3)) / dataframe[name].shift(3)
dataframe[d2_col] = (dataframe[d1_col] - dataframe[d1_col].shift(1))
factor1 = 100 * (ema_period / 5) factor1 = 100 * (ema_period / 5)
factor2 = 10 * (ema_period / 5) factor2 = 10 * (ema_period / 5)
@@ -2450,15 +2491,15 @@ class FrictradeLearning(IStrategy):
dataframe[f"{name}{suffixe}_dist"] = (dataframe['close'] - dataframe[f"{name}{suffixe}"]) / dataframe[ dataframe[f"{name}{suffixe}_dist"] = (dataframe['close'] - dataframe[f"{name}{suffixe}"]) / dataframe[
f"{name}{suffixe}"] f"{name}{suffixe}"]
# dérivée relative simple # # dérivée relative simple
dataframe[d1_col] = (dataframe[name] - dataframe[name].shift(1)) / dataframe[name].shift(1) # dataframe[d1_col] = (dataframe[name] - dataframe[name].shift(1)) / dataframe[name].shift(1)
# lissage EMA # # lissage EMA
dataframe[d1_col] = factor1 * dataframe[d1_col].ewm(span=ema_period, adjust=False).mean() # dataframe[d1_col] = factor1 * dataframe[d1_col].ewm(span=ema_period, adjust=False).mean()
#
# dataframe[d1_col] = dataframe[d1_col].rolling(window=ema_period, center=True).median() # # dataframe[d1_col] = dataframe[d1_col].rolling(window=ema_period, center=True).median()
#
dataframe[d2_col] = dataframe[d1_col] - dataframe[d1_col].shift(1) # dataframe[d2_col] = dataframe[d1_col] - dataframe[d1_col].shift(1)
dataframe[d2_col] = factor2 * dataframe[d2_col].ewm(span=ema_period, adjust=False).mean() # dataframe[d2_col] = factor2 * dataframe[d2_col].ewm(span=ema_period, adjust=False).mean()
# epsilon adaptatif via rolling percentile # epsilon adaptatif via rolling percentile
p_low_d1 = dataframe[d1_col].rolling(window=window, min_periods=1).quantile(0.05) p_low_d1 = dataframe[d1_col].rolling(window=window, min_periods=1).quantile(0.05)