QuantumLearner commited on
Commit
4df4a95
1 Parent(s): 3aa029f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +83 -86
app.py CHANGED
@@ -34,98 +34,95 @@ def compute_wasserstein_distances(log_returns, window_size, rips):
34
  return distances
35
 
36
  # Streamlit app
37
- def main():
38
- st.set_page_config(layout="wide")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
- st.title('Stock Analysis Using Topological Data Analysis')
 
 
 
41
  st.write("""
42
- This application analyzes stock data using Wasserstein distances to detect changes in price dynamics over time.
43
- Wasserstein distances, derived from persistence diagrams in Topological Data Analysis (TDA), help identify significant shifts in stock price behaviors.
 
 
 
 
44
  """)
 
45
 
46
- st.sidebar.title('Parameters')
47
-
48
- # Input fields for user
49
- ticker_name = st.sidebar.text_input('Enter Ticker Symbol', '^GSPC')
50
- start_date_string = st.sidebar.text_input('Start Date (YYYY-MM-DD)', '2020-01-01')
51
- end_date_string = st.sidebar.text_input('End Date (YYYY-MM-DD)', '2025-01-01')
52
- window_size = st.sidebar.slider('Window Size', min_value=5, max_value=50, value=20)
53
- threshold = st.sidebar.slider('Alert Threshold', min_value=0.05, max_value=0.2, value=0.075, step=0.005)
54
-
55
- st.sidebar.write("""
56
- **How to use:**
57
- 1. Enter the stock ticker symbol (e.g., `^GSPC` for S&P 500).
58
- 2. Specify the start and end dates for the analysis period.
59
- 3. Adjust the window size for the sliding window analysis.
60
- 4. Set the alert threshold for detecting significant changes.
61
- 5. Click 'Run Analysis' to start.
62
  """)
63
 
64
- if st.sidebar.button('Run Analysis'):
65
- st.write(f"Analyzing {ticker_name} from {start_date_string} to {end_date_string} with window size {window_size} and threshold {threshold}")
66
-
67
- # Fetch data
68
- prices, log_returns = fetch_data(ticker_name, start_date_string, end_date_string)
69
- rips = Rips(maxdim=2)
70
- wasserstein_dists = compute_wasserstein_distances(log_returns, window_size, rips)
71
-
72
- # Plotting with Plotly
73
- dates = prices.index[window_size:-window_size]
74
- valid_indices = ~np.isnan(wasserstein_dists.flatten())
75
- valid_dates = dates[valid_indices]
76
- valid_distances = wasserstein_dists[valid_indices].flatten()
77
-
78
- alert_indices = [i for i, d in enumerate(valid_distances) if d > threshold]
79
- alert_dates = [valid_dates[i] for i in alert_indices]
80
- alert_values = [prices.iloc[i + window_size] for i in alert_indices]
81
-
82
- # Plot price and alerts
83
- fig = go.Figure()
84
- fig.add_trace(go.Scatter(x=valid_dates, y=prices.iloc[window_size:-window_size], mode='lines', name='Price'))
85
- fig.add_trace(go.Scatter(x=alert_dates, y=alert_values, mode='markers', name='Alert', marker=dict(color='red', size=8)))
86
- fig.update_layout(title=f'{ticker_name} Prices Over Time', xaxis_title='Date', yaxis_title='Price')
87
- st.plotly_chart(fig, use_container_width=True)
88
-
89
- # Plot Wasserstein distances
90
- fig = go.Figure()
91
- fig.add_trace(go.Scatter(x=valid_dates, y=valid_distances, mode='lines', name='Wasserstein Distance', line=dict(color='blue', width=2)))
92
- fig.add_hline(y=threshold, line_dash='dash', line_color='red', annotation_text=f'Threshold: {threshold}', annotation_position='bottom right')
93
- fig.update_layout(title='Wasserstein Distances Over Time', xaxis_title='Date', yaxis_title='Wasserstein Distance')
94
- st.plotly_chart(fig, use_container_width=True)
95
-
96
- # Interpretation of results
97
- st.subheader("Interpretation of Results")
98
-
99
- st.write("""
100
- **Wasserstein Distance Analysis:**
101
- The Wasserstein distance measures the difference between two distributions. In this context, it quantifies changes in the log returns of stock prices over time.
102
- A high Wasserstein distance indicates a significant change in the price dynamics, which might suggest a market event or shift in investor sentiment.
103
- """)
104
-
105
- st.latex(r'''
106
- W(P, Q) = \inf_{\gamma \in \Pi(P, Q)} \mathbb{E}_{(x,y) \sim \gamma} [d(x, y)]
107
- ''')
108
-
109
- st.write("""
110
- - Where \( W(P, Q) \) is the Wasserstein distance between distributions \( P \) and \( Q \).
111
- - \( d(x, y) \) is the distance between points \( x \) and \( y \).
112
- - \( \gamma \) is a joint distribution with marginals \( P \) and \( Q \).
113
-
114
- **Alert Threshold:**
115
- The alert threshold is set to identify significant changes in the Wasserstein distances. Alerts are triggered when the distance exceeds the threshold.
116
- """)
117
- st.write(f"Threshold: {threshold}")
118
-
119
- st.write("""
120
- **Plot Interpretation:**
121
- - The first plot shows the stock price over time with alerts marked in red.
122
- - The second plot displays the Wasserstein distances over time, with the threshold indicated by a dashed red line. Peaks above this line represent significant changes in price dynamics.
123
- """)
124
-
125
- # Main function call
126
- if __name__ == "__main__":
127
- warnings.filterwarnings('ignore')
128
- main()
129
 
130
  hide_streamlit_style = """
131
  <style>
 
34
  return distances
35
 
36
  # Streamlit app
37
+ st.set_page_config(layout="wide")
38
+
39
+ st.title("Market Crash Analysis with Topology")
40
+ st.write("""
41
+ This application analyzes asset price data using Wasserstein distances to detect changes in price dynamics over time.
42
+ Wasserstein distances, derived from persistence diagrams in Topological Data Analysis (TDA), help identify significant shifts in stock price behaviors.
43
+ """)
44
+
45
+ st.sidebar.title('Input Parameters')
46
+
47
+ # Input fields for user
48
+ ticker_name = st.sidebar.text_input('Enter Ticker Symbol', '^GSPC')
49
+ start_date_string = st.sidebar.text_input('Start Date (YYYY-MM-DD)', '2020-01-01')
50
+ end_date_string = st.sidebar.text_input('End Date (YYYY-MM-DD)', '2025-01-01')
51
+ window_size = st.sidebar.slider('Window Size', min_value=5, max_value=50, value=20)
52
+ threshold = st.sidebar.slider('Alert Threshold', min_value=0.05, max_value=0.2, value=0.075, step=0.005)
53
+
54
+ st.sidebar.write("""
55
+ **How to use:**
56
+ 1. Enter the stock ticker symbol (e.g., `^GSPC` for S&P 500).
57
+ 2. Specify the start and end dates for the analysis period.
58
+ 3. Adjust the window size for the sliding window analysis.
59
+ 4. Set the alert threshold for detecting significant changes.
60
+ 5. Click 'Run Analysis' to start.
61
+ """)
62
+
63
+ if st.sidebar.button('Run Analysis'):
64
+ st.write(f"Analyzing {ticker_name} from {start_date_string} to {end_date_string} with window size {window_size} and threshold {threshold}")
65
+
66
+ # Fetch data
67
+ prices, log_returns = fetch_data(ticker_name, start_date_string, end_date_string)
68
+ rips = Rips(maxdim=2)
69
+ wasserstein_dists = compute_wasserstein_distances(log_returns, window_size, rips)
70
+
71
+ # Plotting with Plotly
72
+ dates = prices.index[window_size:-window_size]
73
+ valid_indices = ~np.isnan(wasserstein_dists.flatten())
74
+ valid_dates = dates[valid_indices]
75
+ valid_distances = wasserstein_dists[valid_indices].flatten()
76
+
77
+ alert_indices = [i for i, d in enumerate(valid_distances) if d > threshold]
78
+ alert_dates = [valid_dates[i] for i in alert_indices]
79
+ alert_values = [prices.iloc[i + window_size] for i in alert_indices]
80
+
81
+ # Plot price and alerts
82
+ fig = go.Figure()
83
+ fig.add_trace(go.Scatter(x=valid_dates, y=prices.iloc[window_size:-window_size], mode='lines', name='Price'))
84
+ fig.add_trace(go.Scatter(x=alert_dates, y=alert_values, mode='markers', name='Alert', marker=dict(color='red', size=8)))
85
+ fig.update_layout(title=f'{ticker_name} Prices Over Time', xaxis_title='Date', yaxis_title='Price')
86
+ st.plotly_chart(fig, use_container_width=True)
87
+
88
+ # Plot Wasserstein distances
89
+ fig = go.Figure()
90
+ fig.add_trace(go.Scatter(x=valid_dates, y=valid_distances, mode='lines', name='Wasserstein Distance', line=dict(color='blue', width=2)))
91
+ fig.add_hline(y=threshold, line_dash='dash', line_color='red', annotation_text=f'Threshold: {threshold}', annotation_position='bottom right')
92
+ fig.update_layout(title='Wasserstein Distances Over Time', xaxis_title='Date', yaxis_title='Wasserstein Distance')
93
+ st.plotly_chart(fig, use_container_width=True)
94
+
95
+ # Interpretation of results
96
+ st.subheader("Interpretation of Results")
97
+
98
+ st.write("""
99
+ **Wasserstein Distance Analysis:**
100
+ The Wasserstein distance measures the difference between two distributions. In this context, it quantifies changes in the log returns of stock prices over time.
101
+ A high Wasserstein distance indicates a significant change in the price dynamics, which might suggest a market event or shift in investor sentiment.
102
+ """)
103
 
104
+ st.latex(r'''
105
+ W(P, Q) = \inf_{\gamma \in \Pi(P, Q)} \mathbb{E}_{(x,y) \sim \gamma} [d(x, y)]
106
+ ''')
107
+
108
  st.write("""
109
+ - Where \( W(P, Q) \) is the Wasserstein distance between distributions \( P \) and \( Q \).
110
+ - \( d(x, y) \) is the distance between points \( x \) and \( y \).
111
+ - \( \gamma \) is a joint distribution with marginals \( P \) and \( Q \).
112
+
113
+ **Alert Threshold:**
114
+ The alert threshold is set to identify significant changes in the Wasserstein distances. Alerts are triggered when the distance exceeds the threshold.
115
  """)
116
+ st.write(f"Threshold: {threshold}")
117
 
118
+ st.write("""
119
+ **Plot Interpretation:**
120
+ - The first plot shows the stock price over time with alerts marked in red.
121
+ - The second plot displays the Wasserstein distances over time, with the threshold indicated by a dashed red line. Peaks above this line represent significant changes in price dynamics.
 
 
 
 
 
 
 
 
 
 
 
 
122
  """)
123
 
124
+
125
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  hide_streamlit_style = """
128
  <style>