Menage des inutiles

This commit is contained in:
Jérôme Delacotte
2025-07-01 18:27:41 +02:00
parent 10fa79ede4
commit 6d7386ed99
3 changed files with 119 additions and 99 deletions

View File

@@ -9,11 +9,3 @@ Werkzeug==2.2.3
joblib==1.4.2 joblib==1.4.2
pyarrow pyarrow
pandas-ta pandas-ta
ydata-profiling
tensorflow
keras
scikit-learn
pydot
graphviz
ann_visualizer
netron

View File

@@ -5,19 +5,20 @@ import zipfile
import os import os
import pickle import pickle
import joblib import joblib
import glob
from io import TextIOWrapper from io import TextIOWrapper
from ydata_profiling import ProfileReport # from ydata_profiling import ProfileReport
# model # model
from sklearn.model_selection import train_test_split # from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler # from sklearn.preprocessing import StandardScaler
from tensorflow.keras.models import Sequential # from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense # from tensorflow.keras.layers import Dense
from tensorflow.keras.utils import plot_model # from tensorflow.keras.utils import plot_model
#
from keras.models import Sequential # from keras.models import Sequential
from keras.layers import Dense # from keras.layers import Dense
from ann_visualizer.visualize import ann_viz # from ann_visualizer.visualize import ann_viz
app = Flask(__name__) app = Flask(__name__)
FREQTRADE_USERDATA_DIR = '/mnt/external' FREQTRADE_USERDATA_DIR = '/mnt/external'
@@ -26,13 +27,16 @@ FREQTRADE_USERDATA_DIR = '/mnt/external'
@app.route('/') @app.route('/')
def home(): def home():
# Liste les fichiers dans le répertoire monté # Liste les fichiers dans le répertoire monté
files = os.listdir(FREQTRADE_USERDATA_DIR + "/backtest_results") files = list(filter(os.path.isfile, glob.glob(FREQTRADE_USERDATA_DIR + "/backtest_results/" + "*")))
files.sort(key=os.path.getctime)
# Filtre pour obtenir uniquement les fichiers (pas les dossiers) # Filtre pour obtenir uniquement les fichiers (pas les dossiers)
files = [f for f in files if os.path.isfile(os.path.join(FREQTRADE_USERDATA_DIR + "/backtest_results", f)) and f.lower().endswith('.zip')] files = [os.path.basename(f) for f in files if os.path.isfile(f) and f.lower().endswith('.zip')]
# files2 = os.listdir(FREQTRADE_USERDATA_DIR + "/data/binance")
files2 = list(filter(os.path.isfile, glob.glob(FREQTRADE_USERDATA_DIR + "/data/binance/" + "*")))
files2.sort(key=os.path.getctime)
files2 = [os.path.basename(f) for f in files2 if os.path.isfile(f) and f.lower().endswith('.feather')]
files2 = os.listdir(FREQTRADE_USERDATA_DIR + "/data/binance")
files2 = [f for f in files2 if os.path.isfile(os.path.join(FREQTRADE_USERDATA_DIR + "/data/binance", f)) and f.lower().endswith('.feather')]
# Retourne le template avec la liste des fichiers # Retourne le template avec la liste des fichiers
return render_template('index.html', files=files, files2=files2) return render_template('index.html', files=files, files2=files2)
@@ -197,72 +201,72 @@ def get_chart_data():
return df.to_json(orient="records") #jsonify(chart_data) return df.to_json(orient="records") #jsonify(chart_data)
@app.route('/generate_model') # @app.route('/generate_model')
def generate_model(): # def generate_model():
filename = request.args.get('filename', '') # filename = request.args.get('filename', '')
path = os.path.join(FREQTRADE_USERDATA_DIR + "/data/binance/", filename) # path = os.path.join(FREQTRADE_USERDATA_DIR + "/data/binance/", filename)
print(path) # print(path)
# indicators = request.args.get('indicators', '').split(',') # # indicators = request.args.get('indicators', '').split(',')
df = pd.read_feather(path) # df = pd.read_feather(path)
#
# Choisir les colonnes techniques comme variables d'entrée (X) # # Choisir les colonnes techniques comme variables d'entrée (X)
feature_cols = ['close', 'rsi', 'sma5', 'sma10', 'sma20', 'sma5_1h', 'volume', 'sma5_1h'] # feature_cols = ['close', 'rsi', 'sma5', 'sma10', 'sma20', 'sma5_1h', 'volume', 'sma5_1h']
#
# Variable cible 2 heures # # Variable cible 2 heures
df['target'] = (df['close'].shift(-24) - df['close']) / df['close'] # df['target'] = (df['close'].shift(-24) - df['close']) / df['close']
#
# Supprimer les lignes avec des NaN # # Supprimer les lignes avec des NaN
df.dropna(subset=feature_cols + ['target'], inplace=True) # df.dropna(subset=feature_cols + ['target'], inplace=True)
#
X = df[feature_cols].values # X = df[feature_cols].values
y = df['target'].values # y = df['target'].values
#
# Normalisation # # Normalisation
scaler = StandardScaler() # scaler = StandardScaler()
X = scaler.fit_transform(X) # X = scaler.fit_transform(X)
#
# Split # # Split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2) # X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
#
# Modèle # # Modèle
model = Sequential([ # model = Sequential([
Dense(64, input_dim=X.shape[1], activation='relu'), # Dense(64, input_dim=X.shape[1], activation='relu'),
Dense(32, activation='relu'), # Dense(32, activation='relu'),
Dense(1) # Prédiction continue # Dense(1) # Prédiction continue
]) # ])
#
model.compile(optimizer='adam', loss='mse', metrics=['mae']) # model.compile(optimizer='adam', loss='mse', metrics=['mae'])
#
# Entraînement # # Entraînement
model.fit(X_train, y_train, epochs=100, batch_size=64, validation_data=(X_test, y_test)) # model.fit(X_train, y_train, epochs=100, batch_size=64, validation_data=(X_test, y_test))
#
loss, mae = model.evaluate(X_test, y_test) # loss, mae = model.evaluate(X_test, y_test)
print(f"Erreur moyenne absolue : {mae:.4f}") # print(f"Erreur moyenne absolue : {mae:.4f}")
#
model.summary() # model.summary()
#
plot_model(model, show_shapes=True, show_layer_names=True, to_file=FREQTRADE_USERDATA_DIR + "/reports/model.png") # plot_model(model, show_shapes=True, show_layer_names=True, to_file=FREQTRADE_USERDATA_DIR + "/reports/model.png")
#
model.save(FREQTRADE_USERDATA_DIR + "/reports/model.h5") # model.save(FREQTRADE_USERDATA_DIR + "/reports/model.h5")
#
# ann_viz(model, title="Mon réseau", filename=FREQTRADE_USERDATA_DIR + "/reports/network.gv", view=True) # # ann_viz(model, title="Mon réseau", filename=FREQTRADE_USERDATA_DIR + "/reports/network.gv", view=True)
#
# Créer un exemple de modèle si non encore généré # # Créer un exemple de modèle si non encore généré
model_path = FREQTRADE_USERDATA_DIR + "/reports/model.png" # model_path = FREQTRADE_USERDATA_DIR + "/reports/model.png"
if not os.path.exists(model_path): # if not os.path.exists(model_path):
model = Sequential([ # model = Sequential([
Dense(64, input_shape=(6,), activation='relu'), # Dense(64, input_shape=(6,), activation='relu'),
Dense(32, activation='relu'), # Dense(32, activation='relu'),
Dense(1) # Dense(1)
]) # ])
plot_model(model, to_file=model_path, show_shapes=True, show_layer_names=True) # plot_model(model, to_file=model_path, show_shapes=True, show_layer_names=True)
return render_template('model.html', model_image=model_path) # return render_template('model.html', model_image=model_path)
#
# Route pour servir les fichiers statiques (optionnelle si bien configuré) # Route pour servir les fichiers statiques (optionnelle si bien configuré)
@app.route('/static/<path:filename>') # @app.route('/static/<path:filename>')
def static_files(filename): # def static_files(filename):
return send_from_directory('static', filename) # return send_from_directory('static', filename)
if __name__ == '__main__': if __name__ == '__main__':

View File

@@ -268,7 +268,7 @@ function renderChart(data, filename, create_columns) {
var d = result_of_strategy.trades[key]; var d = result_of_strategy.trades[key];
var date = new Date(d.open_date); var date = new Date(d.open_date);
marks.push({ marks.push({
name: 'Buy', name: d.enter_tag,
coord: [date.toLocaleString('fr-FR', options), d.open_rate], coord: [date.toLocaleString('fr-FR', options), d.open_rate],
value: d.open_rate, value: d.open_rate,
itemStyle: { itemStyle: {
@@ -276,22 +276,28 @@ function renderChart(data, filename, create_columns) {
} }
}) })
let count = 0
for (var key2 in d.orders) { for (var key2 in d.orders) {
var order = d.orders[key2] if (count == 0) {
date = new Date(order.order_filled_timestamp); count ++
marks.push({ }
name: 'Buy', else {
coord: [date.toLocaleString('fr-FR', options), order.safe_price], var order = d.orders[key2]
value: order.safe_price, date = new Date(order.order_filled_timestamp);
itemStyle: { marks.push({
color: 'rgb(0,0,90)' name: d.enter_tag,
} coord: [date.toLocaleString('fr-FR', options), order.safe_price],
}) value: order.safe_price,
itemStyle: {
color: 'rgb(0,0,90)'
}
})
}
} }
date = new Date(d.close_date); date = new Date(d.close_date);
marks.push({ marks.push({
name: 'Sell', name: d.exit_reason,
coord: [date.toLocaleString('fr-FR', options), d.close_rate], coord: [date.toLocaleString('fr-FR', options), d.close_rate],
value: d.close_rate, value: d.close_rate,
itemStyle: { itemStyle: {
@@ -353,6 +359,24 @@ function renderChart(data, filename, create_columns) {
return [date, d.close, d.enter_tag]; return [date, d.close, d.enter_tag];
}) })
}) })
// # prediction
// series.push({
// name: 'Buy',
// type: 'scatter',
// symbolSize: 5,
// itemStyle: {
// color: '#aa0000'
// },
// data: data
// .filter(d => d['poly_pred_t+12'] === 1)
// .map(d => {
// const date = new Date(d.date).toLocaleString('fr-FR', options);
// return [date, d.close, d.enter_tag];
// })
// })
// Volume // Volume
series.push({ series.push({
name: 'Volume', name: 'Volume',