FrictradeLearning.py Stoploss auto et gestion steps de mises adjust
@@ -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"
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
0.2788135593220339
|
0.14152542372881355
|
||||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 21 KiB |
BIN
plots/BTC/crash/indicators_vs_prediction.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
32
tools/sklearn/.ipynb_checkpoints/Sinus-checkpoint.py
Normal 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 d’arbres
|
||||||
|
learning_rate=0.05, # taux d’apprentissage (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()
|
||||||
@@ -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 L’INSPECTION =====")
|
print("\n===== ✅ FIN DE L’INSPECTION =====")
|
||||||
|
|
||||||
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 qu’une plage temporelle
|
# Optionnel : ne garder qu’une 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
|
||||||