Spaces:
Running
Running
import panel as pn | |
import pandas as pd | |
import numpy as np | |
import hvplot.pandas | |
import asyncio | |
from datetime import datetime, timedelta | |
pn.extension('tabulator', 'plotly', sizing_mode="stretch_width") | |
# --- Dummy Data Generator --- | |
def generate_dummy_data(n=100): | |
start = datetime.now() - timedelta(minutes=n) | |
times = [start + timedelta(minutes=i) for i in range(n)] | |
prices = 100 + np.random.randn(n).cumsum() | |
return pd.DataFrame({'Time': times, 'Price': prices}).set_index('Time') | |
def generate_ai_signal(price): | |
mod = price % 10 | |
if mod < 3: | |
return 'BUY', 'green' | |
elif mod > 7: | |
return 'SELL', 'red' | |
return 'HOLD', 'orange' | |
data = generate_dummy_data() | |
signal, color = generate_ai_signal(data['Price'].iloc[-1]) | |
# --- Widgets --- | |
symbol_input = pn.widgets.TextInput(name='Stock Symbol', value='AI_STOCK') | |
interval_slider = pn.widgets.IntSlider(name='Update Interval (s)', start=1, end=10, step=1, value=2) | |
signal_display = pn.indicators.Number( | |
name='AI Signal', | |
value=0, | |
format=signal, | |
font_size='36pt', | |
colors=[(999, color)] | |
) | |
metrics_table = pn.widgets.Tabulator(pd.DataFrame({ | |
'Metric': ['Win Rate', 'Profit Factor', 'Sharpe Ratio'], | |
'Value': ['62%', '1.85', '1.2'] | |
}), disabled=True, selectable=False) | |
chart = data.hvplot.line(y='Price', title="π Live Stock Price", height=400, line_width=3).opts(yformatter="%.2f") | |
stream = hvplot.streams.Buffer(data, index=False, length=100) | |
chart.update(stream) | |
# --- Layout --- | |
sidebar = pn.Column( | |
"## βοΈ Controls", symbol_input, interval_slider, | |
"## π€ AI Signal", signal_display, | |
"## π Metrics", metrics_table, | |
width=300 | |
) | |
main_area = pn.Column(chart) | |
template = pn.template.FastListTemplate( | |
site="AI Trader", | |
title="π AI Trading Dashboard", | |
sidebar=[sidebar], | |
main=[main_area] | |
) | |
# --- Async Update Logic --- | |
async def updater(): | |
while True: | |
await asyncio.sleep(interval_slider.value) | |
new_time = data.index[-1] + timedelta(seconds=10) | |
new_price = data['Price'].iloc[-1] + np.random.randn() * 0.5 | |
new_df = pd.DataFrame([{'Time': new_time, 'Price': new_price}]).set_index('Time') | |
stream.send(new_df) | |
new_signal, new_color = generate_ai_signal(new_price) | |
signal_display.format = new_signal | |
signal_display.colors = [(999, new_color)] | |
template.servable() | |
pn.state.onload(updater) | |