Enoder commited on
Commit
3308842
·
verified ·
1 Parent(s): a6e73a4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +167 -0
app.py ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ import numpy as np
6
+ from datetime import datetime, timedelta
7
+ from sklearn.metrics import mean_squared_error
8
+
9
+ # Fonction pour récupérer les prix historiques
10
+ def get_crypto_prices(coins, start_time, end_time, interval='m15'):
11
+ prices = {}
12
+ for coin, coin_id in coins.items():
13
+ url = f'https://api.coincap.io/v2/assets/{coin_id}/history'
14
+ params = {
15
+ 'interval': interval,
16
+ 'start': int(start_time.timestamp() * 1000),
17
+ 'end': int(end_time.timestamp() * 1000)
18
+ }
19
+ response = requests.get(url, params=params)
20
+ if response.status_code == 200:
21
+ data = response.json().get('data', [])
22
+ prices[coin] = [[int(item['time']), float(item['priceUsd'])] for item in data]
23
+ if data:
24
+ prices[coin].append([int(end_time.timestamp() * 1000), float(data[-1]['priceUsd'])])
25
+ else:
26
+ st.error(f"Erreur lors de la récupération des prix pour {coin}: {response.status_code}")
27
+ st.write(response.text) # Debug pour afficher l'erreur complète
28
+ return prices
29
+
30
+ # Fonction pour prédire les tendances basées sur les patterns
31
+ def predict_patterns(data, future_hours=24):
32
+ df = pd.DataFrame(data, columns=["timestamp", "price"])
33
+ df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
34
+ df.set_index("timestamp", inplace=True)
35
+
36
+ last_timestamp = df.index[-1]
37
+ future_timestamps = [last_timestamp + timedelta(minutes=15 * i) for i in range(1, (future_hours * 60 // 15) + 1)]
38
+
39
+ last_price = df["price"].iloc[-1]
40
+ trend = (df["price"].iloc[-1] - df["price"].iloc[0]) / len(df)
41
+ sma = df["price"].rolling(window=10).mean().iloc[-1]
42
+ ema = df["price"].ewm(span=10, adjust=False).mean().iloc[-1]
43
+ cycle_amplitude = (df["price"].max() - df["price"].min()) / 2
44
+ mean_price = df["price"].mean()
45
+
46
+ patterns = {}
47
+
48
+ patterns["Trend"] = [last_price + i * trend for i in range(1, len(future_timestamps) + 1)]
49
+ patterns["Reversal"] = [last_price - i * trend for i in range(1, len(future_timestamps) + 1)]
50
+ patterns["SMA"] = [sma] * len(future_timestamps)
51
+ patterns["EMA"] = [ema] * len(future_timestamps)
52
+ patterns["Cycle"] = [
53
+ last_price + cycle_amplitude * np.sin(2 * np.pi * i / len(future_timestamps))
54
+ for i in range(len(future_timestamps))
55
+ ]
56
+ patterns["Rebound"] = [last_price + trend * (0.5 ** i) for i in range(len(future_timestamps))]
57
+ patterns["Plateau"] = [last_price] * len(future_timestamps)
58
+ patterns["Breakout"] = [
59
+ last_price + (trend * 2 if i < len(future_timestamps) // 2 else -trend * 2)
60
+ for i in range(len(future_timestamps))
61
+ ]
62
+ patterns["Recovery"] = [last_price + (mean_price - last_price) * (i / len(future_timestamps)) for i in range(len(future_timestamps))]
63
+ patterns["Acceleration"] = [last_price + (trend * 1.5) * i for i in range(len(future_timestamps))]
64
+
65
+ pattern_dfs = {
66
+ pattern_name: pd.DataFrame({"timestamp": future_timestamps, "price": prices})
67
+ for pattern_name, prices in patterns.items()
68
+ }
69
+ return pattern_dfs
70
+
71
+ # Fonction pour identifier un pattern similaire dans l'historique
72
+ def find_similar_pattern(df, pred_data, window_size=5):
73
+ mse_scores = {}
74
+ for i in range(len(df) - window_size):
75
+ history_segment = df["price"].iloc[i:i + window_size].values
76
+ mse = mean_squared_error(history_segment, pred_data[:len(history_segment)])
77
+ mse_scores[i] = mse
78
+
79
+ # Trouver le segment avec le plus faible MSE
80
+ best_start_index = min(mse_scores, key=mse_scores.get)
81
+ similar_pattern = df["price"].iloc[best_start_index:best_start_index + window_size].values
82
+ return similar_pattern
83
+
84
+ # Fonction pour générer une courbe dynamique basée sur les patterns passés
85
+ def generate_dynamic_curve(df, initial_prediction, future_hours=24, window_size=5):
86
+ dynamic_curve = []
87
+ pred_data = initial_prediction[:window_size] # Les premières données de la prédiction
88
+
89
+ # Générer une courbe en utilisant les patterns historiques de manière dynamique
90
+ for _ in range(future_hours // (window_size)):
91
+ similar_pattern = find_similar_pattern(df, pred_data, window_size)
92
+ dynamic_curve.extend(similar_pattern) # Ajoute le pattern trouvé à la courbe
93
+ pred_data = similar_pattern # Met à jour la prédiction avec le dernier pattern trouvé
94
+
95
+ return dynamic_curve
96
+
97
+ # Configuration des dates
98
+ end_time = datetime.now()
99
+ start_time = end_time - timedelta(hours=48)
100
+
101
+ # Liste des cryptos avec leurs IDs corrects sur CoinCap
102
+ coins = {
103
+ "Bitcoin": "bitcoin",
104
+ "Ripple": "xrp",
105
+ "Ethereum": "ethereum",
106
+ "Tether": "tether",
107
+ "Stellar": "stellar"
108
+ }
109
+
110
+ # Récupération des prix
111
+ crypto_prices = get_crypto_prices(coins, start_time, end_time)
112
+
113
+ # Affichage des graphiques
114
+ st.title("Analyse et Prédictions des Cryptos avec Patterns")
115
+ for coin, price_data in crypto_prices.items():
116
+ if price_data:
117
+ df = pd.DataFrame(price_data, columns=["timestamp", "price"])
118
+ df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
119
+
120
+ patterns = predict_patterns(price_data, future_hours=24)
121
+ best_pattern = identify_best_pattern(df, patterns)
122
+
123
+ st.write(f"#### {coin} - Prix et Prédictions")
124
+ fig, ax = plt.subplots(figsize=(12, 6))
125
+ ax.plot(df["timestamp"], df["price"], label="Prix réel", color="blue")
126
+
127
+ # Affiche la prédiction initiale (en jaune)
128
+ best_pattern_df = patterns[best_pattern]
129
+ ax.plot(
130
+ best_pattern_df["timestamp"],
131
+ best_pattern_df["price"],
132
+ label=f"Prédiction initiale ({best_pattern})",
133
+ linestyle="dashed",
134
+ color="yellow"
135
+ )
136
+
137
+ # Génère la courbe dynamique (en vert) basée sur les patterns historiques
138
+ dynamic_curve = generate_dynamic_curve(df, best_pattern_df["price"].values)
139
+ future_timestamps = pd.date_range(df["timestamp"].iloc[-1], periods=(24 * 60 // 15) + 1, freq="15T")
140
+ ax.plot(future_timestamps, dynamic_curve, label="Prédiction dynamique (basée sur historique)", linestyle="dashed", color="green")
141
+
142
+ ax.set_title(f"{coin} - Prix (48h réels + 24h prévu avec {best_pattern})")
143
+ ax.set_xlabel("Temps")
144
+ ax.set_ylabel("Prix (USD)")
145
+ ax.legend()
146
+ st.pyplot(fig)
147
+
148
+ # Texte explicatif du pattern choisi
149
+ explanation = {
150
+ "Trend": "Ce pattern indique que le prix continue sur la tendance actuelle, il suit la direction des prix précédents.",
151
+ "Reversal": "Ce pattern suggère que le prix pourrait inverser la tendance actuelle, en suivant la direction opposée.",
152
+ "SMA": "Le prix pourrait se stabiliser autour de la moyenne mobile simple (SMA), une approximation de la tendance générale.",
153
+ "EMA": "Ce pattern suit la moyenne mobile exponentielle (EMA), qui réagit plus rapidement aux changements de prix.",
154
+ "Cycle": "Le pattern de cycle suppose une oscillation autour d'un point central, représentant des mouvements de prix cycliques.",
155
+ "Rebound": "Le prix pourrait rebondir après avoir montré des signes de ralentissement, suivant une courbe d'amortissement.",
156
+ "Plateau": "Ce pattern suggère que le prix restera relativement stable et horizontal, sans mouvements majeurs.",
157
+ "Breakout": "Le breakout indique une rupture de la tendance actuelle, avec une direction plus forte dans une des deux directions.",
158
+ "Recovery": "Le pattern de récupération suggère que le prix pourrait revenir à sa moyenne historique après une variation importante.",
159
+ "Acceleration": "L'accélération suggère un mouvement rapide des prix, souvent après une période de stagnation ou de consolidation."
160
+ }
161
+
162
+ # Afficher l'explication sous le graphique
163
+ st.write(f"### Explication du pattern ({best_pattern}):")
164
+ st.write(explanation[best_pattern])
165
+
166
+ else:
167
+ st.warning(f"Aucune donnée disponible pour {coin}")