Frictrade
This commit is contained in:
@@ -456,7 +456,7 @@ class FrictradeLearning(IStrategy):
|
||||
# Add all ta features
|
||||
pair = metadata['pair']
|
||||
short_pair = self.getShortName(pair)
|
||||
self.path = f"user_data/plots/{short_pair}/" + ("valide/" if not self.dp.runmode.value in ('backtest') else '')
|
||||
self.path = f"user_data/strategies/plots/{short_pair}/" + ("valide/" if not self.dp.runmode.value in ('backtest') else '')
|
||||
|
||||
heikinashi = qtpylib.heikinashi(dataframe)
|
||||
dataframe['haopen'] = heikinashi['open']
|
||||
@@ -490,6 +490,16 @@ class FrictradeLearning(IStrategy):
|
||||
& (dataframe["sma5_sqrt"] > 5)
|
||||
)
|
||||
|
||||
dataframe["sma12_sqrt"] = (
|
||||
np.sqrt(np.abs(dataframe["sma12"] - dataframe["sma12"].shift(1)))
|
||||
+ np.sqrt(np.abs(dataframe["sma12"].shift(3) - dataframe["sma12"].shift(1)))
|
||||
)
|
||||
dataframe["sma12_inv"] = (
|
||||
(dataframe["sma12"].shift(2) >= dataframe["sma12"].shift(1))
|
||||
& (dataframe["sma12"].shift(1) <= dataframe["sma12"])
|
||||
& (dataframe["sma12_sqrt"] > 5)
|
||||
)
|
||||
|
||||
dataframe["percent"] = dataframe['mid'].pct_change()
|
||||
dataframe["percent3"] = dataframe['mid'].pct_change(3).rolling(3).mean()
|
||||
dataframe["percent12"] = dataframe['mid'].pct_change(12).rolling(12).mean()
|
||||
@@ -723,9 +733,9 @@ class FrictradeLearning(IStrategy):
|
||||
self.trainModel(dataframe, metadata)
|
||||
|
||||
short_pair = self.getShortName(pair)
|
||||
path=f"user_data/plots/{short_pair}/"
|
||||
# path=f"user_data/strategies/plots/{short_pair}/"
|
||||
|
||||
self.model = joblib.load(f"{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
|
||||
features = dataframe[self.model_indicators].fillna(0)
|
||||
@@ -824,7 +834,12 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
# Buy = prediction > threshold
|
||||
dataframe["buy"] = 0
|
||||
dataframe.loc[dataframe["ml_prob"] > 0.5, ['enter_long', 'enter_tag']] = (1, f"future")
|
||||
dataframe.loc[
|
||||
(dataframe["ml_prob"].shift(3) < 0.2)
|
||||
& (dataframe['low'].shift(3) < dataframe['min180'].shift(3))
|
||||
& (dataframe['min180'].shift(3) == dataframe['min180']),
|
||||
['enter_long', 'enter_tag']
|
||||
] = (1, f"future")
|
||||
dataframe['test'] = np.where(dataframe['enter_long'] == 1, dataframe['close'] * 1.003, np.nan)
|
||||
|
||||
return dataframe
|
||||
@@ -1060,9 +1075,10 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
# FIN ########################## ALGO ATH
|
||||
|
||||
condition = last_candle['hapercent'] > 0 and last_candle['sma24_deriv1'] > 0 \
|
||||
and last_candle['close'] < self.pairs[pair]['first_buy'] \
|
||||
and last_candle['ml_prob'] > 0.65
|
||||
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 (decline >= dca_threshold) and condition:
|
||||
@@ -1206,12 +1222,12 @@ class FrictradeLearning(IStrategy):
|
||||
position = (mid - min_) / (max_ - min_)
|
||||
zone = int(position * 3) # 0 à 2
|
||||
|
||||
if zone == 0:
|
||||
current_trailing_stop_positive = self.trailing_stop_positive
|
||||
current_trailing_stop_positive_offset = self.trailing_stop_positive_offset * 2
|
||||
if minutes > 1440:
|
||||
current_trailing_only_offset_is_reached = False
|
||||
current_trailing_stop_positive_offset = self.trailing_stop_positive_offset
|
||||
# if zone == 0:
|
||||
# current_trailing_stop_positive = self.trailing_stop_positive
|
||||
# current_trailing_stop_positive_offset = self.trailing_stop_positive_offset * 2
|
||||
# if minutes > 1440:
|
||||
# current_trailing_only_offset_is_reached = False
|
||||
# current_trailing_stop_positive_offset = self.trailing_stop_positive_offset
|
||||
# if zone == 1:
|
||||
|
||||
# ----- 5) Calcul du trailing stop dynamique -----
|
||||
@@ -1236,7 +1252,7 @@ class FrictradeLearning(IStrategy):
|
||||
stake=0
|
||||
)
|
||||
|
||||
if last_candle['ml_prob'] > 0.65:
|
||||
if last_candle['sma12'] > last_candle['sma24']:
|
||||
return None
|
||||
# if last_candle['sma24_deriv1'] > 0 : #and minutes < 180 and baisse < 30: # and last_candle['sma5_deriv1'] > -0.15:
|
||||
# if (minutes < 180):
|
||||
@@ -1371,7 +1387,7 @@ class FrictradeLearning(IStrategy):
|
||||
pd.set_option('display.max_rows', None)
|
||||
pd.set_option('display.max_columns', None)
|
||||
pd.set_option("display.width", 200)
|
||||
path=f"user_data/plots/{pair}/"
|
||||
path=self.path #f"user_data/plots/{pair}/"
|
||||
os.makedirs(path, exist_ok=True)
|
||||
|
||||
# # Étape 1 : sélectionner numériques
|
||||
@@ -1452,7 +1468,7 @@ class FrictradeLearning(IStrategy):
|
||||
plt.yticks(rotation=0)
|
||||
|
||||
# --- Sauvegarde ---
|
||||
output_path = f"{path}/Matrice_de_correlation_temperature.png"
|
||||
output_path = f"{self.path}/Matrice_de_correlation_temperature.png"
|
||||
plt.savefig(output_path, bbox_inches="tight", dpi=150)
|
||||
plt.close(fig)
|
||||
|
||||
@@ -1594,7 +1610,7 @@ class FrictradeLearning(IStrategy):
|
||||
)
|
||||
|
||||
# Sauvegarde du graphique sur disque
|
||||
output_path = f"{path}/shap_waterfall.png"
|
||||
output_path = f"{self.path}/shap_waterfall.png"
|
||||
plt.savefig(output_path, dpi=200, bbox_inches='tight')
|
||||
plt.close() # ferme la figure proprement
|
||||
|
||||
@@ -1625,13 +1641,13 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
# Graphs
|
||||
fig = plot_optimization_history(study)
|
||||
fig.write_html(f"{path}/optimization_history.html")
|
||||
fig.write_html(f"{self.path}/optimization_history.html")
|
||||
fig = plot_param_importances(study)
|
||||
fig.write_html(f"{path}/param_importances.html")
|
||||
fig.write_html(f"{self.path}/param_importances.html")
|
||||
fig = plot_slice(study)
|
||||
fig.write_html(f"{path}/slice.html")
|
||||
fig.write_html(f"{self.path}/slice.html")
|
||||
fig = plot_parallel_coordinate(study)
|
||||
fig.write_html(f"{path}/parallel_coordinates.html")
|
||||
fig.write_html(f"{self.path}/parallel_coordinates.html")
|
||||
|
||||
|
||||
# 2️⃣ Sélection des features AVANT calibration
|
||||
@@ -1677,14 +1693,14 @@ class FrictradeLearning(IStrategy):
|
||||
feat_imp.plot(kind='bar', figsize=(12, 6))
|
||||
plt.title("Feature importances")
|
||||
# plt.show()
|
||||
plt.savefig(f"{path}/Feature importances.png", bbox_inches='tight')
|
||||
plt.savefig(f"{self.path}/Feature importances.png", bbox_inches='tight')
|
||||
|
||||
result = permutation_importance(self.train_model, X_valid, y_valid, scoring='f1', n_repeats=10, random_state=42)
|
||||
perm_imp = pd.Series(result.importances_mean, index=X_valid.columns).sort_values(ascending=False)
|
||||
perm_imp.plot(kind='bar', figsize=(12, 6))
|
||||
plt.title("Permutation feature importance")
|
||||
# plt.show()
|
||||
plt.savefig(f"{path}/Permutation feature importance.png", bbox_inches='tight')
|
||||
plt.savefig(f"{self.path}/Permutation feature importance.png", bbox_inches='tight')
|
||||
|
||||
# Shap
|
||||
explainer = shap.TreeExplainer(self.train_model)
|
||||
@@ -1695,7 +1711,7 @@ class FrictradeLearning(IStrategy):
|
||||
|
||||
# Force plot pour une observation
|
||||
force_plot = shap.force_plot(explainer.expected_value, shap_values[0, :], X_valid.iloc[0, :])
|
||||
shap.save_html(f"{path}/shap_force_plot.html", force_plot)
|
||||
shap.save_html(f"{self.path}/shap_force_plot.html", force_plot)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(24, 48))
|
||||
PartialDependenceDisplay.from_estimator(
|
||||
@@ -1705,7 +1721,7 @@ class FrictradeLearning(IStrategy):
|
||||
kind="average",
|
||||
ax=ax
|
||||
)
|
||||
fig.savefig(f"{path}/PartialDependenceDisplay.png", bbox_inches="tight")
|
||||
fig.savefig(f"{self.path}/PartialDependenceDisplay.png", bbox_inches="tight")
|
||||
plt.close(fig)
|
||||
|
||||
best_f1 = 0
|
||||
@@ -1726,7 +1742,7 @@ class FrictradeLearning(IStrategy):
|
||||
print(f"Accuracy: {acc:.3f}")
|
||||
|
||||
# 7️⃣ Sauvegarde du modèle
|
||||
joblib.dump(self.train_model, f"{path}/{pair}_rf_model.pkl")
|
||||
joblib.dump(self.train_model, f"{self.path}/{pair}_rf_model.pkl")
|
||||
print(f"✅ Modèle sauvegardé sous {pair}_rf_model.pkl")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user