netflypsb commited on
Commit
fa62b8c
1 Parent(s): c72f1c6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -24
app.py CHANGED
@@ -7,11 +7,29 @@ import yfinance as yf
7
  # Function to load historical data
8
  @st.cache_data
9
  def load_data(ticker):
10
- # Fetch data from Yahoo Finance
11
  return yf.download(ticker, start="2000-01-01", end="2023-01-01")
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # User inputs for strategy parameters
14
  st.title("Algorithmic Trading Strategy Backtesting")
 
15
 
16
  ticker = st.text_input("Enter the ticker symbol", "AAPL")
17
  data = load_data(ticker)
@@ -24,11 +42,8 @@ long_window = st.number_input("Long moving average window", 1, 200, 50)
24
  initial_capital = st.number_input("Initial Capital", 1000, 1000000, 100000)
25
 
26
  # Data Preprocessing
27
- # Calculate moving averages
28
  data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
29
  data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
30
-
31
- # Drop NaN values
32
  data.dropna(inplace=True)
33
 
34
  # Generate Trading Signals
@@ -36,22 +51,15 @@ data['Signal'] = 0
36
  data['Signal'][short_window:] = np.where(data['Short_MA'][short_window:] > data['Long_MA'][short_window:], 1, 0)
37
  data['Position'] = data['Signal'].diff()
38
 
39
- # Show signals in data
40
- st.write(data.tail())
41
-
42
  # Backtesting Engine
43
- # Simulate portfolio
44
  data['Portfolio Value'] = initial_capital
45
  data['Portfolio Value'][short_window:] = initial_capital * (1 + data['Signal'][short_window:].shift(1) * data['Close'].pct_change()[short_window:]).cumprod()
46
 
47
  # Performance metrics
48
- cagr = (data['Portfolio Value'].iloc[-1] / initial_capital) ** (1 / ((data.index[-1] - data.index[short_window]).days / 365.25)) - 1
49
- sharpe_ratio = data['Portfolio Value'].pct_change().mean() / data['Portfolio Value'].pct_change().std() * np.sqrt(252)
50
-
51
  st.write(f"CAGR: {cagr:.2%}")
52
  st.write(f"Sharpe Ratio: {sharpe_ratio:.2f}")
53
 
54
- # Data Visualization
55
  # Plot strategy performance
56
  fig, ax = plt.subplots(figsize=(10, 5))
57
  ax.plot(data.index, data['Portfolio Value'], label='Portfolio Value')
@@ -61,15 +69,32 @@ ax.set_ylabel("Portfolio Value")
61
  ax.legend()
62
  st.pyplot(fig)
63
 
64
- # Highlight buy and sell signals
65
- fig, ax = plt.subplots(figsize=(10, 5))
66
- ax.plot(data.index, data['Close'], label='Close Price', alpha=0.5)
67
- ax.plot(data.index, data['Short_MA'], label=f'Short MA ({short_window})', alpha=0.75)
68
- ax.plot(data.index, data['Long_MA'], label=f'Long MA ({long_window})', alpha=0.75)
69
- ax.plot(data[data['Position'] == 1].index, data['Short_MA'][data['Position'] == 1], '^', markersize=10, color='g', lw=0, label='Buy Signal')
70
- ax.plot(data[data['Position'] == -1].index, data['Short_MA'][data['Position'] == -1], 'v', markersize=10, color='r', lw=0, label='Sell Signal')
71
- ax.set_title(f"{ticker} Price and Trading Signals")
72
- ax.set_xlabel("Date")
73
- ax.set_ylabel("Price")
74
- ax.legend()
75
- st.pyplot(fig)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  # Function to load historical data
8
  @st.cache_data
9
  def load_data(ticker):
 
10
  return yf.download(ticker, start="2000-01-01", end="2023-01-01")
11
 
12
+ def calculate_performance_metrics(data, initial_capital):
13
+ cagr = (data['Portfolio Value'].iloc[-1] / initial_capital) ** (1 / ((data.index[-1] - data.index[0]).days / 365.25)) - 1
14
+ sharpe_ratio = data['Portfolio Value'].pct_change().mean() / data['Portfolio Value'].pct_change().std() * np.sqrt(252)
15
+ return cagr, sharpe_ratio
16
+
17
+ def plot_signals(data, ticker, short_window, long_window):
18
+ fig, ax = plt.subplots(figsize=(10, 5))
19
+ ax.plot(data.index, data['Close'], label='Close Price', alpha=0.5)
20
+ ax.plot(data.index, data['Short_MA'], label=f'Short MA ({short_window})', alpha=0.75)
21
+ ax.plot(data.index, data['Long_MA'], label=f'Long MA ({long_window})', alpha=0.75)
22
+ ax.plot(data[data['Position'] == 1].index, data['Short_MA'][data['Position'] == 1], '^', markersize=10, color='g', lw=0, label='Buy Signal')
23
+ ax.plot(data[data['Position'] == -1].index, data['Short_MA'][data['Position'] == -1], 'v', markersize=10, color='r', lw=0, label='Sell Signal')
24
+ ax.set_title(f"{ticker} Price and Trading Signals")
25
+ ax.set_xlabel("Date")
26
+ ax.set_ylabel("Price")
27
+ ax.legend()
28
+ st.pyplot(fig)
29
+
30
  # User inputs for strategy parameters
31
  st.title("Algorithmic Trading Strategy Backtesting")
32
+ st.markdown("This app allows you to backtest an algorithmic trading strategy using historical stock data.")
33
 
34
  ticker = st.text_input("Enter the ticker symbol", "AAPL")
35
  data = load_data(ticker)
 
42
  initial_capital = st.number_input("Initial Capital", 1000, 1000000, 100000)
43
 
44
  # Data Preprocessing
 
45
  data['Short_MA'] = data['Close'].rolling(window=short_window).mean()
46
  data['Long_MA'] = data['Close'].rolling(window=long_window).mean()
 
 
47
  data.dropna(inplace=True)
48
 
49
  # Generate Trading Signals
 
51
  data['Signal'][short_window:] = np.where(data['Short_MA'][short_window:] > data['Long_MA'][short_window:], 1, 0)
52
  data['Position'] = data['Signal'].diff()
53
 
 
 
 
54
  # Backtesting Engine
 
55
  data['Portfolio Value'] = initial_capital
56
  data['Portfolio Value'][short_window:] = initial_capital * (1 + data['Signal'][short_window:].shift(1) * data['Close'].pct_change()[short_window:]).cumprod()
57
 
58
  # Performance metrics
59
+ cagr, sharpe_ratio = calculate_performance_metrics(data, initial_capital)
 
 
60
  st.write(f"CAGR: {cagr:.2%}")
61
  st.write(f"Sharpe Ratio: {sharpe_ratio:.2f}")
62
 
 
63
  # Plot strategy performance
64
  fig, ax = plt.subplots(figsize=(10, 5))
65
  ax.plot(data.index, data['Portfolio Value'], label='Portfolio Value')
 
69
  ax.legend()
70
  st.pyplot(fig)
71
 
72
+ # Plot trading signals
73
+ plot_signals(data, ticker, short_window, long_window)
74
+
75
+ # Advanced Performance Metrics
76
+ st.subheader("Advanced Performance Metrics")
77
+ # Maximum Drawdown Calculation
78
+ rolling_max = data['Portfolio Value'].cummax()
79
+ daily_drawdown = data['Portfolio Value'] / rolling_max - 1.0
80
+ max_drawdown = daily_drawdown.cummin().iloc[-1]
81
+ st.write(f"Maximum Drawdown: {max_drawdown:.2%}")
82
+
83
+ # Trade Statistics
84
+ st.subheader("Trade Statistics")
85
+ num_trades = data['Position'].value_counts().sum()
86
+ num_winning_trades = data['Position'][data['Position'] == 1].count()
87
+ num_losing_trades = data['Position'][data['Position'] == -1].count()
88
+ win_rate = num_winning_trades / num_trades
89
+ loss_rate = num_losing_trades / num_trades
90
+ st.write(f"Total Trades: {num_trades}")
91
+ st.write(f"Winning Trades: {num_winning_trades} ({win_rate:.2%})")
92
+ st.write(f"Losing Trades: {num_losing_trades} ({loss_rate:.2%})")
93
+
94
+ # Add option to upload data
95
+ st.subheader("Upload Your Own Data")
96
+ uploaded_file = st.file_uploader("Choose a file", type="csv")
97
+ if uploaded_file is not None:
98
+ user_data = pd.read_csv(uploaded_file)
99
+ st.write("Uploaded data:")
100
+ st.write(user_data.head())