File size: 3,053 Bytes
c66a623
bca40a6
c66a623
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bca40a6
1f79e01
 
c66a623
bca40a6
 
 
 
 
 
1f79e01
 
 
 
 
 
c66a623
1f79e01
 
 
 
 
 
 
 
 
 
c66a623
1f79e01
c66a623
 
 
bca40a6
 
1f79e01
c66a623
1f79e01
c66a623
 
 
1f79e01
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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)