Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -340,18 +340,33 @@ def plot_rolling_pain_index(data: pd.DataFrame, window: int) -> go.Figure:
|
|
| 340 |
st.set_page_config(page_title="Dynamic Risk Management Indicators", layout="wide")
|
| 341 |
st.title('Dynamic Risk Management Indicators')
|
| 342 |
|
|
|
|
|
|
|
| 343 |
# Sidebar for method selection
|
| 344 |
-
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 348 |
|
| 349 |
# Sidebar for input parameters
|
| 350 |
-
st.sidebar.
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
end_date = st.sidebar.date_input('End Date', pd.to_datetime('2024-12-31'))
|
| 354 |
-
window_size = st.sidebar.number_input('Rolling Window Size (Days)', min_value=1, value=252)
|
| 355 |
|
| 356 |
# Fetch data
|
| 357 |
if 'data' not in st.session_state or st.sidebar.button('Fetch Data'):
|
|
@@ -406,14 +421,6 @@ if selected == "Rolling Volatility":
|
|
| 406 |
\text{Volatility of Volatility}_t = \text{std}(\text{Rolling Volatility}_{t-n:t})
|
| 407 |
''')
|
| 408 |
|
| 409 |
-
st.markdown("""
|
| 410 |
-
**How to use:**
|
| 411 |
-
1. Enter the stock ticker, start date, and end date.
|
| 412 |
-
2. Enter the rolling window size.
|
| 413 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 414 |
-
4. The chart will display the rolling volatility and the volatility of volatility.
|
| 415 |
-
""")
|
| 416 |
-
|
| 417 |
fig = plot_rolling_volatility(data, window_size)
|
| 418 |
st.plotly_chart(fig)
|
| 419 |
|
|
@@ -456,14 +463,6 @@ elif selected == "Rolling Sharpe Ratio":
|
|
| 456 |
st.latex(r'''
|
| 457 |
\text{Rolling Sharpe Ratio}_t = \frac{\text{Rolling Average Return}_t - R_f}{\text{Rolling Std Dev}_t} \times \sqrt{252}
|
| 458 |
''')
|
| 459 |
-
st.markdown("""
|
| 460 |
-
|
| 461 |
-
**How to use:**
|
| 462 |
-
1. Enter the stock ticker, start date, and end date.
|
| 463 |
-
2. Enter the rolling window size and risk-free rate.
|
| 464 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 465 |
-
4. The chart will display the rolling Sharpe Ratio.
|
| 466 |
-
""")
|
| 467 |
|
| 468 |
fig = plot_rolling_sharpe(data, window_size, risk_free_rate)
|
| 469 |
st.plotly_chart(fig)
|
|
@@ -510,13 +509,7 @@ elif selected == "Rolling Treynor Ratio":
|
|
| 510 |
\text{Treynor Ratio}_t = \frac{\text{Average Rolling Return}_t - R_f}{\beta_t}
|
| 511 |
''')
|
| 512 |
st.markdown("""
|
| 513 |
-
|
| 514 |
-
|
| 515 |
-
**How to use:**
|
| 516 |
-
1. Enter the stock ticker, start date, and end date.
|
| 517 |
-
2. Enter the benchmark ticker, rolling window size, and risk-free rate.
|
| 518 |
-
3. Click 'Fetch Data' to load the stock and benchmark data.
|
| 519 |
-
4. The chart will display the rolling Treynor Ratio.
|
| 520 |
""")
|
| 521 |
|
| 522 |
fig = plot_rolling_treynor(data, market_data, window_size, risk_free_rate)
|
|
@@ -555,13 +548,7 @@ elif selected == "Rolling Beta":
|
|
| 555 |
\beta_{RANSAC} = \text{RANSAC}(\text{Return}_{\text{benchmark}}, \text{Return}_{\text{stock}})
|
| 556 |
''')
|
| 557 |
st.markdown("""
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
**How to use:**
|
| 561 |
-
1. Enter the stock ticker, start date, and end date.
|
| 562 |
-
2. Enter the benchmark ticker and rolling window size.
|
| 563 |
-
3. Click 'Fetch Data' to load the stock and benchmark data.
|
| 564 |
-
4. The chart will display the rolling beta calculated using both OLS and RANSAC methods.
|
| 565 |
""")
|
| 566 |
|
| 567 |
fig = plot_rolling_beta(data, market_data, window_size)
|
|
@@ -609,13 +596,7 @@ elif selected == "Rolling Jensen's Alpha":
|
|
| 609 |
\alpha_t = \text{Return}_{\text{stock}, t} - \text{Expected Return}_t
|
| 610 |
''')
|
| 611 |
st.markdown("""
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
**How to use:**
|
| 615 |
-
1. Enter the stock ticker, start date, and end date.
|
| 616 |
-
2. Enter the benchmark ticker, rolling window size, and risk-free rate.
|
| 617 |
-
3. Click 'Fetch Data' to load the stock and benchmark data.
|
| 618 |
-
4. The chart will display the rolling Jensen's Alpha.
|
| 619 |
""")
|
| 620 |
|
| 621 |
fig = plot_rolling_alpha(data, market_data, window_size, risk_free_rate)
|
|
@@ -645,16 +626,7 @@ elif selected == "Rolling Value at Risk":
|
|
| 645 |
\text{VaR}_{\alpha, t} = \text{Quantile}_{\alpha}(\text{Return}_{t-n:t})
|
| 646 |
''')
|
| 647 |
st.markdown("""
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
**How to use:**
|
| 651 |
-
1. Enter the stock ticker, start date, and end date.
|
| 652 |
-
2. Enter the rolling window size.
|
| 653 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 654 |
-
4. The chart will display the rolling VaR at different confidence levels.
|
| 655 |
-
|
| 656 |
-
**Results:**
|
| 657 |
-
The chart shows the close prices along with the rolling VaR at different confidence levels over time.
|
| 658 |
""")
|
| 659 |
|
| 660 |
fig = plot_rolling_var(data, window_size)
|
|
@@ -684,16 +656,7 @@ elif selected == "Rolling Conditional VaR":
|
|
| 684 |
\text{CVaR}_{\alpha, t} = \frac{1}{n} \sum_{i=1}^{n} \text{Return}_{i} \text{ where } \text{Return}_{i} < \text{VaR}_{\alpha, t}
|
| 685 |
''')
|
| 686 |
st.markdown("""
|
| 687 |
-
|
| 688 |
-
|
| 689 |
-
**How to use:**
|
| 690 |
-
1. Enter the stock ticker, start date, and end date.
|
| 691 |
-
2. Enter the rolling window size.
|
| 692 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 693 |
-
4. The chart will display the rolling CVaR at different confidence levels.
|
| 694 |
-
|
| 695 |
-
**Results:**
|
| 696 |
-
The chart shows the close prices along with the rolling CVaR at different confidence levels over time.
|
| 697 |
""")
|
| 698 |
|
| 699 |
fig = plot_rolling_cvar(data, window_size)
|
|
@@ -723,16 +686,7 @@ elif selected == "Rolling Tail Ratio":
|
|
| 723 |
\text{Tail Ratio}_t = \frac{|\text{Quantile}_{95}(\text{Return}_{t-n:t})|}{|\text{Quantile}_{5}(\text{Return}_{t-n:t})|}
|
| 724 |
''')
|
| 725 |
st.markdown("""
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
**How to use:**
|
| 729 |
-
1. Enter the stock ticker, start date, and end date.
|
| 730 |
-
2. Enter the rolling window size.
|
| 731 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 732 |
-
4. The chart will display the rolling Tail Ratio.
|
| 733 |
-
|
| 734 |
-
**Results:**
|
| 735 |
-
The chart shows the close prices along with the rolling Tail Ratio over time, indicating the balance between extreme positive and negative returns.
|
| 736 |
""")
|
| 737 |
|
| 738 |
fig = plot_rolling_tail_ratio(data, window_size)
|
|
@@ -762,16 +716,7 @@ elif selected == "Rolling Omega Ratio":
|
|
| 762 |
\text{Omega Ratio}_t = \frac{\sum (\text{Return}_{i} > MAR) (\text{Return}_{i} - MAR)}{\sum (\text{Return}_{i} < MAR) (MAR - \text{Return}_{i})}
|
| 763 |
''')
|
| 764 |
st.markdown("""
|
| 765 |
-
|
| 766 |
-
|
| 767 |
-
**How to use:**
|
| 768 |
-
1. Enter the stock ticker, start date, and end date.
|
| 769 |
-
2. Enter the rolling window size and minimum acceptable return.
|
| 770 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 771 |
-
4. The chart will display the rolling Omega Ratio.
|
| 772 |
-
|
| 773 |
-
**Results:**
|
| 774 |
-
The chart shows the close prices along with the rolling Omega Ratio over time, indicating the risk-return trade-off.
|
| 775 |
""")
|
| 776 |
|
| 777 |
fig = plot_rolling_omega(data, window_size)
|
|
@@ -801,16 +746,7 @@ elif selected == "Rolling Sortino Ratio":
|
|
| 801 |
\text{Sortino Ratio}_t = \frac{\sqrt{252} \cdot \text{Mean}(\text{Return}_{t-n:t} - MAR)}{\sqrt{\text{Mean}(\min(0, \text{Return}_{t-n:t} - MAR)^2)}}
|
| 802 |
''')
|
| 803 |
st.markdown("""
|
| 804 |
-
|
| 805 |
-
|
| 806 |
-
**How to use:**
|
| 807 |
-
1. Enter the stock ticker, start date, and end date.
|
| 808 |
-
2. Enter the rolling window size and minimum acceptable return.
|
| 809 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 810 |
-
4. The chart will display the rolling Sortino Ratio.
|
| 811 |
-
|
| 812 |
-
**Results:**
|
| 813 |
-
The chart shows the close prices along with the rolling Sortino Ratio over time, indicating the risk-adjusted return considering downside risk.
|
| 814 |
""")
|
| 815 |
|
| 816 |
fig = plot_rolling_sortino(data, window_size, MAR)
|
|
@@ -840,16 +776,7 @@ elif selected == "Rolling Calmar Ratio":
|
|
| 840 |
\text{Calmar Ratio}_t = \frac{\text{CAGR}_{t-n:t}}{\text{Max Drawdown}_{t-n:t}}
|
| 841 |
''')
|
| 842 |
st.markdown("""
|
| 843 |
-
|
| 844 |
-
|
| 845 |
-
**How to use:**
|
| 846 |
-
1. Enter the stock ticker, start date, and end date.
|
| 847 |
-
2. Enter the rolling window size.
|
| 848 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 849 |
-
4. The chart will display the rolling Calmar Ratio.
|
| 850 |
-
|
| 851 |
-
**Results:**
|
| 852 |
-
The chart shows the close prices along with the rolling Calmar Ratio over time, indicating the performance of the stock relative to its maximum drawdown.
|
| 853 |
""")
|
| 854 |
|
| 855 |
fig = plot_rolling_calmar(data, window_size)
|
|
@@ -879,16 +806,7 @@ elif selected == "Rolling Stability":
|
|
| 879 |
\text{Stability}_t = \sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (\log(1 + \text{Return}_{t-i}) - \overline{\log(1 + \text{Return})})^2}
|
| 880 |
''')
|
| 881 |
st.markdown("""
|
| 882 |
-
|
| 883 |
-
|
| 884 |
-
**How to use:**
|
| 885 |
-
1. Enter the stock ticker, start date, and end date.
|
| 886 |
-
2. Enter the rolling window size.
|
| 887 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 888 |
-
4. The chart will display the rolling stability.
|
| 889 |
-
|
| 890 |
-
**Results:**
|
| 891 |
-
The chart shows the close prices along with the rolling stability over time, indicating the consistency of returns.
|
| 892 |
""")
|
| 893 |
|
| 894 |
fig = plot_rolling_stability(data, window_size)
|
|
@@ -921,16 +839,7 @@ elif selected == "Rolling Maximum Drawdown":
|
|
| 921 |
\text{Max Drawdown}_t = \frac{\text{Cumulative Return}_t - \text{Rolling Max Cumulative Return}_t}{\text{Rolling Max Cumulative Return}_t}
|
| 922 |
''')
|
| 923 |
st.markdown("""
|
| 924 |
-
|
| 925 |
-
|
| 926 |
-
**How to use:**
|
| 927 |
-
1. Enter the stock ticker, start date, and end date.
|
| 928 |
-
2. Enter the rolling window size.
|
| 929 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 930 |
-
4. The chart will display the rolling maximum drawdown.
|
| 931 |
-
|
| 932 |
-
**Results:**
|
| 933 |
-
The chart shows the close prices along with the rolling maximum drawdown over time, indicating the peak-to-trough decline during a specified period.
|
| 934 |
""")
|
| 935 |
|
| 936 |
fig = plot_rolling_drawdown(data, window_size)
|
|
@@ -966,16 +875,6 @@ elif selected == "Rolling Capture Ratios":
|
|
| 966 |
st.latex(r'''
|
| 967 |
\text{Downside Capture Ratio}_t = \frac{\sum_{i=1}^{t} \text{Return}_{\text{stock}, i}}{\sum_{i=1}^{t} \text{Return}_{\text{benchmark}, i}}, \quad \text{if } \text{Return}_{\text{benchmark}, i} < 0
|
| 968 |
''')
|
| 969 |
-
st.markdown("""
|
| 970 |
-
**How to use:**
|
| 971 |
-
1. Enter the stock ticker, start date, and end date.
|
| 972 |
-
2. Enter the benchmark ticker and rolling window size.
|
| 973 |
-
3. Click 'Fetch Data' to load the stock and benchmark data.
|
| 974 |
-
4. The chart will display the rolling capture ratios.
|
| 975 |
-
|
| 976 |
-
**Results:**
|
| 977 |
-
The chart shows the close prices along with the rolling upside and downside capture ratios over time, indicating the stock's performance relative to the benchmark during up and down market conditions.
|
| 978 |
-
""")
|
| 979 |
|
| 980 |
fig = plot_rolling_capture(data, market_data, window_size)
|
| 981 |
st.plotly_chart(fig)
|
|
@@ -1017,16 +916,6 @@ elif selected == "Rolling Pain Index":
|
|
| 1017 |
st.latex(r'''
|
| 1018 |
\text{Pain Index} = \frac{1}{n} \sum_{i=1}^{n} \text{Drawdown}_i \quad \text{for } \text{Drawdown}_i < 0
|
| 1019 |
''')
|
| 1020 |
-
st.markdown("""
|
| 1021 |
-
**How to use:**
|
| 1022 |
-
1. Enter the stock ticker, start date, and end date.
|
| 1023 |
-
2. Enter the rolling window size.
|
| 1024 |
-
3. Click 'Fetch Data' to load the stock data.
|
| 1025 |
-
4. The chart will display the rolling pain index.
|
| 1026 |
-
|
| 1027 |
-
**Results:**
|
| 1028 |
-
The chart shows the close prices along with the rolling pain index over time, indicating the average drawdown experienced over a specified period.
|
| 1029 |
-
""")
|
| 1030 |
|
| 1031 |
fig = plot_rolling_pain_index(data, window_size)
|
| 1032 |
st.plotly_chart(fig)
|
|
|
|
| 340 |
st.set_page_config(page_title="Dynamic Risk Management Indicators", layout="wide")
|
| 341 |
st.title('Dynamic Risk Management Indicators')
|
| 342 |
|
| 343 |
+
st.sidebar.title("Input Parameters")
|
| 344 |
+
|
| 345 |
# Sidebar for method selection
|
| 346 |
+
import datetime
|
| 347 |
+
|
| 348 |
+
# Setting today's date plus one day
|
| 349 |
+
today_plus_one = pd.to_datetime(datetime.datetime.now().date() + pd.Timedelta(days=1))
|
| 350 |
+
|
| 351 |
+
# Sidebar for ticker and dates inside an expander
|
| 352 |
+
with st.sidebar.expander("Ticker and Dates", expanded=True):
|
| 353 |
+
ticker = st.text_input('Enter Stock Ticker', 'VOW.DE', help="Enter the stock or crypto ticker symbol (e.g., AAPL, BTC-USD).")
|
| 354 |
+
start_date = st.date_input('Start Date', pd.to_datetime('2010-01-01'), help="Select the start date for the data analysis.")
|
| 355 |
+
end_date = st.date_input('End Date', today_plus_one, help="Select the end date for the data analysis.")
|
| 356 |
+
|
| 357 |
+
# Sidebar for method selection inside an expander
|
| 358 |
+
with st.sidebar.expander("Select Method", expanded=True):
|
| 359 |
+
selected = st.radio("Select Indicator",
|
| 360 |
+
["Rolling Volatility", "Rolling Sharpe Ratio", "Rolling Treynor Ratio", "Rolling Beta", "Rolling Jensen's Alpha",
|
| 361 |
+
"Rolling Value at Risk", "Rolling Conditional VaR", "Rolling Tail Ratio", "Rolling Omega Ratio",
|
| 362 |
+
"Rolling Sortino Ratio", "Rolling Calmar Ratio", "Rolling Stability", "Rolling Maximum Drawdown",
|
| 363 |
+
"Rolling Capture Ratios", "Rolling Pain Index"],
|
| 364 |
+
help="Choose the financial risk indicator you want to calculate and analyze.")
|
| 365 |
|
| 366 |
# Sidebar for input parameters
|
| 367 |
+
window_size = st.sidebar.number_input('Rolling Window Size (Days)', min_value=1, value=252,
|
| 368 |
+
help="Enter the number of days to use for the rolling window in the selected risk indicator calculation.")
|
| 369 |
+
|
|
|
|
|
|
|
| 370 |
|
| 371 |
# Fetch data
|
| 372 |
if 'data' not in st.session_state or st.sidebar.button('Fetch Data'):
|
|
|
|
| 421 |
\text{Volatility of Volatility}_t = \text{std}(\text{Rolling Volatility}_{t-n:t})
|
| 422 |
''')
|
| 423 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 424 |
fig = plot_rolling_volatility(data, window_size)
|
| 425 |
st.plotly_chart(fig)
|
| 426 |
|
|
|
|
| 463 |
st.latex(r'''
|
| 464 |
\text{Rolling Sharpe Ratio}_t = \frac{\text{Rolling Average Return}_t - R_f}{\text{Rolling Std Dev}_t} \times \sqrt{252}
|
| 465 |
''')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 466 |
|
| 467 |
fig = plot_rolling_sharpe(data, window_size, risk_free_rate)
|
| 468 |
st.plotly_chart(fig)
|
|
|
|
| 509 |
\text{Treynor Ratio}_t = \frac{\text{Average Rolling Return}_t - R_f}{\beta_t}
|
| 510 |
''')
|
| 511 |
st.markdown("""
|
| 512 |
+
where \( R_f \) is the risk-free rate.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 513 |
""")
|
| 514 |
|
| 515 |
fig = plot_rolling_treynor(data, market_data, window_size, risk_free_rate)
|
|
|
|
| 548 |
\beta_{RANSAC} = \text{RANSAC}(\text{Return}_{\text{benchmark}}, \text{Return}_{\text{stock}})
|
| 549 |
''')
|
| 550 |
st.markdown("""
|
| 551 |
+
RANSAC algorithm iteratively fits the model and removes outliers.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 552 |
""")
|
| 553 |
|
| 554 |
fig = plot_rolling_beta(data, market_data, window_size)
|
|
|
|
| 596 |
\alpha_t = \text{Return}_{\text{stock}, t} - \text{Expected Return}_t
|
| 597 |
''')
|
| 598 |
st.markdown("""
|
| 599 |
+
where \( \alpha_t \) is Jensen's Alpha at time \( t \).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 600 |
""")
|
| 601 |
|
| 602 |
fig = plot_rolling_alpha(data, market_data, window_size, risk_free_rate)
|
|
|
|
| 626 |
\text{VaR}_{\alpha, t} = \text{Quantile}_{\alpha}(\text{Return}_{t-n:t})
|
| 627 |
''')
|
| 628 |
st.markdown("""
|
| 629 |
+
where \( \alpha \) is the confidence level and \( n \) is the window size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 630 |
""")
|
| 631 |
|
| 632 |
fig = plot_rolling_var(data, window_size)
|
|
|
|
| 656 |
\text{CVaR}_{\alpha, t} = \frac{1}{n} \sum_{i=1}^{n} \text{Return}_{i} \text{ where } \text{Return}_{i} < \text{VaR}_{\alpha, t}
|
| 657 |
''')
|
| 658 |
st.markdown("""
|
| 659 |
+
where \( n \) is the number of returns below the VaR threshold and \( \alpha \) is the confidence level.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 660 |
""")
|
| 661 |
|
| 662 |
fig = plot_rolling_cvar(data, window_size)
|
|
|
|
| 686 |
\text{Tail Ratio}_t = \frac{|\text{Quantile}_{95}(\text{Return}_{t-n:t})|}{|\text{Quantile}_{5}(\text{Return}_{t-n:t})|}
|
| 687 |
''')
|
| 688 |
st.markdown("""
|
| 689 |
+
where \( n \) is the window size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
""")
|
| 691 |
|
| 692 |
fig = plot_rolling_tail_ratio(data, window_size)
|
|
|
|
| 716 |
\text{Omega Ratio}_t = \frac{\sum (\text{Return}_{i} > MAR) (\text{Return}_{i} - MAR)}{\sum (\text{Return}_{i} < MAR) (MAR - \text{Return}_{i})}
|
| 717 |
''')
|
| 718 |
st.markdown("""
|
| 719 |
+
where \( MAR \) is the Minimum Acceptable Return and \( n \) is the window size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 720 |
""")
|
| 721 |
|
| 722 |
fig = plot_rolling_omega(data, window_size)
|
|
|
|
| 746 |
\text{Sortino Ratio}_t = \frac{\sqrt{252} \cdot \text{Mean}(\text{Return}_{t-n:t} - MAR)}{\sqrt{\text{Mean}(\min(0, \text{Return}_{t-n:t} - MAR)^2)}}
|
| 747 |
''')
|
| 748 |
st.markdown("""
|
| 749 |
+
where \( MAR \) is the Minimum Acceptable Return and \( n \) is the window size.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 750 |
""")
|
| 751 |
|
| 752 |
fig = plot_rolling_sortino(data, window_size, MAR)
|
|
|
|
| 776 |
\text{Calmar Ratio}_t = \frac{\text{CAGR}_{t-n:t}}{\text{Max Drawdown}_{t-n:t}}
|
| 777 |
''')
|
| 778 |
st.markdown("""
|
| 779 |
+
where \( \text{CAGR} \) is the Compound Annual Growth Rate and \( \text{Max Drawdown} \) is the maximum drawdown over the window \( n \).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 780 |
""")
|
| 781 |
|
| 782 |
fig = plot_rolling_calmar(data, window_size)
|
|
|
|
| 806 |
\text{Stability}_t = \sqrt{\frac{1}{n-1} \sum_{i=1}^{n} (\log(1 + \text{Return}_{t-i}) - \overline{\log(1 + \text{Return})})^2}
|
| 807 |
''')
|
| 808 |
st.markdown("""
|
| 809 |
+
where \( n \) is the window size and \( \overline{\log(1 + \text{Return})} \) is the mean of the log returns over the window.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 810 |
""")
|
| 811 |
|
| 812 |
fig = plot_rolling_stability(data, window_size)
|
|
|
|
| 839 |
\text{Max Drawdown}_t = \frac{\text{Cumulative Return}_t - \text{Rolling Max Cumulative Return}_t}{\text{Rolling Max Cumulative Return}_t}
|
| 840 |
''')
|
| 841 |
st.markdown("""
|
| 842 |
+
where the Rolling Max Cumulative Return is the maximum cumulative return over the window.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 843 |
""")
|
| 844 |
|
| 845 |
fig = plot_rolling_drawdown(data, window_size)
|
|
|
|
| 875 |
st.latex(r'''
|
| 876 |
\text{Downside Capture Ratio}_t = \frac{\sum_{i=1}^{t} \text{Return}_{\text{stock}, i}}{\sum_{i=1}^{t} \text{Return}_{\text{benchmark}, i}}, \quad \text{if } \text{Return}_{\text{benchmark}, i} < 0
|
| 877 |
''')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 878 |
|
| 879 |
fig = plot_rolling_capture(data, market_data, window_size)
|
| 880 |
st.plotly_chart(fig)
|
|
|
|
| 916 |
st.latex(r'''
|
| 917 |
\text{Pain Index} = \frac{1}{n} \sum_{i=1}^{n} \text{Drawdown}_i \quad \text{for } \text{Drawdown}_i < 0
|
| 918 |
''')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 919 |
|
| 920 |
fig = plot_rolling_pain_index(data, window_size)
|
| 921 |
st.plotly_chart(fig)
|