Frictrade progression adjust exponentielle / correction trailing / Hyperopt
This commit is contained in:
27
FrictradeLearning.json
Normal file
27
FrictradeLearning.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"strategy_name": "FrictradeLearning",
|
||||
"params": {
|
||||
"roi": {
|
||||
"0": 10
|
||||
},
|
||||
"stoploss": {
|
||||
"stoploss": -1.0
|
||||
},
|
||||
"trailing": {
|
||||
"trailing_stop": false,
|
||||
"trailing_stop_positive": 0.15,
|
||||
"trailing_stop_positive_offset": 1,
|
||||
"trailing_only_offset_is_reached": true
|
||||
},
|
||||
"max_open_trades": {
|
||||
"max_open_trades": 80
|
||||
},
|
||||
"protection": {
|
||||
"allow_decrease_rate": 0.8,
|
||||
"first_adjust_param": 0.004,
|
||||
"max_steps": 15
|
||||
}
|
||||
},
|
||||
"ft_stratparam_v": 1,
|
||||
"export_time": "2025-12-07 21:51:14.946942+00:00"
|
||||
}
|
||||
@@ -120,7 +120,11 @@ class FrictradeLearning(IStrategy):
|
||||
-18: 0.30,
|
||||
}
|
||||
|
||||
allow_decrease_rate = 0.4
|
||||
allow_decrease_rate = DecimalParameter(0.1, 0.8, decimals=1, default=0.4, space='protection')
|
||||
first_adjust_param = DecimalParameter(0.001, 0.01, decimals=3, default=0.003, space='protection')
|
||||
max_steps = IntParameter(10, 50, default=40, space='protection', optimize=True, load=True)
|
||||
|
||||
hours_force = IntParameter(1, 48, default=24, space='buy', optimize=True, load=True)
|
||||
|
||||
# ROI table:
|
||||
minimal_roi = {
|
||||
@@ -139,8 +143,6 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
# Buy hypers
|
||||
timeframe = '1m'
|
||||
max_open_trades = 5
|
||||
max_amount = 40
|
||||
|
||||
parameters = {}
|
||||
# DCA config
|
||||
@@ -252,12 +254,18 @@ class FrictradeLearning(IStrategy):
|
||||
# d = n / (p * (p - 1)) # incrément
|
||||
# return [round(a + i * d, 3) for i in range(p)]
|
||||
def progressive_parts(total, n, first):
|
||||
# solve for r
|
||||
# S = first * (r^n - 1)/(r - 1) = total
|
||||
# numeric solving
|
||||
|
||||
# conditions impossibles → on évite le solveur
|
||||
if total <= 0 or first <= 0 or n <= 1:
|
||||
return [0] * n
|
||||
|
||||
f = lambda r: first * (r ** n - 1) / (r - 1) - total
|
||||
r = mp.findroot(f, 1.05) # initial guess
|
||||
|
||||
try:
|
||||
r = mp.findroot(f, 1.2) # 1.2 = plus stable que 1.05
|
||||
except Exception:
|
||||
# fallback en cas d'échec
|
||||
return [first] * n
|
||||
|
||||
parts = [round(first * (r ** k), 4) for k in range(n)]
|
||||
return parts
|
||||
@@ -272,9 +280,9 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
steps = self.approx_value(last_candle['mid'], self.pairs[pair]['last_ath'])
|
||||
self.pairs[pair]['dca_thresholds'] = progressive_parts(
|
||||
(last_candle['mid'] - (self.pairs[pair]['last_ath'] * (1 - self.allow_decrease_rate))) / last_candle['mid'],
|
||||
steps, 0.003)
|
||||
print(f"val={last_candle['mid']} steps={steps} pct={(last_candle['mid'] - (self.pairs[pair]['last_ath'] * (1 - self.allow_decrease_rate))) / last_candle['mid']}")
|
||||
(last_candle['mid'] - (self.pairs[pair]['last_ath'] * (1 - self.allow_decrease_rate.value))) / last_candle['mid'],
|
||||
steps, self.first_adjust_param.value)
|
||||
print(f"val={last_candle['mid']} steps={steps} pct={(last_candle['mid'] - (self.pairs[pair]['last_ath'] * (1 - self.allow_decrease_rate.value))) / last_candle['mid']}")
|
||||
print(self.pairs[pair]['dca_thresholds'])
|
||||
|
||||
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float,
|
||||
@@ -850,8 +858,8 @@ class FrictradeLearning(IStrategy):
|
||||
#
|
||||
# for val in range(90000, 130000, 10000):
|
||||
# steps = self.approx_value(val, 126000)
|
||||
# print(f"val={val} steps={steps} pct={(val - (126000 * (1 - self.allow_decrease_rate))) / val}")
|
||||
# dca = split_ratio_one_third((val - (126000 * (1 - self.allow_decrease_rate))) / 126000, steps)
|
||||
# print(f"val={val} steps={steps} pct={(val - (126000 * (1 - self.allow_decrease_rate.value))) / val}")
|
||||
# dca = split_ratio_one_third((val - (126000 * (1 - self.allow_decrease_rate.value))) / 126000, steps)
|
||||
# print(dca)
|
||||
|
||||
return dataframe
|
||||
@@ -1033,9 +1041,9 @@ class FrictradeLearning(IStrategy):
|
||||
# return adjusted_stake_amount
|
||||
|
||||
def approx_value(self, x, X_max):
|
||||
X_min = X_max * (1 - self.allow_decrease_rate) # 126198 * 0.4 = 75718,8
|
||||
X_min = X_max * (1 - self.allow_decrease_rate.value) # 126198 * 0.4 = 75718,8
|
||||
Y_min = 1
|
||||
Y_max = 40
|
||||
Y_max = self.max_steps.value
|
||||
a = (Y_max - Y_min) / (X_max - X_min) # 39 ÷ (126198 − 126198×0,6) = 0,000772595
|
||||
b = Y_min - a * X_min # 1 − (0,000772595 × 75718,8) = −38
|
||||
y = a * x + b # 0,000772595 * 115000 - 38
|
||||
@@ -1112,7 +1120,9 @@ class FrictradeLearning(IStrategy):
|
||||
if self.pairs[pair]['first_buy']:
|
||||
pct_first = self.getPctFirstBuy(pair, last_candle)
|
||||
|
||||
if profit > - self.pairs[pair]['first_amount'] and count_of_buys > 15 and last_candle['sma24_deriv1_1h'] < 0:
|
||||
if profit > - self.pairs[pair]['first_amount'] \
|
||||
and self.wallets.get_available_stake_amount() < self.pairs[pair]['first_amount'] \
|
||||
and last_candle['sma24_deriv1_1h'] < 0:
|
||||
stake_amount = trade.stake_amount
|
||||
self.pairs[pair]['previous_profit'] = profit
|
||||
trade_type = "Sell " + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
|
||||
@@ -1155,21 +1165,21 @@ class FrictradeLearning(IStrategy):
|
||||
# last_fill_price = buy_orders[-1].price
|
||||
|
||||
# baisse relative
|
||||
if minutes % 60 == 0:
|
||||
ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle))
|
||||
self.pairs[pair]['last_ath'] = ath
|
||||
else:
|
||||
ath = self.pairs[pair]['last_ath']
|
||||
# if minutes % 60 == 0:
|
||||
# ath = max(self.pairs[pair]['last_max'], self.get_last_ath_before_candle(last_candle))
|
||||
# self.pairs[pair]['last_ath'] = ath
|
||||
# else:
|
||||
# ath = self.pairs[pair]['last_ath']
|
||||
|
||||
# steps = self.approx_value(last_candle['mid'], ath)
|
||||
|
||||
# dca_thresholds = split_ratio_one_third((last_candle['mid'] - (ath * self.allow_decrease_rate)) / last_candle['mid'], steps) #((last_candle['mid'] - (ath * self.allow_decrease_rate)) / steps) / last_candle['mid'] # 0.0025 + 0.0005 * count_of_buys
|
||||
# dca_thresholds = split_ratio_one_third((last_candle['mid'] - (ath * self.allow_decrease_rate.value)) / last_candle['mid'], steps) #((last_candle['mid'] - (ath * self.allow_decrease_rate.value)) / steps) / last_candle['mid'] # 0.0025 + 0.0005 * count_of_buys
|
||||
if len(self.pairs[pair]['dca_thresholds']) == 0:
|
||||
self.calculateStepsDcaThresholds(last_candle, pair)
|
||||
|
||||
dca_threshold = self.pairs[pair]['dca_thresholds'][min(count_of_buys - 1, len(self.pairs[pair]['dca_thresholds']) - 1)]
|
||||
|
||||
# print(f"{count_of_buys} {ath * (1 - self.allow_decrease_rate)} {round(last_candle['mid'], 2)} {round((last_candle['mid'] - (ath * self.allow_decrease_rate)) / last_candle['mid'], 2)} {steps} {round(dca_threshold, 4)}")
|
||||
# print(f"{count_of_buys} {ath * (1 - self.allow_decrease_rate.value)} {round(last_candle['mid'], 2)} {round((last_candle['mid'] - (ath * self.allow_decrease_rate.value)) / last_candle['mid'], 2)} {steps} {round(dca_threshold, 4)}")
|
||||
decline = (last_fill_price - current_rate) / last_fill_price
|
||||
increase = - decline
|
||||
|
||||
@@ -1209,13 +1219,10 @@ class FrictradeLearning(IStrategy):
|
||||
# return None
|
||||
|
||||
# FIN ########################## ALGO ATH
|
||||
force = hours > 24 and last_candle['sma60_deriv1_1h'] > 0
|
||||
force = hours > self.hours_force.value and last_candle['sma60_deriv1_1h'] > 0
|
||||
condition = last_candle['percent'] > 0 and last_candle['sma24_deriv1'] > 0 \
|
||||
and last_candle['close'] < self.pairs[pair]['first_buy']
|
||||
# and last_candle['ml_prob'] > 0.65
|
||||
|
||||
limit_buy = 40
|
||||
# or (last_candle['close'] <= last_candle['min180'] and hours > 3)
|
||||
if ((force or decline >= dca_threshold) and condition):
|
||||
try:
|
||||
if self.pairs[pair]['has_gain'] and profit > 0:
|
||||
@@ -1224,6 +1231,9 @@ class FrictradeLearning(IStrategy):
|
||||
return None
|
||||
|
||||
stake_amount = min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle))
|
||||
|
||||
if force:
|
||||
stake_amount = stake_amount / 4
|
||||
# print(f"profit={profit} previous={self.pairs[pair]['previous_profit']} count_of_buys={trade.nr_of_successful_entries}")
|
||||
if stake_amount > 0:
|
||||
self.pairs[pair]['previous_profit'] = profit
|
||||
@@ -1402,7 +1412,7 @@ class FrictradeLearning(IStrategy):
|
||||
# ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? -----
|
||||
if current_trailing_only_offset_is_reached:
|
||||
# Max profit pas atteint ET perte < 2 * current_trailing_stop_positive
|
||||
if max_profit < min(2, max_profit * current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain'])): #2 * current_trailing_stop_positive:
|
||||
if profit > max_profit * current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']): #2 * current_trailing_stop_positive:
|
||||
print(f"{current_time} trailing non atteint trailing_stop={round(trailing_stop,4)} profit={round(profit, 4)} max={round(max_profit, 4)} "
|
||||
f"{min(2, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']))}")
|
||||
return None # ne pas activer le trailing encore
|
||||
@@ -1514,8 +1524,6 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
return dataframe
|
||||
|
||||
import pandas as pd
|
||||
|
||||
def to_utc_ts(self, x):
|
||||
return pd.to_datetime(x, utc=True)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user