import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
from typing import Dict, Any, List
import pandas as pd
from datetime import datetime
def create_price_chart(data: Dict[str, Any], symbol: str) -> str:
try:
if not data or "prices" not in data:
return f"
No price data available for {symbol.upper()}
"
prices = data["prices"]
volumes = data.get("total_volumes", [])
if not prices:
return f"No price history found for {symbol.upper()}
"
df = pd.DataFrame(prices, columns=["timestamp", "price"])
df["datetime"] = pd.to_datetime(df["timestamp"], unit="ms")
fig = make_subplots(
rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.05,
subplot_titles=[f"{symbol.upper()} Price Chart", "Volume"],
row_width=[0.7, 0.3]
)
fig.add_trace(
go.Scatter(
x=df["datetime"],
y=df["price"],
mode="lines",
name="Price",
line=dict(color="#00D4AA", width=2),
hovertemplate="%{y:$,.2f}
%{x}"
),
row=1, col=1
)
if volumes:
vol_df = pd.DataFrame(volumes, columns=["timestamp", "volume"])
vol_df["datetime"] = pd.to_datetime(vol_df["timestamp"], unit="ms")
fig.add_trace(
go.Bar(
x=vol_df["datetime"],
y=vol_df["volume"],
name="Volume",
marker_color="#FF6B6B",
opacity=0.7,
hovertemplate="$%{y:,.0f}
%{x}"
),
row=2, col=1
)
current_price = df["price"].iloc[-1]
price_change = ((df["price"].iloc[-1] - df["price"].iloc[0]) / df["price"].iloc[0]) * 100
fig.update_layout(
title=dict(
text=f"{symbol.upper()} - ${current_price:,.4f} ({price_change:+.2f}%)",
x=0.5,
font=dict(size=20, color="#FFFFFF")
),
xaxis_title="Date",
yaxis_title="Price (USD)",
template="plotly_dark",
showlegend=False,
height=600,
margin=dict(l=60, r=60, t=80, b=60),
plot_bgcolor="rgba(0,0,0,0)",
paper_bgcolor="rgba(0,0,0,0)"
)
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="rgba(255,255,255,0.1)")
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="rgba(255,255,255,0.1)")
return fig.to_html(include_plotlyjs="cdn", div_id=f"chart_{symbol}")
except Exception as e:
return f"Chart generation failed: {str(e)}
"
def create_market_overview(data: Dict[str, Any]) -> str:
try:
if not data or "market_data" not in data:
return "Market data unavailable
"
market_data = data["market_data"]
if not market_data:
return "No market data found
"
df = pd.DataFrame(market_data)
df = df.head(20)
fig = make_subplots(
rows=2, cols=2,
subplot_titles=[
"Market Cap Distribution",
"24h Price Changes",
"Trading Volume",
"Price vs Volume"
],
specs=[[{"type": "pie"}, {"type": "bar"}],
[{"type": "bar"}, {"type": "scatter"}]]
)
fig.add_trace(
go.Pie(
labels=df["symbol"].str.upper(),
values=df["market_cap"],
textinfo="label+percent",
textposition="inside",
marker=dict(colors=px.colors.qualitative.Set3),
hovertemplate="%{label}
Market Cap: $%{value:,.0f}"
),
row=1, col=1
)
colors = ["#00D4AA" if x >= 0 else "#FF6B6B" for x in df["price_change_percentage_24h"]]
fig.add_trace(
go.Bar(
x=df["symbol"].str.upper(),
y=df["price_change_percentage_24h"],
marker_color=colors,
hovertemplate="%{x}
24h Change: %{y:+.2f}%"
),
row=1, col=2
)
fig.add_trace(
go.Bar(
x=df["symbol"].str.upper(),
y=df["total_volume"],
marker_color="#4ECDC4",
hovertemplate="%{x}
Volume: $%{y:,.0f}"
),
row=2, col=1
)
fig.add_trace(
go.Scatter(
x=df["current_price"],
y=df["total_volume"],
mode="markers+text",
text=df["symbol"].str.upper(),
textposition="top center",
marker=dict(
size=df["market_cap"] / df["market_cap"].max() * 50 + 10,
color=df["price_change_percentage_24h"],
colorscale="RdYlGn",
colorbar=dict(title="24h Change %"),
line=dict(width=1, color="white")
),
hovertemplate="%{text}
Price: $%{x:,.4f}
Volume: $%{y:,.0f}"
),
row=2, col=2
)
global_info = data.get("global_data", {}).get("data", {})
total_mcap = global_info.get("total_market_cap", {}).get("usd", 0)
total_volume = global_info.get("total_volume", {}).get("usd", 0)
btc_dominance = global_info.get("market_cap_percentage", {}).get("btc", 0)
title_text = f"Crypto Market Overview - Total MCap: ${total_mcap/1e12:.2f}T | 24h Vol: ${total_volume/1e9:.0f}B | BTC Dom: {btc_dominance:.1f}%"
fig.update_layout(
title=dict(
text=title_text,
x=0.5,
font=dict(size=16, color="#FFFFFF")
),
template="plotly_dark",
showlegend=False,
height=800,
margin=dict(l=60, r=60, t=100, b=60),
plot_bgcolor="rgba(0,0,0,0)",
paper_bgcolor="rgba(0,0,0,0)"
)
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor="rgba(255,255,255,0.1)")
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor="rgba(255,255,255,0.1)")
return fig.to_html(include_plotlyjs="cdn", div_id="market_overview")
except Exception as e:
return f"Market overview failed: {str(e)}
"
def create_comparison_chart(coins_data: List[Dict[str, Any]]) -> str:
try:
if not coins_data:
return "No comparison data available
"
df = pd.DataFrame(coins_data)
fig = make_subplots(
rows=1, cols=2,
subplot_titles=["Price Comparison", "Market Cap Comparison"]
)
colors = px.colors.qualitative.Set1[:len(df)]
for i, (_, coin) in enumerate(df.iterrows()):
fig.add_trace(
go.Bar(
name=coin["symbol"].upper(),
x=[coin["symbol"].upper()],
y=[coin["current_price"]],
marker_color=colors[i],
hovertemplate=f"{coin['name']}
Price: $%{{y:,.4f}}"
),
row=1, col=1
)
fig.add_trace(
go.Bar(
name=coin["symbol"].upper(),
x=[coin["symbol"].upper()],
y=[coin["market_cap"]],
marker_color=colors[i],
showlegend=False,
hovertemplate=f"{coin['name']}
Market Cap: $%{{y:,.0f}}"
),
row=1, col=2
)
fig.update_layout(
title="Cryptocurrency Comparison",
template="plotly_dark",
height=500,
showlegend=True
)
return fig.to_html(include_plotlyjs="cdn", div_id="comparison_chart")
except Exception as e:
return f"Comparison chart failed: {str(e)}
"