Spaces:
Running
Running
import io | |
import pandas as pd | |
import FinanceDataReader as fdr | |
import plotly.graph_objects as go | |
import gradio as gr | |
from concurrent.futures import ThreadPoolExecutor, as_completed | |
import yfinance as yf | |
def get_stock_prices(stock_code, days): | |
try: | |
if stock_code.isdigit(): | |
df = fdr.DataReader(stock_code) | |
end_date = pd.to_datetime('today') | |
start_date = pd.date_range(end=end_date, periods=days, freq='B')[0] | |
df = df[(df.index >= start_date) & (df.index <= end_date)] | |
else: | |
stock = yf.Ticker(stock_code) | |
end_date = pd.to_datetime('today') | |
start_date = end_date - pd.DateOffset(days=days) | |
df = stock.history(start=start_date, end=end_date) | |
# Convert timezone-aware datetime index to timezone-naive | |
df.index = df.index.tz_localize(None) | |
df = df[(df.index >= start_date) & (df.index <= end_date)] | |
if df.empty: | |
print(f"<p style='color: red;'>No data available for {stock_code}</p>") | |
return None | |
return df['Close'] | |
except Exception as e: | |
print(f"<p style='color: red;'>Failed to fetch data for {stock_code}: {e}</p>") | |
return None | |
import plotly.graph_objects as go | |
from concurrent.futures import ThreadPoolExecutor, as_completed | |
def share_price_trend(stock_codes, days): | |
stock_prices = {} | |
# Assume `get_stock_prices` is defined elsewhere | |
with ThreadPoolExecutor(max_workers=10) as executor: | |
futures = {executor.submit(get_stock_prices, stock_code.strip(), int(days)): stock_code.strip() for stock_code in stock_codes.split(',')} | |
for future in as_completed(futures): | |
stock_code = futures[future] | |
try: | |
prices = future.result() | |
if prices is not None: | |
stock_prices[stock_code] = prices | |
except Exception as e: | |
print(f"<p style='color: red;'>Failed to fetch data for {stock_code}: {e}</p>") | |
if not stock_prices: | |
return "No data available for the provided stock codes." | |
fig = go.Figure() | |
for stock_code, prices in stock_prices.items(): | |
relative_prices = prices / prices.iloc[0] | |
fig.add_trace(go.Scatter( | |
x=relative_prices.index, | |
y=relative_prices, | |
mode='lines', | |
name=stock_code.upper(), | |
hovertemplate='<b>%{text}</b><br>Price: %{y:.2f}<extra></extra>', | |
text=[f'{stock_code.upper()}: {price:.2f}' for price in prices] | |
)) | |
fig.update_layout( | |
# title=f'Relative Stock Prices Over the Last {days} Days', | |
# xaxis_title='Date', | |
# yaxis_title='Relative Price', | |
showlegend=True, | |
xaxis=dict( | |
showline=True, | |
showgrid=True, | |
gridcolor='LightGray', # Grid color | |
gridwidth=1, # Grid line width | |
), | |
yaxis=dict( | |
showline=True, | |
showgrid=True, | |
gridcolor='LightGray', # Grid color | |
gridwidth=1, # Grid line width | |
), | |
hovermode='x', | |
margin=dict(l=50, r=50, t=50, b=50), # Adjust margins | |
autosize=True | |
) | |
return fig | |
def gradio_interface(stock_codes, days): | |
fig = share_price_trend(stock_codes, days) | |
return gr.Plot(fig) | |