Spaces:
Sleeping
Sleeping
Create backend.py
Browse files- backend.py +132 -0
backend.py
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pandas as pd
|
| 2 |
+
import requests
|
| 3 |
+
import random
|
| 4 |
+
from datetime import datetime, timedelta
|
| 5 |
+
|
| 6 |
+
# -----------------------------
|
| 7 |
+
# Fetch BTC Data
|
| 8 |
+
# -----------------------------
|
| 9 |
+
def fetch_btc_data():
|
| 10 |
+
try:
|
| 11 |
+
url = "https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=50"
|
| 12 |
+
res = requests.get(url, timeout=10)
|
| 13 |
+
res.raise_for_status()
|
| 14 |
+
data = res.json()
|
| 15 |
+
prices = data['prices']
|
| 16 |
+
df = pd.DataFrame(prices, columns=['time', 'close'])
|
| 17 |
+
df['time'] = pd.to_datetime(df['time'], unit='ms')
|
| 18 |
+
return df
|
| 19 |
+
except Exception as e:
|
| 20 |
+
print(f"Error fetching BTC data: {e}")
|
| 21 |
+
return pd.DataFrame()
|
| 22 |
+
|
| 23 |
+
# -----------------------------
|
| 24 |
+
# Simulated Prediction
|
| 25 |
+
# -----------------------------
|
| 26 |
+
def simulate_lstm_prediction(df, hours_ahead=0):
|
| 27 |
+
if df.empty or len(df) < 5:
|
| 28 |
+
return None, None, None
|
| 29 |
+
|
| 30 |
+
current_price = df.iloc[-1]['close']
|
| 31 |
+
momentum = (df.iloc[-1]['close'] - df.iloc[-5]['close']) / df.iloc[-5]['close']
|
| 32 |
+
|
| 33 |
+
time_factor = hours_ahead * 0.015
|
| 34 |
+
variance = (random.random() - 0.5) * (0.04 + time_factor)
|
| 35 |
+
|
| 36 |
+
pred_price = current_price * (1 + (momentum * 0.35) + variance)
|
| 37 |
+
trend = "HIGH β" if pred_price > current_price else "LOW β"
|
| 38 |
+
confidence = random.uniform(65, 92)
|
| 39 |
+
|
| 40 |
+
return pred_price, trend, confidence
|
| 41 |
+
|
| 42 |
+
# -----------------------------
|
| 43 |
+
# Create Plot
|
| 44 |
+
# -----------------------------
|
| 45 |
+
def create_plot(df):
|
| 46 |
+
import plotly.graph_objects as go
|
| 47 |
+
|
| 48 |
+
if df.empty:
|
| 49 |
+
fig = go.Figure()
|
| 50 |
+
fig.update_layout(template="plotly_dark", height=400,
|
| 51 |
+
annotations=[dict(text="No data available", x=0.5, y=0.5, showarrow=False, font=dict(size=20))])
|
| 52 |
+
return fig
|
| 53 |
+
|
| 54 |
+
fig = go.Figure()
|
| 55 |
+
fig.add_trace(go.Scatter(x=df['time'], y=df['close'], mode='lines', name='BTC Price',
|
| 56 |
+
line=dict(color='#3b82f6', width=4), fill='tozeroy', fillcolor='rgba(59, 130, 246, 0.1)'))
|
| 57 |
+
|
| 58 |
+
fig.update_layout(template="plotly_dark", height=400, margin=dict(l=0,r=0,t=0,b=0),
|
| 59 |
+
xaxis=dict(showgrid=False, title="Date"),
|
| 60 |
+
yaxis=dict(showgrid=True, gridcolor='rgba(255,255,255,0.05)', title="Price (USD)"))
|
| 61 |
+
return fig
|
| 62 |
+
|
| 63 |
+
# -----------------------------
|
| 64 |
+
# Main Backend Function
|
| 65 |
+
# -----------------------------
|
| 66 |
+
def run_dashboard():
|
| 67 |
+
df = fetch_btc_data()
|
| 68 |
+
current_time = datetime.utcnow() + timedelta(hours=5) # PKT Time
|
| 69 |
+
|
| 70 |
+
if df.empty:
|
| 71 |
+
error_html = "<div style='text-align:center;padding:30px;color:#ef4444;'>β οΈ Unable to fetch data</div>"
|
| 72 |
+
return None, error_html, error_html, error_html, error_html, error_html
|
| 73 |
+
|
| 74 |
+
current_price = df.iloc[-1]['close']
|
| 75 |
+
current_box = f"""
|
| 76 |
+
<div class='current-price-card' style='text-align: center; padding: 20px;'>
|
| 77 |
+
<div style='margin-bottom: 8px;'><span style='font-size: 0.75rem; color: #fbbf24;'>π {current_time.strftime('%H:%M')}</span></div>
|
| 78 |
+
<div style='font-size: 2rem; font-weight: 900; color: #fbbf24;'>${current_price:,.2f}</div>
|
| 79 |
+
<div style='font-size: 0.75rem; color: #fcd34d;'>Current Bitcoin Price</div>
|
| 80 |
+
</div>
|
| 81 |
+
"""
|
| 82 |
+
|
| 83 |
+
# 1 Hour
|
| 84 |
+
p1, t1, c1 = simulate_lstm_prediction(df, 1)
|
| 85 |
+
time1 = current_time + timedelta(hours=1)
|
| 86 |
+
pred1 = format_prediction_box(time1.strftime("%H:%M"), p1, t1, c1)
|
| 87 |
+
|
| 88 |
+
# 2 Hours
|
| 89 |
+
p2, t2, c2 = simulate_lstm_prediction(df, 2)
|
| 90 |
+
time2 = current_time + timedelta(hours=2)
|
| 91 |
+
pred2 = format_prediction_box(time2.strftime("%H:%M"), p2, t2, c2)
|
| 92 |
+
|
| 93 |
+
# 1 Day
|
| 94 |
+
p3, t3, c3 = simulate_lstm_prediction(df, 24)
|
| 95 |
+
time3 = current_time + timedelta(hours=24)
|
| 96 |
+
pred3 = format_prediction_box(time3.strftime("%b %d, %H:%M"), p3, t3, c3)
|
| 97 |
+
|
| 98 |
+
plot = create_plot(df)
|
| 99 |
+
|
| 100 |
+
analysis = f"""
|
| 101 |
+
<div class='analysis-box' style='text-align: center; padding: 16px;'>
|
| 102 |
+
<p style='color: #e0e7ff; font-size: 0.85rem; font-style: italic;'>π‘ {random.choice([
|
| 103 |
+
"Momentum persistence detected in recent sequences.",
|
| 104 |
+
"Strong correlation with historical breakout patterns.",
|
| 105 |
+
"Attention mechanisms highlighting key support levels."
|
| 106 |
+
])}</p>
|
| 107 |
+
</div>
|
| 108 |
+
"""
|
| 109 |
+
|
| 110 |
+
return plot, current_box, pred1, pred2, pred3, analysis
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
# Helper function for prediction box
|
| 114 |
+
def format_prediction_box(time_str, price, trend, confidence):
|
| 115 |
+
if price is None:
|
| 116 |
+
return "<div class='price-card' style='text-align:center;padding:20px;'><p style='color:#ef4444;'>Prediction unavailable</p></div>"
|
| 117 |
+
|
| 118 |
+
if "HIGH" in trend:
|
| 119 |
+
color = "#34d399"; icon = "π"; bg = "rgba(52, 211, 153, 0.1)"
|
| 120 |
+
else:
|
| 121 |
+
color = "#f87171"; icon = "π"; bg = "rgba(248, 113, 113, 0.1)"
|
| 122 |
+
|
| 123 |
+
return f"""
|
| 124 |
+
<div class='price-card' style='text-align: center; padding: 20px;'>
|
| 125 |
+
<div style='margin-bottom:5px;'><span style='font-size:0.75rem;color:#94a3b8;'>π {time_str}</span></div>
|
| 126 |
+
<div style='font-size:1.5rem;font-weight:800;color:#e0e7ff;margin:8px 0;'>${price:,.2f}</div>
|
| 127 |
+
<div style='background:{bg};padding:6px 12px;border-radius:16px;display:inline-block;'>
|
| 128 |
+
<span style='color:{color};font-weight:700;'>{icon} {trend}</span>
|
| 129 |
+
</div>
|
| 130 |
+
<div style='margin-top:5px;font-size:0.7rem;color:#cbd5e1;'>Confidence: {confidence:.0f}%</div>
|
| 131 |
+
</div>
|
| 132 |
+
"""
|