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,
|
-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:
|
# ROI table:
|
||||||
minimal_roi = {
|
minimal_roi = {
|
||||||
@@ -139,8 +143,6 @@ class FrictradeLearning(IStrategy):
|
|||||||
|
|
||||||
# Buy hypers
|
# Buy hypers
|
||||||
timeframe = '1m'
|
timeframe = '1m'
|
||||||
max_open_trades = 5
|
|
||||||
max_amount = 40
|
|
||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
# DCA config
|
# DCA config
|
||||||
@@ -252,12 +254,18 @@ class FrictradeLearning(IStrategy):
|
|||||||
# d = n / (p * (p - 1)) # incrément
|
# d = n / (p * (p - 1)) # incrément
|
||||||
# return [round(a + i * d, 3) for i in range(p)]
|
# return [round(a + i * d, 3) for i in range(p)]
|
||||||
def progressive_parts(total, n, first):
|
def progressive_parts(total, n, first):
|
||||||
# solve for r
|
|
||||||
# S = first * (r^n - 1)/(r - 1) = total
|
# conditions impossibles → on évite le solveur
|
||||||
# numeric solving
|
if total <= 0 or first <= 0 or n <= 1:
|
||||||
|
return [0] * n
|
||||||
|
|
||||||
f = lambda r: first * (r ** n - 1) / (r - 1) - total
|
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)]
|
parts = [round(first * (r ** k), 4) for k in range(n)]
|
||||||
return parts
|
return parts
|
||||||
@@ -272,9 +280,9 @@ class FrictradeLearning(IStrategy):
|
|||||||
|
|
||||||
steps = self.approx_value(last_candle['mid'], self.pairs[pair]['last_ath'])
|
steps = self.approx_value(last_candle['mid'], self.pairs[pair]['last_ath'])
|
||||||
self.pairs[pair]['dca_thresholds'] = progressive_parts(
|
self.pairs[pair]['dca_thresholds'] = progressive_parts(
|
||||||
(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, 0.003)
|
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))) / last_candle['mid']}")
|
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'])
|
print(self.pairs[pair]['dca_thresholds'])
|
||||||
|
|
||||||
def confirm_trade_exit(self, pair: str, trade: Trade, order_type: str, amount: float, rate: float,
|
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):
|
# for val in range(90000, 130000, 10000):
|
||||||
# steps = self.approx_value(val, 126000)
|
# steps = self.approx_value(val, 126000)
|
||||||
# print(f"val={val} steps={steps} pct={(val - (126000 * (1 - self.allow_decrease_rate))) / val}")
|
# 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))) / 126000, steps)
|
# dca = split_ratio_one_third((val - (126000 * (1 - self.allow_decrease_rate.value))) / 126000, steps)
|
||||||
# print(dca)
|
# print(dca)
|
||||||
|
|
||||||
return dataframe
|
return dataframe
|
||||||
@@ -1033,9 +1041,9 @@ class FrictradeLearning(IStrategy):
|
|||||||
# return adjusted_stake_amount
|
# return adjusted_stake_amount
|
||||||
|
|
||||||
def approx_value(self, x, X_max):
|
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_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
|
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
|
b = Y_min - a * X_min # 1 − (0,000772595 × 75718,8) = −38
|
||||||
y = a * x + b # 0,000772595 * 115000 - 38
|
y = a * x + b # 0,000772595 * 115000 - 38
|
||||||
@@ -1112,7 +1120,9 @@ class FrictradeLearning(IStrategy):
|
|||||||
if self.pairs[pair]['first_buy']:
|
if self.pairs[pair]['first_buy']:
|
||||||
pct_first = self.getPctFirstBuy(pair, last_candle)
|
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
|
stake_amount = trade.stake_amount
|
||||||
self.pairs[pair]['previous_profit'] = profit
|
self.pairs[pair]['previous_profit'] = profit
|
||||||
trade_type = "Sell " + (last_candle['enter_tag'] if last_candle['enter_long'] == 1 else '')
|
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
|
# last_fill_price = buy_orders[-1].price
|
||||||
|
|
||||||
# baisse relative
|
# baisse relative
|
||||||
if minutes % 60 == 0:
|
# if minutes % 60 == 0:
|
||||||
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))
|
||||||
self.pairs[pair]['last_ath'] = ath
|
# self.pairs[pair]['last_ath'] = ath
|
||||||
else:
|
# else:
|
||||||
ath = self.pairs[pair]['last_ath']
|
# ath = self.pairs[pair]['last_ath']
|
||||||
|
|
||||||
# steps = self.approx_value(last_candle['mid'], 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:
|
if len(self.pairs[pair]['dca_thresholds']) == 0:
|
||||||
self.calculateStepsDcaThresholds(last_candle, pair)
|
self.calculateStepsDcaThresholds(last_candle, pair)
|
||||||
|
|
||||||
dca_threshold = self.pairs[pair]['dca_thresholds'][min(count_of_buys - 1, len(self.pairs[pair]['dca_thresholds']) - 1)]
|
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
|
decline = (last_fill_price - current_rate) / last_fill_price
|
||||||
increase = - decline
|
increase = - decline
|
||||||
|
|
||||||
@@ -1209,13 +1219,10 @@ class FrictradeLearning(IStrategy):
|
|||||||
# return None
|
# return None
|
||||||
|
|
||||||
# FIN ########################## ALGO ATH
|
# 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 \
|
condition = last_candle['percent'] > 0 and last_candle['sma24_deriv1'] > 0 \
|
||||||
and last_candle['close'] < self.pairs[pair]['first_buy']
|
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):
|
if ((force or decline >= dca_threshold) and condition):
|
||||||
try:
|
try:
|
||||||
if self.pairs[pair]['has_gain'] and profit > 0:
|
if self.pairs[pair]['has_gain'] and profit > 0:
|
||||||
@@ -1224,6 +1231,9 @@ class FrictradeLearning(IStrategy):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
stake_amount = min(self.wallets.get_available_stake_amount(), self.adjust_stake_amount(pair, last_candle))
|
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}")
|
# print(f"profit={profit} previous={self.pairs[pair]['previous_profit']} count_of_buys={trade.nr_of_successful_entries}")
|
||||||
if stake_amount > 0:
|
if stake_amount > 0:
|
||||||
self.pairs[pair]['previous_profit'] = profit
|
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 ? -----
|
# ----- 4) OFFSET : faut-il attendre de dépasser trailing_stop_positive_offset ? -----
|
||||||
if current_trailing_only_offset_is_reached:
|
if current_trailing_only_offset_is_reached:
|
||||||
# Max profit pas atteint ET perte < 2 * current_trailing_stop_positive
|
# 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)} "
|
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']))}")
|
f"{min(2, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']))}")
|
||||||
return None # ne pas activer le trailing encore
|
return None # ne pas activer le trailing encore
|
||||||
@@ -1514,8 +1524,6 @@ class FrictradeLearning(IStrategy):
|
|||||||
|
|
||||||
return dataframe
|
return dataframe
|
||||||
|
|
||||||
import pandas as pd
|
|
||||||
|
|
||||||
def to_utc_ts(self, x):
|
def to_utc_ts(self, x):
|
||||||
return pd.to_datetime(x, utc=True)
|
return pd.to_datetime(x, utc=True)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user