Frictrade progression adjust exponentielle / correction trailing
This commit is contained in:
@@ -27,6 +27,7 @@ import ta
|
|||||||
import talib.abstract as talib
|
import talib.abstract as talib
|
||||||
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
import freqtrade.vendor.qtpylib.indicators as qtpylib
|
||||||
from datetime import timezone, timedelta
|
from datetime import timezone, timedelta
|
||||||
|
import mpmath as mp
|
||||||
|
|
||||||
# Machine Learning
|
# Machine Learning
|
||||||
from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor
|
from sklearn.ensemble import RandomForestClassifier,RandomForestRegressor
|
||||||
@@ -133,7 +134,7 @@ class FrictradeLearning(IStrategy):
|
|||||||
|
|
||||||
trailing_stop = False
|
trailing_stop = False
|
||||||
trailing_stop_positive = 0.15
|
trailing_stop_positive = 0.15
|
||||||
trailing_stop_positive_offset = 0.5
|
trailing_stop_positive_offset = 1
|
||||||
trailing_only_offset_is_reached = True
|
trailing_only_offset_is_reached = True
|
||||||
|
|
||||||
# Buy hypers
|
# Buy hypers
|
||||||
@@ -246,19 +247,33 @@ class FrictradeLearning(IStrategy):
|
|||||||
return allow_to_buy
|
return allow_to_buy
|
||||||
|
|
||||||
def calculateStepsDcaThresholds(self, last_candle, pair):
|
def calculateStepsDcaThresholds(self, last_candle, pair):
|
||||||
def split_ratio_one_third(n, p):
|
# def split_ratio_one_third(n, p):
|
||||||
a = n / (2 * p) # première valeur
|
# a = n / (2 * p) # première valeur
|
||||||
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):
|
||||||
|
# solve for r
|
||||||
|
# S = first * (r^n - 1)/(r - 1) = total
|
||||||
|
# numeric solving
|
||||||
|
|
||||||
|
f = lambda r: first * (r ** n - 1) / (r - 1) - total
|
||||||
|
r = mp.findroot(f, 1.05) # initial guess
|
||||||
|
|
||||||
|
parts = [round(first * (r ** k), 4) for k in range(n)]
|
||||||
|
return parts
|
||||||
|
|
||||||
|
# r, parts = progressive_parts(0.4, 40, 0.004)
|
||||||
|
# print("r =", r)
|
||||||
|
# print(parts)
|
||||||
|
|
||||||
if self.pairs[pair]['last_ath'] == 0 :
|
if self.pairs[pair]['last_ath'] == 0 :
|
||||||
ath = max(last_candle['mid'], self.get_last_ath_before_candle(last_candle))
|
ath = max(last_candle['mid'], self.get_last_ath_before_candle(last_candle))
|
||||||
self.pairs[pair]['last_ath'] = ath
|
self.pairs[pair]['last_ath'] = ath
|
||||||
|
|
||||||
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'] = split_ratio_one_third(
|
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))) / last_candle['mid'],
|
||||||
steps)
|
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']}")
|
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(self.pairs[pair]['dca_thresholds'])
|
print(self.pairs[pair]['dca_thresholds'])
|
||||||
|
|
||||||
@@ -895,9 +910,11 @@ class FrictradeLearning(IStrategy):
|
|||||||
# Buy = prediction > threshold
|
# Buy = prediction > threshold
|
||||||
dataframe["buy"] = 0
|
dataframe["buy"] = 0
|
||||||
dataframe.loc[
|
dataframe.loc[
|
||||||
(dataframe["ml_prob"].shift(3) < 0.2)
|
(dataframe["ml_prob"].shift(1) < dataframe["ml_prob"])
|
||||||
& (dataframe['low'].shift(3) < dataframe['min180'].shift(3))
|
& (dataframe['sma24_deriv1'] > 0)
|
||||||
& (dataframe['min180'].shift(3) == dataframe['min180']),
|
& (dataframe['sma12_deriv1'] > 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"future")
|
||||||
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.003, np.nan)
|
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.003, np.nan)
|
||||||
@@ -1310,6 +1327,8 @@ class FrictradeLearning(IStrategy):
|
|||||||
|
|
||||||
# if current_profit > 0:
|
# if current_profit > 0:
|
||||||
# print(f"profit={profit} max_profit={max_profit} current_profit={current_profit}")
|
# print(f"profit={profit} max_profit={max_profit} current_profit={current_profit}")
|
||||||
|
if profit < 0:
|
||||||
|
return None
|
||||||
|
|
||||||
baisse = 0
|
baisse = 0
|
||||||
if profit > 0:
|
if profit > 0:
|
||||||
@@ -1318,11 +1337,11 @@ class FrictradeLearning(IStrategy):
|
|||||||
self.pairs[pair]['count_of_buys'] = count_of_buys
|
self.pairs[pair]['count_of_buys'] = count_of_buys
|
||||||
self.pairs[pair]['current_profit'] = profit
|
self.pairs[pair]['current_profit'] = profit
|
||||||
|
|
||||||
dispo = round(self.wallets.get_available_stake_amount())
|
# dispo = round(self.wallets.get_available_stake_amount())
|
||||||
hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
|
# hours_since_first_buy = (current_time - trade.open_date_utc).seconds / 3600.0
|
||||||
days_since_first_buy = (current_time - trade.open_date_utc).days
|
# days_since_first_buy = (current_time - trade.open_date_utc).days
|
||||||
hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
|
# hours = (current_time - trade.date_last_filled_utc).total_seconds() / 3600.0
|
||||||
minutes = (current_time - trade.date_last_filled_utc).total_seconds() / 60.0
|
# minutes = (current_time - trade.date_last_filled_utc).total_seconds() / 60.0
|
||||||
|
|
||||||
# ----- 2) Mise à jour du max_price -----
|
# ----- 2) Mise à jour du max_price -----
|
||||||
self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
|
self.pairs[pair]['max_touch'] = max(last_candle['close'], self.pairs[pair]['max_touch'])
|
||||||
@@ -1383,14 +1402,23 @@ 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, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain']))\
|
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:
|
||||||
and (max_profit > current_trailing_stop_positive_offset): #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
|
return None # ne pas activer le trailing encore
|
||||||
|
else:
|
||||||
|
print(f"{current_time} trailing 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']))}")
|
||||||
|
|
||||||
# Sinon : trailing actif dès le début
|
# Sinon : trailing actif dès le début
|
||||||
|
|
||||||
# ----- 6) Condition de vente -----
|
# ----- 6) Condition de vente -----
|
||||||
if 0 < profit <= trailing_stop and last_candle['mid'] < last_candle['sma5']:
|
if 0 < profit <= trailing_stop and last_candle['mid'] < last_candle['sma5']:
|
||||||
self.pairs[pair]['force_buy'] = True
|
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(min(2, current_trailing_stop_positive_offset * (count_of_buys - self.pairs[pair]['has_gain'])), 4)}")
|
||||||
|
|
||||||
return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}"
|
return f"stop_{count_of_buys}_{self.pairs[pair]['has_gain']}"
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user