JayLacoma commited on
Commit
0d60bcb
·
verified ·
1 Parent(s): 0ac5f84

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +165 -38
app.py CHANGED
@@ -1,22 +1,21 @@
1
  # %%
2
- # Install necessary packages if not already installed
3
- # pip install gradio yfinance prophet plotly matplotlib
4
-
5
  import gradio as gr
6
  import pandas as pd
7
  import yfinance as yf
8
  from datetime import datetime
9
- import plotly.express as px
10
  import plotly.graph_objects as go
11
- import matplotlib.pyplot as plt
12
  import numpy as np
13
 
14
  # Functions for calculating indicators (SMA, RSI, etc.) and generating trading signals
15
- # (Reuse the code you've already written for technical indicators and forecasting)
16
 
17
  def calculate_sma(df, window):
18
  return df['Close'].rolling(window=window).mean()
19
 
 
 
 
 
20
  def calculate_macd(df):
21
  short_ema = df['Close'].ewm(span=12, adjust=False).mean()
22
  long_ema = df['Close'].ewm(span=26, adjust=False).mean()
@@ -24,6 +23,7 @@ def calculate_macd(df):
24
  signal = macd.ewm(span=9, adjust=False).mean()
25
  return macd, signal
26
 
 
27
  def calculate_rsi(df):
28
  delta = df['Close'].diff()
29
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
@@ -45,43 +45,81 @@ def calculate_stochastic_oscillator(df):
45
  slowd = slowk.rolling(window=3).mean()
46
  return slowk, slowd
47
 
48
- def generate_trading_signals(df):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
- # Calculate Simple Moving Averages (SMA)
51
- df['SMA_50'] = calculate_sma(df, 50)
52
- df['SMA_200'] = calculate_sma(df, 200)
53
 
54
- # Calculate other technical indicators
 
 
 
 
 
 
 
 
55
  df['RSI'] = calculate_rsi(df)
56
  df['MiddleBB'], df['UpperBB'], df['LowerBB'] = calculate_bollinger_bands(df)
57
  df['SlowK'], df['SlowD'] = calculate_stochastic_oscillator(df)
 
 
 
 
 
58
 
59
  # Generate trading signals
60
- df['SMA_Signal'] = np.where(df['SMA_50'] > df['SMA_200'], 1, 0)
61
 
62
  macd, signal = calculate_macd(df)
63
- df['MACD_Signal'] = np.where((macd > signal.shift(1)) & (macd.shift(1) < signal), 1, 0)
 
 
 
64
 
65
- df['RSI_Signal'] = np.where(df['RSI'] < 30, 1, 0)
66
- df['RSI_Signal'] = np.where(df['RSI'] > 70, -1, df['RSI_Signal'])
67
 
68
- df['BB_Signal'] = np.where(df['Close'] < df['LowerBB'], 1, 0)
69
  df['BB_Signal'] = np.where(df['Close'] > df['UpperBB'], -1, df['BB_Signal'])
70
 
71
- df['Stochastic_Signal'] = np.where((df['SlowK'] < 20) & (df['SlowD'] < 20), 1, 0)
72
- df['Stochastic_Signal'] = np.where((df['SlowK'] > 80) & (df['SlowD'] > 80), -1, df['Stochastic_Signal'])
73
-
74
- # Summing the values of each individual signal column
75
- df['Combined_Signal'] = df[['SMA_Signal', 'MACD_Signal', 'RSI_Signal', 'BB_Signal', 'Stochastic_Signal']].sum(axis=1)
76
 
 
 
 
 
77
 
78
 
 
 
 
 
79
 
 
80
 
81
 
82
  # %%
83
- import plotly.graph_objects as go
84
-
85
  def plot_combined_signals(df, ticker):
86
  # Create a figure
87
  fig = go.Figure()
@@ -104,7 +142,7 @@ def plot_combined_signals(df, ticker):
104
  ))
105
 
106
  # Add sell signals
107
- sell_signals = df[df['Combined_Signal'] <= -2]
108
  fig.add_trace(go.Scatter(
109
  x=sell_signals.index, y=sell_signals['Close'],
110
  mode='markers',
@@ -112,7 +150,7 @@ def plot_combined_signals(df, ticker):
112
  name='Sell Signal'
113
  ))
114
 
115
- # Add combined signal trace
116
  fig.add_trace(go.Scatter(
117
  x=df.index, y=df['Combined_Signal'],
118
  mode='lines',
@@ -121,41 +159,126 @@ def plot_combined_signals(df, ticker):
121
  yaxis='y2'
122
  ))
123
 
124
- # Update layout for secondary y-axis
125
  fig.update_layout(
126
  title=f'{ticker}: Stock Price and Combined Trading Signal (Last 60 Days)',
127
- xaxis=dict(title='Date', gridcolor='gray', gridwidth=0.5),
128
- yaxis=dict(title='Price', side='left', gridcolor='gray', gridwidth=0.5),
129
  yaxis2=dict(title='Combined Signal', overlaying='y', side='right', showgrid=False),
130
  plot_bgcolor='black',
131
  paper_bgcolor='black',
132
- font=dict(color='white'),
133
- legend=dict(x=0.01, y=0.99, bgcolor='rgba(0,0,0,0)'),
134
- hovermode='x unified'
135
  )
136
 
137
  return fig
138
 
139
-
140
  # %%
141
  def stock_analysis(ticker, start_date, end_date):
142
  # Download stock data from Yahoo Finance
143
  df = yf.download(ticker, start=start_date, end=end_date)
144
 
145
- # Run your existing trading signals and indicators here
146
  generate_trading_signals(df)
147
 
148
  # Last 60 days
149
  df_last_60 = df.tail(60)
150
 
151
- # Plot trading signals using the improved function
152
  fig_signals = plot_combined_signals(df_last_60, ticker)
153
 
154
-
155
- # Combine the figures into HTML output
156
  return fig_signals
157
 
158
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  # %%
160
  # Define Gradio interface
161
  with gr.Blocks() as demo:
@@ -169,12 +292,16 @@ with gr.Blocks() as demo:
169
  button = gr.Button("Analyze Stock")
170
 
171
  # Outputs: Display results, charts
172
- signals_output = gr.Plot(label="Trading Signals")
 
 
173
 
174
  # Link button to function
175
- button.click(stock_analysis, inputs=[ticker_input, start_date_input, end_date_input], outputs=[signals_output])
 
176
 
177
  # Launch the interface
178
  demo.launch()
179
 
180
 
 
 
1
  # %%
2
+ # %%
 
 
3
  import gradio as gr
4
  import pandas as pd
5
  import yfinance as yf
6
  from datetime import datetime
 
7
  import plotly.graph_objects as go
 
8
  import numpy as np
9
 
10
  # Functions for calculating indicators (SMA, RSI, etc.) and generating trading signals
 
11
 
12
  def calculate_sma(df, window):
13
  return df['Close'].rolling(window=window).mean()
14
 
15
+ def calculate_ema(df, window):
16
+ return df['Close'].ewm(span=window, adjust=False).mean()
17
+
18
+
19
  def calculate_macd(df):
20
  short_ema = df['Close'].ewm(span=12, adjust=False).mean()
21
  long_ema = df['Close'].ewm(span=26, adjust=False).mean()
 
23
  signal = macd.ewm(span=9, adjust=False).mean()
24
  return macd, signal
25
 
26
+
27
  def calculate_rsi(df):
28
  delta = df['Close'].diff()
29
  gain = (delta.where(delta > 0, 0)).rolling(window=14).mean()
 
45
  slowd = slowk.rolling(window=3).mean()
46
  return slowk, slowd
47
 
48
+ def calculate_atr(df, window=14):
49
+ high_low = df['High'] - df['Low']
50
+ high_close = np.abs(df['High'] - df['Close'].shift())
51
+ low_close = np.abs(df['Low'] - df['Close'].shift())
52
+ tr = high_low.combine(high_close, max).combine(low_close, max)
53
+ atr = tr.rolling(window=window).mean()
54
+ return atr
55
+
56
+ def calculate_cmf(df, window=20):
57
+ mfv = ((df['Close'] - df['Low']) - (df['High'] - df['Close'])) / (df['High'] - df['Low']) * df['Volume']
58
+ cmf = mfv.rolling(window=window).sum() / df['Volume'].rolling(window=window).sum()
59
+ return cmf
60
+
61
+ def calculate_cci(df, window=20):
62
+ """Calculate Commodity Channel Index (CCI)."""
63
+ typical_price = (df['High'] + df['Low'] + df['Close']) / 3
64
+ sma = typical_price.rolling(window=window).mean()
65
+ mean_deviation = (typical_price - sma).abs().rolling(window=window).mean()
66
+ cci = (typical_price - sma) / (0.015 * mean_deviation)
67
+ return cci
68
 
 
 
 
69
 
70
+
71
+
72
+
73
+ def generate_trading_signals(df):
74
+ # Calculate various indicators
75
+ df['SMA_30'] = calculate_sma(df, 30)
76
+ df['SMA_100'] = calculate_sma(df, 100)
77
+ df['EMA_12'] = calculate_ema(df, 12)
78
+ df['EMA_26'] = calculate_ema(df, 26)
79
  df['RSI'] = calculate_rsi(df)
80
  df['MiddleBB'], df['UpperBB'], df['LowerBB'] = calculate_bollinger_bands(df)
81
  df['SlowK'], df['SlowD'] = calculate_stochastic_oscillator(df)
82
+ df['ATR'] = calculate_atr(df)
83
+ df['CMF'] = calculate_cmf(df)
84
+ df['CCI'] = calculate_cci(df)
85
+
86
+
87
 
88
  # Generate trading signals
89
+ df['SMA_Signal'] = np.where(df['SMA_30'] > df['SMA_100'], 1, 0)
90
 
91
  macd, signal = calculate_macd(df)
92
+ df['MACD_Signal'] = np.select([(macd > signal) & (macd.shift(1) <= signal.shift(1)),
93
+ (macd < signal) & (macd.shift(1) >= signal.shift(1))],[1, -1], default=0)
94
+
95
+
96
 
97
+ df['RSI_Signal'] = np.where(df['RSI'] < 20, 1, 0)
98
+ df['RSI_Signal'] = np.where(df['RSI'] > 90, -1, df['RSI_Signal'])
99
 
100
+ df['BB_Signal'] = np.where(df['Close'] < df['LowerBB'], 0, 0)
101
  df['BB_Signal'] = np.where(df['Close'] > df['UpperBB'], -1, df['BB_Signal'])
102
 
103
+ df['Stochastic_Signal'] = np.where((df['SlowK'] < 10) & (df['SlowD'] < 15), 1, 0)
104
+ df['Stochastic_Signal'] = np.where((df['SlowK'] > 90) & (df['SlowD'] > 85), -1, df['Stochastic_Signal'])
105
+
106
+ df['CMF_Signal'] = np.where(df['CMF'] > 0.3, -1, np.where(df['CMF'] < -0.3, 1, 0))
 
107
 
108
+
109
+ df['CCI_Signal'] = np.where(df['CCI'] < -180, 1, 0)
110
+ df['CCI_Signal'] = np.where(df['CCI'] > 150, -1, df['CCI_Signal'])
111
+
112
 
113
 
114
+ # Combined signal for stronger buy/sell points
115
+ df['Combined_Signal'] = df[['RSI_Signal', 'BB_Signal',
116
+ 'Stochastic_Signal', 'CMF_Signal',
117
+ 'CCI_Signal']].sum(axis=1)
118
 
119
+ return df
120
 
121
 
122
  # %%
 
 
123
  def plot_combined_signals(df, ticker):
124
  # Create a figure
125
  fig = go.Figure()
 
142
  ))
143
 
144
  # Add sell signals
145
+ sell_signals = df[df['Combined_Signal'] <= -3]
146
  fig.add_trace(go.Scatter(
147
  x=sell_signals.index, y=sell_signals['Close'],
148
  mode='markers',
 
150
  name='Sell Signal'
151
  ))
152
 
153
+ # Combined signal trace
154
  fig.add_trace(go.Scatter(
155
  x=df.index, y=df['Combined_Signal'],
156
  mode='lines',
 
159
  yaxis='y2'
160
  ))
161
 
162
+ # Update layout
163
  fig.update_layout(
164
  title=f'{ticker}: Stock Price and Combined Trading Signal (Last 60 Days)',
165
+ xaxis=dict(title='Date'),
166
+ yaxis=dict(title='Price', side='left'),
167
  yaxis2=dict(title='Combined Signal', overlaying='y', side='right', showgrid=False),
168
  plot_bgcolor='black',
169
  paper_bgcolor='black',
170
+ font=dict(color='white')
 
 
171
  )
172
 
173
  return fig
174
 
 
175
  # %%
176
  def stock_analysis(ticker, start_date, end_date):
177
  # Download stock data from Yahoo Finance
178
  df = yf.download(ticker, start=start_date, end=end_date)
179
 
180
+ # Generate signals
181
  generate_trading_signals(df)
182
 
183
  # Last 60 days
184
  df_last_60 = df.tail(60)
185
 
186
+ # Plot signals
187
  fig_signals = plot_combined_signals(df_last_60, ticker)
188
 
 
 
189
  return fig_signals
190
 
191
 
192
+
193
+
194
+ # %%
195
+ def plot_individual_signals(df, ticker):
196
+ # Create a figure
197
+ fig = go.Figure()
198
+ fig.add_trace(go.Scatter(
199
+ x=df.index, y=df['Close'],
200
+ mode='lines',
201
+ name='Closing Price',
202
+ line=dict(color='lightcoral', width=2)
203
+ ))
204
+
205
+ # Add buy/sell signals for each indicator
206
+ signal_names = ['RSI_Signal', 'BB_Signal',
207
+ 'Stochastic_Signal', 'CMF_Signal',
208
+ 'CCI_Signal']
209
+
210
+ for signal in signal_names:
211
+ buy_signals = df[df[signal] == 1]
212
+ sell_signals = df[df[signal] == -1]
213
+
214
+ fig.add_trace(go.Scatter(
215
+ x=buy_signals.index, y=buy_signals['Close'],
216
+ mode='markers',
217
+ marker=dict(symbol='triangle-up', size=10, color='lightgreen'),
218
+ name=f'{signal} Buy Signal'
219
+ ))
220
+
221
+ fig.add_trace(go.Scatter(
222
+ x=sell_signals.index, y=sell_signals['Close'],
223
+ mode='markers',
224
+ marker=dict(symbol='triangle-down', size=10, color='lightsalmon'),
225
+ name=f'{signal} Sell Signal'
226
+ ))
227
+
228
+ fig.update_layout(
229
+ title=f'{ticker}: Individual Trading Signals',
230
+ xaxis=dict(title='Date'),
231
+ yaxis=dict(title='Price', side='left'),
232
+ plot_bgcolor='black',
233
+ paper_bgcolor='black',
234
+ font=dict(color='white')
235
+ )
236
+
237
+ return fig
238
+
239
+
240
+ def display_signals(df):
241
+ # Create a signals DataFrame
242
+ signals_df = df[['Close', 'SMA_Signal', 'MACD_Signal', 'RSI_Signal',
243
+ 'BB_Signal', 'Stochastic_Signal', 'ATR_Signal',
244
+ 'CMF_Signal', 'CCI_Signal']].copy()
245
+
246
+ # The Date is the index, so we don't need to add it as a column
247
+ signals_df.index.name = 'Date' # Name the index for better readability
248
+
249
+ # Replace signal values with 'Buy', 'Sell', or 'Hold'
250
+ for column in signals_df.columns:
251
+ signals_df[column] = signals_df[column].replace(
252
+ {1: 'Buy', -1: 'Sell', 0: 'Hold'}
253
+ )
254
+
255
+ return signals_df
256
+
257
+ def stock_analysis(ticker, start_date, end_date):
258
+ # Download stock data from Yahoo Finance
259
+ df = yf.download(ticker, start=start_date, end=end_date)
260
+
261
+ # Generate signals
262
+ df = generate_trading_signals(df)
263
+
264
+ # Last 60 days for plotting
265
+ df_last_60 = df.tail(60)
266
+
267
+ # Plot combined signals
268
+ fig_signals = plot_combined_signals(df_last_60, ticker)
269
+
270
+ # Plot individual signals
271
+ fig_individual_signals = plot_individual_signals(df_last_60, ticker)
272
+
273
+ # Display signals DataFrame
274
+ signals_df = df_last_60[['Close', 'SMA_Signal', 'MACD_Signal', 'RSI_Signal', 'BB_Signal',
275
+ 'Stochastic_Signal', 'ATR_Signal', 'CMF_Signal',
276
+ 'CCI_Signal']]
277
+
278
+ return fig_signals, fig_individual_signals
279
+
280
+
281
+
282
  # %%
283
  # Define Gradio interface
284
  with gr.Blocks() as demo:
 
292
  button = gr.Button("Analyze Stock")
293
 
294
  # Outputs: Display results, charts
295
+ combined_signals_output = gr.Plot(label="Combined Trading Signals")
296
+ individual_signals_output = gr.Plot(label="Individual Trading Signals")
297
+ #signals_df_output = gr.Dataframe(label="Buy/Sell Signals")
298
 
299
  # Link button to function
300
+ button.click(stock_analysis, inputs=[ticker_input, start_date_input, end_date_input],
301
+ outputs=[combined_signals_output, individual_signals_output])
302
 
303
  # Launch the interface
304
  demo.launch()
305
 
306
 
307
+