import gradio as gr import plotly.graph_objects as go import requests import os import datetime import random import time # Set the base currency (USD) and available cryptocurrencies base_currency = "USD" cryptos = ["BTC", "ETH", "XMR", "ETC", "RVN", "KAS", "DOGE", "LTC"] colors = ["red", "blue", "green", "orange", "purple", "yellow", "gold", "aqua", "fuchsia", "chartreuse", "coral", "maroon", "olive"] # Retrieve API key from environment variables api_key = os.getenv("CRYPTOCOMPARE_API_KEY") def fetch_crypto_data(crypto): """Fetches historical price data for the selected cryptocurrency.""" crypto_prices = [] crypto_dates = [] current_timestamp = int(time.time()) end_date = current_timestamp limit = 365 # Max limit per API call total_data_points = 0 while total_data_points < limit: url = f"https://min-api.cryptocompare.com/data/v2/histoday?fsym={crypto}&tsym={base_currency}&limit={limit}&toTs={end_date}&api_key={api_key}" response = requests.get(url) data = response.json() if "Data" not in data or "Data" not in data["Data"]: return "Error fetching data. Please check API key and limits." data_points = len(data["Data"]["Data"]) total_data_points += data_points crypto_prices += [x["close"] for x in data["Data"]["Data"]] crypto_dates += [x["time"] for x in data["Data"]["Data"]] end_date = data["Data"]["Data"][-1]["time"] - 86400 crypto_dates = [datetime.datetime.fromtimestamp(x).strftime("%Y-%m-%d") for x in crypto_dates] return crypto_dates, crypto_prices def plot_crypto_prices(): """Creates individual plots for each cryptocurrency with a filled area below the line.""" figures = [] for crypto in cryptos: crypto_dates, crypto_prices = fetch_crypto_data(crypto) if isinstance(crypto_dates, str): continue # Skip on error line_color = random.choice(colors) fill_color = random.choice(colors) fig = go.Figure() fig.add_trace(go.Scatter(x=crypto_dates, y=crypto_prices, mode='lines', name=crypto, line=dict(color=line_color))) fig.add_trace(go.Scatter(x=crypto_dates, y=crypto_prices, fill='tozeroy', fillcolor=fill_color, mode='none', name=f"{crypto} Fill")) fig.update_layout( title=f"{crypto} Price History", xaxis_title="Date", yaxis_title="Price (USD)", template="plotly_dark", xaxis=dict(tickangle=-45), legend_title=crypto ) figures.append(fig) return figures # Create Gradio Interface demo = gr.Interface( fn=plot_crypto_prices, inputs=[], outputs=[gr.Plot(label=f"{crypto} Price Chart") for crypto in cryptos], title="Cryptocurrency Price Visualization", description="Displays historical price data for multiple cryptocurrencies over the past year, with filled areas below the lines." ) if __name__ == "__main__": demo.launch(debug=True)