Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,7 +6,7 @@ import persim
|
|
| 6 |
import plotly.graph_objs as go
|
| 7 |
import warnings
|
| 8 |
|
| 9 |
-
# Function to fetch stock data
|
| 10 |
def fetch_data(ticker_name, start_date, end_date):
|
| 11 |
raw_data = yf.download(ticker_name, start=start_date, end=end_date)
|
| 12 |
adjusted_close = raw_data['Adj Close'].dropna()
|
|
@@ -33,34 +33,38 @@ def compute_wasserstein_distances(log_returns, window_size, rips):
|
|
| 33 |
|
| 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
|
| 43 |
""")
|
| 44 |
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
threshold
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
|
| 63 |
-
if st.
|
| 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
|
|
@@ -92,12 +96,10 @@ if st.sidebar.button('Run Analysis'):
|
|
| 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 |
-
#
|
| 96 |
-
st.subheader("
|
| 97 |
-
|
| 98 |
st.write("""
|
| 99 |
-
|
| 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 |
|
|
@@ -109,25 +111,29 @@ if st.sidebar.button('Run Analysis'):
|
|
| 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
|
| 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>
|
| 129 |
#MainMenu {visibility: hidden;}
|
| 130 |
footer {visibility: hidden;}
|
| 131 |
</style>
|
| 132 |
"""
|
| 133 |
-
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
|
|
|
| 6 |
import plotly.graph_objs as go
|
| 7 |
import warnings
|
| 8 |
|
| 9 |
+
# Function to fetch stock or crypto data
|
| 10 |
def fetch_data(ticker_name, start_date, end_date):
|
| 11 |
raw_data = yf.download(ticker_name, start=start_date, end=end_date)
|
| 12 |
adjusted_close = raw_data['Adj Close'].dropna()
|
|
|
|
| 33 |
|
| 34 |
return distances
|
| 35 |
|
| 36 |
+
# Streamlit app configuration
|
| 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 asset price behaviors for both stocks and cryptocurrencies.
|
| 43 |
""")
|
| 44 |
|
| 45 |
+
# Sidebar for "How to Use" instructions inside an expander, closed by default
|
| 46 |
+
with st.sidebar.expander("How to Use", expanded=False):
|
| 47 |
+
st.write("""
|
| 48 |
+
**How to use this app:**
|
| 49 |
+
1. Enter the stock or crypto ticker symbol (e.g., `^GSPC` for S&P 500 or `BTC-USD` for Bitcoin).
|
| 50 |
+
2. Specify the start and end dates for the analysis period.
|
| 51 |
+
3. Adjust the window size for the sliding window analysis.
|
| 52 |
+
4. Set the alert threshold for detecting significant changes in price dynamics.
|
| 53 |
+
5. Click 'Run Analysis' to start.
|
| 54 |
+
""")
|
| 55 |
+
|
| 56 |
+
# Input parameters inside an expander, open by default
|
| 57 |
+
with st.expander("Input Parameters", expanded=True):
|
| 58 |
+
ticker_name = st.text_input('Enter Stock or Crypto Symbol (e.g., AAPL or BTC-USD)', '^GSPC', help="Enter the ticker symbol for the stock or cryptocurrency you want to analyze.")
|
| 59 |
+
start_date_string = st.date_input('Start Date', pd.to_datetime('2020-01-01'), help="Select the start date for the data range.")
|
| 60 |
+
end_date_string = st.date_input('End Date', pd.to_datetime(pd.Timestamp.now().date() + pd.Timedelta(days=1)), help="Select the end date for the data range.")
|
| 61 |
+
|
| 62 |
+
# Parameters for the selected method inside an expander, open by default
|
| 63 |
+
with st.expander("Parameters", expanded=True):
|
| 64 |
+
window_size = st.slider('Window Size', min_value=5, max_value=50, value=20, help="Set the window size for the sliding window analysis.")
|
| 65 |
+
threshold = st.slider('Alert Threshold', min_value=0.05, max_value=0.2, value=0.075, step=0.005, help="Set the threshold for detecting significant changes in price dynamics.")
|
| 66 |
|
| 67 |
+
if st.button('Run Analysis'):
|
| 68 |
st.write(f"Analyzing {ticker_name} from {start_date_string} to {end_date_string} with window size {window_size} and threshold {threshold}")
|
| 69 |
|
| 70 |
# Fetch data
|
|
|
|
| 96 |
fig.update_layout(title='Wasserstein Distances Over Time', xaxis_title='Date', yaxis_title='Wasserstein Distance')
|
| 97 |
st.plotly_chart(fig, use_container_width=True)
|
| 98 |
|
| 99 |
+
# Explanation of the Wasserstein Distance method
|
| 100 |
+
st.subheader("Wasserstein Distance Methodology")
|
|
|
|
| 101 |
st.write("""
|
| 102 |
+
The Wasserstein distance is a measure from optimal transport theory, used here to compare distributions of log returns in different time windows.
|
|
|
|
| 103 |
A high Wasserstein distance indicates a significant change in the price dynamics, which might suggest a market event or shift in investor sentiment.
|
| 104 |
""")
|
| 105 |
|
|
|
|
| 111 |
- Where \( W(P, Q) \) is the Wasserstein distance between distributions \( P \) and \( Q \).
|
| 112 |
- \( d(x, y) \) is the distance between points \( x \) and \( y \).
|
| 113 |
- \( \gamma \) is a joint distribution with marginals \( P \) and \( Q \).
|
|
|
|
|
|
|
|
|
|
| 114 |
""")
|
| 115 |
+
|
| 116 |
+
# Interpretation of results
|
| 117 |
+
st.subheader("Interpretation of Results")
|
| 118 |
+
st.write("""
|
| 119 |
+
**Wasserstein Distance Analysis:**
|
| 120 |
+
The Wasserstein distance quantifies changes in the log returns of asset prices over time.
|
| 121 |
+
A high distance indicates a significant shift in price dynamics, potentially due to a market event or a change in investor behavior.
|
| 122 |
+
""")
|
| 123 |
+
|
| 124 |
st.write(f"Threshold: {threshold}")
|
| 125 |
|
| 126 |
st.write("""
|
| 127 |
**Plot Interpretation:**
|
| 128 |
+
- The first plot shows the asset price over time with alerts marked in red.
|
| 129 |
- 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.
|
| 130 |
""")
|
| 131 |
|
| 132 |
+
# Hide the default Streamlit menu and footer
|
|
|
|
|
|
|
| 133 |
hide_streamlit_style = """
|
| 134 |
<style>
|
| 135 |
#MainMenu {visibility: hidden;}
|
| 136 |
footer {visibility: hidden;}
|
| 137 |
</style>
|
| 138 |
"""
|
| 139 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|