FrictradeLearning.py Stoploss auto et gestion steps de mises adjust

This commit is contained in:
Jérôme Delacotte
2025-12-14 20:20:26 +01:00
parent 639afa42f0
commit c82b3359fa
16 changed files with 471 additions and 257 deletions

View File

@@ -9,22 +9,27 @@
}, },
"trailing": { "trailing": {
"trailing_stop": false, "trailing_stop": false,
"trailing_stop_positive": 0.15, "trailing_stop_positive": 0.2,
"trailing_stop_positive_offset": 1, "trailing_stop_positive_offset": 1,
"trailing_only_offset_is_reached": true "trailing_only_offset_is_reached": true
}, },
"max_open_trades": { "max_open_trades": {
"max_open_trades": 80 "max_open_trades": 20
},
"buy": {
"hours_force": 11
}, },
"protection": { "protection": {
"allow_decrease_rate": 0.7, "allow_decrease_rate": 0.4,
"first_adjust_param": 0.01, "first_adjust_param": 0.005,
"max_steps": 35 "max_steps": 45
},
"buy": {
"hours_force": 44,
"indic_1h_force_buy": "sma5_deriv1_1h"
},
"sell": {
"offset_max": 18,
"offset_min": 17
} }
}, },
"ft_stratparam_v": 1, "ft_stratparam_v": 1,
"export_time": "2025-12-09 07:22:51.929255+00:00" "export_time": "2025-12-14 18:44:03.713386+00:00"
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1 +1 @@
0.2788135593220339 0.14152542372881355

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 24 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
import numpy as np
import matplotlib.pyplot as plt
from lightgbm import LGBMRegressor
# === Données non linéaires ===
np.random.seed(0)
X = np.linspace(0, 10, 200).reshape(-1, 1)
y = np.sin(X).ravel() + np.random.normal(0, 0.1, X.shape[0]) # sinusoïde + bruit
# === Entraînement du modèle ===
model = LGBMRegressor(
n_estimators=300, # nombre darbres
learning_rate=0.05, # taux dapprentissage (plus petit = plus lisse)
max_depth=5 # profondeur des arbres (plus grand = plus complexe)
)
model.fit(X, y)
# === Prédiction ===
X_test = np.linspace(0, 10, 500).reshape(-1, 1)
y_pred = model.predict(X_test)
# === Visualisation ===
plt.figure(figsize=(10, 5))
plt.scatter(X, y, color="lightgray", label="Données réelles (sin + bruit)", s=20)
plt.plot(X_test, np.sin(X_test), color="green", linestyle="--", label="sin(x) réel")
plt.plot(X_test, y_pred, color="red", label="Prédiction LGBM")
plt.title("Approximation non linéaire avec LGBMRegressor")
plt.xlabel("x")
plt.ylabel("y")
plt.legend()
plt.grid(True)
plt.show()

View File

@@ -445,6 +445,46 @@ class Crash:
return selected_corr return selected_corr
def drawPredictions(self, df, indicators, y_proba, threshold=0.5):
"""
Trace simultanément plusieurs indicateurs et la prédiction du modèle.
Parameters
----------
df : pd.DataFrame
Dataframe avec les colonnes des indicateurs et la target.
indicators : list[str]
Liste des colonnes du dataframe à tracer.
y_proba : np.array
Probabilités prédites par le modèle (valeurs continues entre 0 et 1)
threshold : float
Seuil pour convertir probabilité en signal binaire
output_file : str
Fichier sur lequel sauvegarder le graphique
"""
plt.figure(figsize=(18, 6))
# Tracer les indicateurs
for col in indicators:
plt.plot(df.index, df[col], label=col, alpha=0.7)
# Tracer la prédiction du modèle (probabilité)
plt.plot(df.index, y_proba, label="Prediction prob.", color="black", linestyle="--")
# Optionnel : signal binaire (1 si prob > threshold)
y_signal = (y_proba > threshold).astype(int)
plt.scatter(df.index, y_signal, color='red', marker='o', label='Signal > threshold', s=20)
plt.title("Indicateurs + prédiction MLP")
plt.xlabel("Date")
plt.ylabel("Valeur / Probabilité")
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.savefig(f"{self.path}/indicators_vs_prediction.png")
plt.close()
def drawSequentialGraphs(self, model, history, X_train_scaled, X_valid_scaled, y_train, def drawSequentialGraphs(self, model, history, X_train_scaled, X_valid_scaled, y_train,
y_valid, thresholds=None, best_threshold=None y_valid, thresholds=None, best_threshold=None
): ):
@@ -556,6 +596,17 @@ class Crash:
# plt.savefig(f"{self.path}/permutation_importance.png") # plt.savefig(f"{self.path}/permutation_importance.png")
# plt.close() # plt.close()
# Exemple : on choisit 3 indicateurs du dataframe
indicators = ['percent12']
# y_proba = model.predict(X_valid_scaled).ravel()
self.drawPredictions(
df=self.dataframe.iloc[-len(y_proba):], # sélectionner la période correspondant à X_valid
indicators=indicators,
y_proba=y_proba,
threshold=0.5
)
# ========================= # =========================
# 7⃣ Sauvegarde seuil # 7⃣ Sauvegarde seuil
# ========================= # =========================
@@ -567,7 +618,7 @@ class Crash:
"best_f1": max(f1s) "best_f1": max(f1s)
} }
def optimize_sequential(self, X_train, y_train, X_valid, y_valid, n_trials=20): def optimize_sequential(self, X_train, X_valid, y_train, y_valid , n_trials=20):
def objective(trial): def objective(trial):
tf.keras.backend.clear_session() tf.keras.backend.clear_session()
@@ -835,7 +886,7 @@ class Crash:
# df['target'] = df['target'].fillna(0).astype(int) # df['target'] = df['target'].fillna(0).astype(int)
# label : crash si -n% dans les p heures # label : crash si -n% dans les p heures
self.calculateTarget(df) self.initTarget(df)
self.calculateCorrelation(df) self.calculateCorrelation(df)
@@ -872,7 +923,7 @@ class Crash:
assert len(X_train) == len(y_train) assert len(X_train) == len(y_train)
assert len(X_valid) == len(y_valid) assert len(X_valid) == len(y_valid)
self.train_model, study = self.optimize_sequential(X_train, y_train, X_valid, y_valid, n_trials=50) self.train_model, study = self.optimize_sequential(X_train, X_valid, y_train, y_valid, n_trials=50)
self.analyseStudy(study) self.analyseStudy(study)
@@ -939,7 +990,7 @@ class Crash:
# plt.ylabel("Score") # plt.ylabel("Score")
# plt.show() # plt.show()
self.analyze_model(pair, self.train_model, X_train, X_valid, y_train, y_valid) self.analyze_model(self.train_model, X_train, X_valid, y_train, y_valid)
def analyseImportances(self, selected_features, X_train, X_valid, y_valid): def analyseImportances(self, selected_features, X_train, X_valid, y_valid):
# Feature importance # Feature importance
@@ -1137,7 +1188,7 @@ class Crash:
# FIN SHAP # FIN SHAP
def calculateTarget(self, df): def initTarget(self, df):
future = df['mid'].shift(-12) future = df['mid'].shift(-12)
df['future_dd'] = (future - df['mid']) / df['mid'] df['future_dd'] = (future - df['mid']) / df['mid']
df['target'] = (df['future_dd'] > 0.003).astype(int) df['target'] = (df['future_dd'] > 0.003).astype(int)
@@ -1214,7 +1265,7 @@ class Crash:
print("\n===== ✅ FIN DE LINSPECTION =====") print("\n===== ✅ FIN DE LINSPECTION =====")
def analyze_model(self, pair, model, X_train, X_valid, y_train, y_valid): def analyze_model(self, model, X_train, X_valid, y_train, y_valid):
""" """
Analyse complète d'un modèle ML supervisé (classification binaire). Analyse complète d'un modèle ML supervisé (classification binaire).
Affiche performances, importance des features, matrices, seuils, etc. Affiche performances, importance des features, matrices, seuils, etc.
@@ -1398,7 +1449,7 @@ class Crash:
df = df.set_index('date') df = df.set_index('date')
# Optionnel : ne garder quune plage temporelle # Optionnel : ne garder quune plage temporelle
df = df["2025-01-01":"2025-07-14"] df = df["2025-01-01":"2025-02-01"]
df = df.reset_index('date') df = df.reset_index('date')
# Supprimer NaN # Supprimer NaN