StockProfits / app.py
pm6six's picture
Rename Gradio to app.py
b9eb3a2 verified
raw
history blame
4.67 kB
import pandas as pd
import yfinance as yf
import numpy as np
import matplotlib.pyplot as plt
import gradio as gr
import io
print("App is starting...")
# Define the SMA Crossover Trading Strategy Function
def sma_crossover_strategy(initial_budget, start_date, end_date, ticker):
print(f"Fetching data for {ticker} from {start_date} to {end_date}...")
try:
# Fetch stock data
df = yf.download(ticker, start=start_date, end=end_date, progress=False)
if df.empty:
print("No data fetched. Returning error message.")
return None, "No data available for the specified ticker and date range.", None
except Exception as e:
print(f"Error fetching data: {str(e)}")
return None, f"Error fetching data: {str(e)}", None
# Calculate SMAs
print("Calculating SMAs...")
df = df[['Close']]
df['SMA_50'] = df['Close'].rolling(window=50).mean()
df['SMA_150'] = df['Close'].rolling(window=150).mean()
# Define signals
df['Signal'] = 0
df['Signal'][df['SMA_50'] > df['SMA_150']] = 1
df['Signal'][df['SMA_50'] < df['SMA_150']] = -1
df['Position'] = df['Signal'].diff()
# Initialize portfolio simulation
print("Simulating portfolio...")
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: # Buy signal
shares = cash / row['Close']
cash = 0
elif row['Position'] == -1 and shares > 0: # Sell signal
cash = shares * row['Close']
shares = 0
# Calculate current portfolio value
portfolio_value = cash + (shares * row['Close'])
portfolio_values.append(portfolio_value)
# Handle missing data at the start
df = df.iloc[149:]
df['Portfolio Value'] = portfolio_values[149:]
# Generate plot
print("Generating plot...")
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()
# Save plot to in-memory buffer
plot_file = io.BytesIO()
plt.savefig(plot_file, format='png')
plot_file.seek(0)
plt.close()
# Final portfolio summary
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, None
# Create Gradio Interface
print("Setting up Gradio app...")
with gr.Blocks() as app:
gr.Markdown("# SMA Crossover Trading Strategy Simulator")
with gr.Tabs():
# SMA Strategy Simulator Tab
with gr.Tab("SMA Strategy Simulator"):
with gr.Row():
initial_budget = gr.Number(label="Initial Investment ($)", value=100, interactive=True)
start_date = gr.Text(label="Start Date (YYYY-MM-DD)", value="1993-01-01", interactive=True)
end_date = gr.Text(label="End Date (YYYY-MM-DD)", value="2023-12-31", interactive=True)
ticker = gr.Dropdown(
label="Stock Ticker Symbol",
choices=["SPY", "TSLA", "GOOGL", "AAPL", "MSFT"],
value="SPY",
)
run_button = gr.Button("Run Simulation")
with gr.Row():
portfolio_graph = gr.Image(label="Portfolio Value Over Time")
summary_text = gr.Textbox(label="Simulation Summary", lines=8)
# Instructions Tab
with gr.Tab("Instructions"):
gr.Markdown("""
## How to Use:
1. Enter your initial investment amount.
2. Specify the trading period (start and end dates).
3. Select a stock ticker symbol (e.g., SPY, TSLA, GOOGL).
4. Click "Run Simulation" to visualize the portfolio value over time and view a summary of results.
""")
# Connect simulation function to Gradio app
run_button.click(
sma_crossover_strategy,
inputs=[initial_budget, start_date, end_date, ticker],
outputs=[portfolio_graph, summary_text],
)
print("Launching Gradio app...")
app.launch()