StockProfits / app.py
pm6six's picture
Update app.py
71746cb verified
raw
history blame
3.24 kB
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()