Spaces:
Sleeping
Sleeping
QAway-to
commited on
Commit
Β·
e7eba34
1
Parent(s):
c02f97a
New tabs and functions v2.0
Browse files- app.py +16 -20
- core/crypto_dashboard.py +31 -100
- core/data_binance.py +22 -0
- core/data_coinlore.py +13 -0
- core/data_yfinance.py +16 -0
app.py
CHANGED
|
@@ -97,31 +97,27 @@ with gr.Blocks(theme=dark_theme, css="""
|
|
| 97 |
chart_out = gr.Plot(label="Alpha vs BTC")
|
| 98 |
chart_btn.click(fn=build_alpha_chart, inputs=chart_in, outputs=chart_out)
|
| 99 |
|
| 100 |
-
# --- Crypto Intelligence Dashboard (
|
| 101 |
with gr.TabItem("Crypto Intelligence Dashboard"):
|
| 102 |
-
gr.Markdown("###
|
| 103 |
|
| 104 |
with gr.Row():
|
| 105 |
-
|
| 106 |
-
label="Select
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
price_plot = gr.Plot(label="Recent Market (Binance)")
|
| 115 |
-
hist_plot = gr.Plot(label="Historical Chart (TradingView)")
|
| 116 |
-
ai_summary = gr.Textbox(label="AI Market Summary", lines=8, elem_id="llm_comment_box")
|
| 117 |
|
| 118 |
from core.crypto_dashboard import build_crypto_dashboard
|
| 119 |
-
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
|
| 123 |
-
|
| 124 |
-
)
|
| 125 |
|
| 126 |
gr.Markdown("---")
|
| 127 |
gr.Markdown(
|
|
|
|
| 97 |
chart_out = gr.Plot(label="Alpha vs BTC")
|
| 98 |
chart_btn.click(fn=build_alpha_chart, inputs=chart_in, outputs=chart_out)
|
| 99 |
|
| 100 |
+
# --- Crypto Intelligence Dashboard (final Power BI style) ---
|
| 101 |
with gr.TabItem("Crypto Intelligence Dashboard"):
|
| 102 |
+
gr.Markdown("### πΉ Multi-Source Market Dashboard")
|
| 103 |
|
| 104 |
with gr.Row():
|
| 105 |
+
data_source = gr.Radio(
|
| 106 |
+
["Binance", "Coinlore", "Yahoo"], label="Select Data Source", value="Binance")
|
| 107 |
+
asset_select = gr.CheckboxGroup(
|
| 108 |
+
label="Assets", choices=["BTCUSDT", "ETHUSDT", "BNBUSDT", "SOLUSDT", "DOGEUSDT"],
|
| 109 |
+
value=["BTCUSDT", "ETHUSDT"])
|
| 110 |
+
load_btn = gr.Button("Build Dashboard", variant="primary")
|
| 111 |
+
|
| 112 |
+
chart = gr.Plot(label="Market Visualization")
|
| 113 |
+
ai_box = gr.Textbox(label="AI Summary", lines=8, elem_id="llm_comment_box")
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
from core.crypto_dashboard import build_crypto_dashboard
|
| 116 |
+
|
| 117 |
+
load_btn.click(fn=build_crypto_dashboard,
|
| 118 |
+
inputs=[data_source, asset_select],
|
| 119 |
+
outputs=[chart, ai_box],
|
| 120 |
+
show_progress="minimal")
|
|
|
|
| 121 |
|
| 122 |
gr.Markdown("---")
|
| 123 |
gr.Markdown(
|
core/crypto_dashboard.py
CHANGED
|
@@ -1,111 +1,42 @@
|
|
| 1 |
"""
|
| 2 |
-
|
| 3 |
-
Purpose: Unified dashboard for live & historical crypto analytics (Binance + Yahoo Finance)
|
| 4 |
-
π·πΊ ΠΠΎΠ΄ΡΠ»Ρ: crypto_dashboard.py
|
| 5 |
-
ΠΠ°Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅: ΠΠ΄ΠΈΠ½ΡΠΉ Π΄Π°ΡΠ±ΠΎΡΠ΄ Π΄Π»Ρ Π°Π½Π°Π»ΠΈΠ·Π° ΠΊΡΠΈΠΏΡΠΎΡΡΠ½ΠΊΠ° Π½Π° Binance ΠΈ Yahoo.
|
| 6 |
"""
|
| 7 |
-
|
| 8 |
-
import requests
|
| 9 |
-
import pandas as pd
|
| 10 |
-
import yfinance as yf
|
| 11 |
-
import plotly.express as px
|
| 12 |
-
import plotly.graph_objects as go
|
| 13 |
from services.llm_client import llm_service
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
ticker = s.replace("USDT", "-USD")
|
| 37 |
-
df = yf.download(ticker, period="5y", interval="1d", progress=False)
|
| 38 |
-
df = df.reset_index()[["Date", "Close"]]
|
| 39 |
-
df.columns = ["datetime", "close"]
|
| 40 |
-
df["symbol"] = s
|
| 41 |
-
frames.append(df)
|
| 42 |
-
except Exception:
|
| 43 |
-
continue
|
| 44 |
-
if not frames:
|
| 45 |
-
return pd.DataFrame()
|
| 46 |
-
return pd.concat(frames, ignore_index=True)
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
# === Build Dashboard ===
|
| 50 |
-
def build_crypto_dashboard(selected_assets: list[str], start_date: str, end_date: str):
|
| 51 |
-
if not selected_assets:
|
| 52 |
-
selected_assets = ["BTCUSDT", "ETHUSDT", "BNBUSDT"]
|
| 53 |
-
|
| 54 |
-
# --- Binance recent ---
|
| 55 |
-
recent_frames = []
|
| 56 |
-
for sym in selected_assets:
|
| 57 |
-
df = get_binance_klines(sym, "1d", 180)
|
| 58 |
-
recent_frames.append(df.assign(symbol=sym))
|
| 59 |
-
df_recent = pd.concat(recent_frames)
|
| 60 |
-
|
| 61 |
-
fig_recent = px.line(
|
| 62 |
-
df_recent, x="timestamp", y="close", color="symbol",
|
| 63 |
-
title="Market Prices (Binance, recent 6 months)",
|
| 64 |
-
template="plotly_dark"
|
| 65 |
-
)
|
| 66 |
-
fig_recent.update_layout(height=420, legend_title_text="Asset")
|
| 67 |
-
|
| 68 |
-
# --- Yahoo historical normalized ---
|
| 69 |
-
df_hist = get_yf_history(selected_assets)
|
| 70 |
-
if not df_hist.empty:
|
| 71 |
-
df_hist["returns"] = df_hist.groupby("symbol")["close"].apply(lambda x: x / x.iloc[0] - 1)
|
| 72 |
-
fig_hist = px.line(df_hist, x="datetime", y="returns", color="symbol",
|
| 73 |
-
title="Historical Normalized Performance (Yahoo Finance)",
|
| 74 |
-
template="plotly_dark")
|
| 75 |
-
fig_hist.update_layout(height=420)
|
| 76 |
else:
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
text="No Yahoo Finance data available",
|
| 80 |
-
xref="paper", yref="paper", x=0.5, y=0.5, showarrow=False
|
| 81 |
-
)
|
| 82 |
-
|
| 83 |
-
# --- AI Market Summary ---
|
| 84 |
-
summary = _generate_ai_summary(df_recent, df_hist, selected_assets)
|
| 85 |
-
|
| 86 |
-
return fig_recent, fig_hist, summary
|
| 87 |
-
|
| 88 |
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
return "β No data available to summarize."
|
| 92 |
|
| 93 |
-
growth = []
|
| 94 |
-
for a in assets:
|
| 95 |
-
sub = df_recent[df_recent["symbol"] == a]
|
| 96 |
-
if len(sub) > 5:
|
| 97 |
-
g = (sub["close"].iloc[-1] / sub["close"].iloc[0] - 1) * 100
|
| 98 |
-
growth.append(f"{a}: {g:.2f}%")
|
| 99 |
-
growth_text = ", ".join(growth)
|
| 100 |
|
|
|
|
| 101 |
prompt = f"""
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
Give a concise professional summary:
|
| 105 |
-
- Market direction (bullish/bearish)
|
| 106 |
-
- Volatility trends
|
| 107 |
-
- Leaders vs laggards
|
| 108 |
-
- Short-term outlook
|
| 109 |
"""
|
| 110 |
summary = ""
|
| 111 |
for delta in llm_service.stream_chat(
|
|
|
|
| 1 |
"""
|
| 2 |
+
Power-BI-style dashboard combining Binance, Coinlore, and Yahoo Finance
|
|
|
|
|
|
|
|
|
|
| 3 |
"""
|
| 4 |
+
import plotly.express as px, plotly.graph_objects as go
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
from services.llm_client import llm_service
|
| 6 |
+
from core.data_binance import get_binance_data
|
| 7 |
+
from core.data_coinlore import get_coinlore_data
|
| 8 |
+
from core.data_yfinance import get_yf_history
|
| 9 |
+
|
| 10 |
+
def build_crypto_dashboard(source: str, symbols: list[str]):
|
| 11 |
+
if source == "Binance":
|
| 12 |
+
df = get_binance_data(symbols)
|
| 13 |
+
fig = px.line(df, x="timestamp", y="close", color="symbol",
|
| 14 |
+
title="Binance Price History (1y)", template="plotly_dark")
|
| 15 |
+
elif source == "Yahoo":
|
| 16 |
+
df = get_yf_history([s.replace("USDT","-USD") for s in symbols])
|
| 17 |
+
df["returns"] = df.groupby("symbol")["close"].apply(lambda x: x/x.iloc[0]-1)
|
| 18 |
+
fig = px.line(df, x="timestamp", y="returns", color="symbol",
|
| 19 |
+
title="Yahoo Finance β Normalized Returns (2y)", template="plotly_dark")
|
| 20 |
+
elif source == "Coinlore":
|
| 21 |
+
df = get_coinlore_data().head(25)
|
| 22 |
+
fig = px.treemap(df,
|
| 23 |
+
path=["symbol"], values="market_cap_usd",
|
| 24 |
+
color="percent_change_24h",
|
| 25 |
+
color_continuous_scale="RdYlGn",
|
| 26 |
+
title="Coinlore Market Treemap (Top 25)",
|
| 27 |
+
template="plotly_dark")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
else:
|
| 29 |
+
fig = go.Figure()
|
| 30 |
+
fig.add_annotation(text="Unknown data source", x=0.5, y=0.5, showarrow=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
+
insight = _generate_ai_summary(source, symbols)
|
| 33 |
+
return fig, insight
|
|
|
|
| 34 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
| 36 |
+
def _generate_ai_summary(source, symbols):
|
| 37 |
prompt = f"""
|
| 38 |
+
Summarize crypto market from {source} for assets: {', '.join(symbols)}.
|
| 39 |
+
Describe trend, volatility, and investor sentiment.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
"""
|
| 41 |
summary = ""
|
| 42 |
for delta in llm_service.stream_chat(
|
core/data_binance.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Binance API Handler β public OHLC data
|
| 3 |
+
"""
|
| 4 |
+
import requests, pandas as pd
|
| 5 |
+
|
| 6 |
+
BINANCE = "https://api.binance.com/api/v3"
|
| 7 |
+
|
| 8 |
+
def get_binance_data(symbols=None, limit=500):
|
| 9 |
+
if symbols is None:
|
| 10 |
+
symbols = ["BTCUSDT", "ETHUSDT", "BNBUSDT"]
|
| 11 |
+
frames = []
|
| 12 |
+
for s in symbols:
|
| 13 |
+
url = f"{BINANCE}/klines?symbol={s}&interval=1d&limit={limit}"
|
| 14 |
+
r = requests.get(url).json()
|
| 15 |
+
df = pd.DataFrame(r, columns=[
|
| 16 |
+
"t","o","h","l","c","v","ct","qv","tr","tb","tbv","ig"])
|
| 17 |
+
df = df[["t","c"]].rename(columns={"t":"timestamp","c":"close"})
|
| 18 |
+
df["timestamp"] = pd.to_datetime(df["timestamp"], unit="ms")
|
| 19 |
+
df["close"] = df["close"].astype(float)
|
| 20 |
+
df["symbol"] = s
|
| 21 |
+
frames.append(df)
|
| 22 |
+
return pd.concat(frames)
|
core/data_coinlore.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Coinlore API Handler β market overview
|
| 3 |
+
"""
|
| 4 |
+
import requests, pandas as pd
|
| 5 |
+
|
| 6 |
+
def get_coinlore_data():
|
| 7 |
+
url = "https://api.coinlore.net/api/tickers/"
|
| 8 |
+
data = requests.get(url).json()["data"]
|
| 9 |
+
df = pd.DataFrame(data)
|
| 10 |
+
df["price_usd"] = df["price_usd"].astype(float)
|
| 11 |
+
df["market_cap_usd"] = df["market_cap_usd"].astype(float)
|
| 12 |
+
df["percent_change_24h"] = df["percent_change_24h"].astype(float)
|
| 13 |
+
return df
|
core/data_yfinance.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Yahoo Finance API Handler β historical 5-10 years
|
| 3 |
+
"""
|
| 4 |
+
import yfinance as yf, pandas as pd
|
| 5 |
+
|
| 6 |
+
def get_yf_history(symbols=None, period="2y"):
|
| 7 |
+
if symbols is None:
|
| 8 |
+
symbols = ["BTC-USD","ETH-USD","BNB-USD"]
|
| 9 |
+
frames = []
|
| 10 |
+
for s in symbols:
|
| 11 |
+
df = yf.download(s, period=period, interval="1d", progress=False)
|
| 12 |
+
df = df.reset_index()[["Date","Close"]]
|
| 13 |
+
df.columns = ["timestamp","close"]
|
| 14 |
+
df["symbol"] = s.replace("-USD","USDT")
|
| 15 |
+
frames.append(df)
|
| 16 |
+
return pd.concat(frames)
|