Spaces:
Sleeping
Sleeping
import pandas as pd | |
import yfinance as yf | |
import numpy as np | |
import matplotlib.pyplot as plt | |
import io | |
import gradio as gr | |
def sma_crossover_strategy(initial_budget, start_date, end_date, ticker): | |
try: | |
df = yf.download(ticker, start=start_date, end=end_date, progress=False) | |
if df.empty: | |
return None, "No data available for the specified ticker and date range." | |
except Exception as e: | |
return None, f"Error fetching data: {str(e)}" | |
df = df[['Close']] | |
df['SMA_50'] = df['Close'].rolling(window=50).mean() | |
df['SMA_150'] = df['Close'].rolling(window=150).mean() | |
df['Signal'] = 0 | |
df.loc[df['SMA_50'] > df['SMA_150'], 'Signal'] = 1 | |
df.loc[df['SMA_50'] < df['SMA_150'], 'Signal'] = -1 | |
df['Position'] = df['Signal'].diff() | |
cash = initial_budget | |
shares = 0 | |
portfolio_values = [] | |
for index, row in df.iterrows(): | |
if pd.isna(row['Close']): | |
continue | |
if row['Position'] == 1 and cash > 0: | |
shares = cash / row['Close'] | |
cash = 0 | |
elif row['Position'] == -1 and shares > 0: | |
cash = shares * row['Close'] | |
shares = 0 | |
portfolio_value = cash + (shares * row['Close']) | |
portfolio_values.append(portfolio_value) | |
df = df.iloc[149:] # Skip rows without SMA values | |
df['Portfolio Value'] = portfolio_values[149:] | |
plt.figure(figsize=(14, 8)) | |
plt.plot(df['Portfolio Value'], label='Portfolio Value', color='purple') | |
plt.xlabel('Date') | |
plt.ylabel('Portfolio Value ($)') | |
plt.title(f'Portfolio Value Over Time with 50/150 SMA Crossover Strategy ({ticker})') | |
plt.legend() | |
plt.grid() | |
plt.tight_layout() | |
plot_file = io.BytesIO() | |
plt.savefig(plot_file, format='png') | |
plot_file.seek(0) | |
plt.close() | |
final_value = portfolio_values[-1] | |
profit_loss = final_value - initial_budget | |
percentage_return = (profit_loss / initial_budget) * 100 | |
results = f""" | |
Ticker: {ticker} | |
Trading Period: {start_date} to {end_date} | |
Initial Investment: ${initial_budget} | |
Final Portfolio Value: ${final_value:.2f} | |
Total Profit/Loss: ${profit_loss:.2f} | |
Percentage Return: {percentage_return:.2f}% | |
""" | |
return plot_file, results | |
# Define Gradio App | |
with gr.Blocks() as app: | |
gr.Markdown("# SMA Crossover Trading Strategy Simulator") | |
with gr.Row(): | |
initial_budget = gr.Number(label="Initial Investment ($)", value=100) | |
start_date = gr.Text(label="Start Date (YYYY-MM-DD)", value="1993-01-01") | |
end_date = gr.Text(label="End Date (YYYY-MM-DD)", value="2023-12-31") | |
ticker = gr.Dropdown( | |
label="Stock Ticker Symbol", | |
choices=["SPY", "TSLA", "GOOGL", "AAPL", "MSFT"], | |
value="SPY", | |
) | |
run_button = gr.Button("Run Simulation") | |
portfolio_graph = gr.Image(label="Portfolio Value Over Time") | |
summary_text = gr.Textbox(label="Simulation Summary", lines=8) | |
run_button.click( | |
sma_crossover_strategy, | |
inputs=[initial_budget, start_date, end_date, ticker], | |
outputs=[portfolio_graph, summary_text], | |
) | |
# Ensure only one app.launch() is called | |
if __name__ == "__main__": | |
app.launch() | |