File size: 4,668 Bytes
97f6d3d
 
 
 
 
ae3466a
97f6d3d
b9eb3a2
7ec3f0a
b9eb3a2
97f6d3d
b9eb3a2
ae3466a
b9eb3a2
ae3466a
 
b9eb3a2
ae3466a
 
b9eb3a2
ae3466a
 
b9eb3a2
 
a11b754
97f6d3d
 
b9eb3a2
 
a11b754
 
 
 
97f6d3d
b9eb3a2
 
a11b754
 
 
97f6d3d
 
ae3466a
 
b9eb3a2
97f6d3d
a11b754
b9eb3a2
97f6d3d
a11b754
b9eb3a2
 
97f6d3d
 
 
b9eb3a2
a11b754
 
97f6d3d
b9eb3a2
 
97f6d3d
 
 
 
 
 
 
 
 
b9eb3a2
ae3466a
 
 
97f6d3d
 
b9eb3a2
97f6d3d
 
 
 
 
 
 
 
 
 
 
 
c51bf55
ae3466a
97f6d3d
b9eb3a2
 
97f6d3d
 
 
 
b9eb3a2
97f6d3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b9eb3a2
97f6d3d
 
 
 
 
 
 
 
 
b9eb3a2
97f6d3d
 
 
ae3466a
97f6d3d
 
b9eb3a2
672b2d6
ae3466a
b9eb3a2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
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()