Enoder commited on
Commit
560c2c3
·
verified ·
1 Parent(s): 8121e1e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +144 -41
app.py CHANGED
@@ -1,48 +1,151 @@
1
  import streamlit as st
 
2
  import pandas as pd
 
3
  import numpy as np
4
- import requests
 
5
 
6
- # Fonction pour obtenir les données de la crypto-monnaie via l'API CoinCap
7
- def get_crypto_data(crypto_symbol="bitcoin", lookback=30):
8
- url = f"https://api.coincap.io/v2/assets/{crypto_symbol}/history?interval=m15"
9
- response = requests.get(url)
10
- data = response.json()
11
-
12
- # Afficher les premières lignes des données retournées pour vérifier la structure
13
- st.write("Données brutes de l'API CoinCap:", data)
14
-
15
- if 'data' not in data:
16
- st.error(f"Erreur : Impossible de récupérer les données pour {crypto_symbol}")
17
- return pd.DataFrame()
18
-
19
- # Vérifier la structure et s'assurer que les colonnes sont correctes
20
- raw_data = data['data']
21
-
22
- if len(raw_data) == 0:
23
- st.error("Aucune donnée disponible pour cette crypto-monnaie.")
24
- return pd.DataFrame()
25
-
26
- # Convertir les données en DataFrame et afficher les premières lignes pour vérifier la structure
27
- df = pd.DataFrame(raw_data)
28
- st.write("Données transformées en DataFrame:", df.head())
29
-
30
- # Vérifier les noms de colonnes avant de procéder
31
- if 'time' in df.columns:
32
- df['timestamp'] = pd.to_datetime(df['time'], unit='ms')
33
- df.set_index('timestamp', inplace=True)
34
- df.drop(columns=['time'], inplace=True) # Supprimer la colonne 'time' si nécessaire
35
- else:
36
- st.error("Le champ 'time' n'existe pas dans les données.")
37
- return pd.DataFrame()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
- return df
 
 
40
 
41
- # Exemple d'utilisation dans Streamlit
42
- crypto_symbol = "bitcoin" # Vous pouvez changer cela pour d'autres cryptos comme 'ethereum'
43
- df = get_crypto_data(crypto_symbol)
44
 
45
- if not df.empty:
46
- st.write("Données crypto:", df)
47
- else:
48
- st.write("Pas de données à afficher.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 le pattern le plus ressemblant
72
+ def identify_best_pattern(df, patterns):
73
+ mse_scores = {}
74
+ actual_values = df["price"].values[-len(df) // 2:] # Dernières heures
75
+
76
+ for pattern_name, pattern_df in patterns.items():
77
+ predicted_values = np.array(pattern_df["price"].values[:len(actual_values)])
78
+ min_length = min(len(actual_values), len(predicted_values))
79
+ mse = mean_squared_error(actual_values[:min_length], predicted_values[:min_length])
80
+ mse_scores[pattern_name] = mse
81
 
82
+ # Sélection du pattern avec la MSE la plus faible
83
+ best_pattern = min(mse_scores, key=mse_scores.get)
84
+ return best_pattern
85
 
86
+ # Configuration des dates
87
+ end_time = datetime.now()
88
+ start_time = end_time - timedelta(hours=48)
89
 
90
+ # Liste des cryptos avec leurs IDs corrects sur CoinCap
91
+ coins = {
92
+ "Bitcoin": "bitcoin",
93
+ "Ripple": "xrp",
94
+ "Ethereum": "ethereum",
95
+ "Tether": "tether",
96
+ "Stellar": "stellar"
97
+ }
98
+
99
+ # Récupération des prix
100
+ crypto_prices = get_crypto_prices(coins, start_time, end_time)
101
+
102
+ # Affichage des graphiques
103
+ st.title("Analyse et Prédictions des Cryptos avec Patterns")
104
+ for coin, price_data in crypto_prices.items():
105
+ if price_data:
106
+ df = pd.DataFrame(price_data, columns=["timestamp", "price"])
107
+ df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
108
+
109
+ patterns = predict_patterns(price_data, future_hours=24)
110
+ best_pattern = identify_best_pattern(df, patterns)
111
+
112
+ st.write(f"#### {coin} - Prix et Prédictions")
113
+ fig, ax = plt.subplots(figsize=(12, 6))
114
+ ax.plot(df["timestamp"], df["price"], label="Prix réel", color="blue")
115
+
116
+ # Affiche uniquement le meilleur pattern
117
+ best_pattern_df = patterns[best_pattern]
118
+ ax.plot(
119
+ best_pattern_df["timestamp"],
120
+ best_pattern_df["price"],
121
+ label=f"Prédiction ({best_pattern})",
122
+ linestyle="dashed",
123
+ color="orange"
124
+ )
125
+
126
+ ax.set_title(f"{coin} - Prix (48h réels + 24h prévu avec {best_pattern})")
127
+ ax.set_xlabel("Temps")
128
+ ax.set_ylabel("Prix (USD)")
129
+ ax.legend()
130
+ st.pyplot(fig)
131
+
132
+ # Texte explicatif du pattern choisi
133
+ explanation = {
134
+ "Trend": "Ce pattern indique que le prix continue sur la tendance actuelle, il suit la direction des prix précédents.",
135
+ "Reversal": "Ce pattern suggère que le prix pourrait inverser la tendance actuelle, en suivant la direction opposée.",
136
+ "SMA": "Le prix pourrait se stabiliser autour de la moyenne mobile simple (SMA), une approximation de la tendance générale.",
137
+ "EMA": "Ce pattern suit la moyenne mobile exponentielle (EMA), qui réagit plus rapidement aux changements de prix.",
138
+ "Cycle": "Le pattern de cycle suppose une oscillation autour d'un point central, représentant des mouvements de prix cycliques.",
139
+ "Rebound": "Le prix pourrait rebondir après avoir montré des signes de ralentissement, suivant une courbe d'amortissement.",
140
+ "Plateau": "Ce pattern suggère que le prix restera relativement stable et horizontal, sans mouvements majeurs.",
141
+ "Breakout": "Le breakout indique une rupture de la tendance actuelle, avec une direction plus forte dans une des deux directions.",
142
+ "Recovery": "Le pattern de récupération suggère que le prix pourrait revenir à sa moyenne historique après une variation importante.",
143
+ "Acceleration": "L'accélération suggère un mouvement rapide des prix, souvent après une période de stagnation ou de consolidation."
144
+ }
145
+
146
+ # Afficher l'explication sous le graphique
147
+ st.write(f"### Explication du pattern ({best_pattern}):")
148
+ st.write(explanation[best_pattern])
149
+
150
+ else:
151
+ st.warning(f"Aucune donnée disponible pour {coin}")