QAway-to commited on
Commit
b9d9d1e
·
1 Parent(s): e7eba34

New tabs and functions v2.1

Browse files
Files changed (3) hide show
  1. app.py +15 -14
  2. core/crypto_dashboard.py +65 -38
  3. requirements.txt +1 -1
app.py CHANGED
@@ -97,28 +97,29 @@ 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 (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(
124
  "<center><small style='color:#6e7681;'>Developed with Featherless.ai • Powered by OpenAI-compatible API</small></center>",
 
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 (Coinlore, Altair) ---
101
  with gr.TabItem("Crypto Intelligence Dashboard"):
102
+ gr.Markdown("### 💹 Coinlore Market Dashboard (Altair Edition)")
103
 
104
  with gr.Row():
105
+ top_slider = gr.Slider(label="Top N coins", minimum=20, maximum=100, step=10, value=50)
106
+ load_btn = gr.Button("Generate Dashboard", variant="primary")
 
 
 
 
107
 
108
+ treemap_plot = gr.Plot(label="Market Composition")
109
+ movers_plot = gr.Plot(label="Top Movers")
110
+ scatter_plot = gr.Plot(label="Market Cap vs Volume")
111
+ ai_box = gr.Textbox(label="AI Market Summary", lines=8, elem_id="llm_comment_box")
112
 
113
  from core.crypto_dashboard import build_crypto_dashboard
114
 
 
 
 
 
115
 
116
+ def run_dash(n): return build_crypto_dashboard(n)
117
+
118
+
119
+ load_btn.click(fn=run_dash,
120
+ inputs=top_slider,
121
+ outputs=[treemap_plot, movers_plot, scatter_plot, ai_box],
122
+ show_progress="minimal")
123
  gr.Markdown("---")
124
  gr.Markdown(
125
  "<center><small style='color:#6e7681;'>Developed with Featherless.ai • Powered by OpenAI-compatible API</small></center>",
core/crypto_dashboard.py CHANGED
@@ -1,47 +1,74 @@
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(
43
  messages=[{"role": "user", "content": prompt}],
44
  model="meta-llama/Meta-Llama-3.1-8B-Instruct"
45
  ):
46
- summary += delta
47
- return summary
 
1
  """
2
+ Coinlore Dashboard Power BI style (Altair)
3
  """
4
+ import requests, pandas as pd, altair as alt
5
  from services.llm_client import llm_service
6
+
7
+
8
+ def fetch_coinlore_data(limit=100):
9
+ url = "https://api.coinlore.net/api/tickers/"
10
+ data = requests.get(url).json()["data"]
11
+ df = pd.DataFrame(data)
12
+ for col in ["price_usd", "market_cap_usd", "volume24",
13
+ "percent_change_1h", "percent_change_24h", "percent_change_7d"]:
14
+ df[col] = pd.to_numeric(df[col], errors="coerce")
15
+ return df.head(limit)
16
+
17
+
18
+ def build_crypto_dashboard(top_n=50):
19
+ df = fetch_coinlore_data(top_n)
20
+
21
+ # === 1️⃣ Treemap imitation ===
22
+ base = alt.Chart(df).mark_rect().encode(
23
+ x=alt.X('symbol:N', title=None, axis=None),
24
+ y=alt.Y('market_cap_usd:Q', title=None, axis=None),
25
+ color=alt.Color('percent_change_24h:Q',
26
+ scale=alt.Scale(scheme='redyellowgreen'),
27
+ title='24h Change %'),
28
+ tooltip=['symbol', 'price_usd', 'market_cap_usd', 'percent_change_24h']
29
+ ).properties(title="Market Composition (Top Coins)", height=300)
30
+
31
+ # === 2️⃣ Bar chart (Top Movers 24h) ===
32
+ movers = df.sort_values("percent_change_24h", ascending=False).head(15)
33
+ bar = alt.Chart(movers).mark_bar(cornerRadiusEnd=4).encode(
34
+ x=alt.X('percent_change_24h:Q', title='Change %'),
35
+ y=alt.Y('symbol:N', sort='-x', title=None),
36
+ color=alt.Color('percent_change_24h:Q', scale=alt.Scale(scheme='greenblue')),
37
+ tooltip=['symbol', 'price_usd', 'percent_change_24h']
38
+ ).properties(title="Top 15 Gainers (24h)", height=300)
39
+
40
+ # === 3️⃣ Scatter (Market Cap vs Volume) ===
41
+ scatter = alt.Chart(df).mark_circle(size=70).encode(
42
+ x=alt.X('market_cap_usd:Q', scale=alt.Scale(type='log')),
43
+ y=alt.Y('volume24:Q', scale=alt.Scale(type='log')),
44
+ color=alt.Color('percent_change_7d:Q',
45
+ scale=alt.Scale(scheme='redyellowgreen'),
46
+ title='7d %'),
47
+ tooltip=['symbol', 'price_usd', 'market_cap_usd', 'volume24', 'percent_change_7d']
48
+ ).properties(title="Market Cap vs 24h Volume", height=350)
49
+
50
+ # === LLM summary ===
51
+ ai_comment = _generate_ai_summary(df)
52
+
53
+ return base, bar, scatter, ai_comment
54
+
55
+
56
+ def _generate_ai_summary(df):
57
+ leaders = df.sort_values("percent_change_24h", ascending=False).head(3)
58
+ laggards = df.sort_values("percent_change_24h").head(3)
59
  prompt = f"""
60
+ Provide a brief professional summary of today's crypto market based on Coinlore data.
61
+ Top gainers: {', '.join(leaders['symbol'].tolist())}.
62
+ Top losers: {', '.join(laggards['symbol'].tolist())}.
63
+ Include:
64
+ - general sentiment
65
+ - volatility trend
66
+ - short-term outlook (bullish/bearish)
67
  """
68
+ text = ""
69
  for delta in llm_service.stream_chat(
70
  messages=[{"role": "user", "content": prompt}],
71
  model="meta-llama/Meta-Llama-3.1-8B-Instruct"
72
  ):
73
+ text += delta
74
+ return text
requirements.txt CHANGED
@@ -7,4 +7,4 @@ matplotlib
7
  plotly
8
  yfinance>=0.2.43
9
  plotly>=6.3.1
10
-
 
7
  plotly
8
  yfinance>=0.2.43
9
  plotly>=6.3.1
10
+ altair