Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -11,7 +11,7 @@ from ta.volatility import BollingerBands
|
|
| 11 |
|
| 12 |
# Helper functions
|
| 13 |
def fetch_stock_data(ticker: str, start_date: str, end_date: str) -> pd.DataFrame:
|
| 14 |
-
"""Fetch stock data from Yahoo Finance."""
|
| 15 |
return yf.download(ticker, start=start_date, end=end_date)
|
| 16 |
|
| 17 |
def plot_z_score(close_prices: pd.Series, periods: list, z_thresh: float, n_days: int) -> go.Figure:
|
|
@@ -40,15 +40,12 @@ def plot_z_score(close_prices: pd.Series, periods: list, z_thresh: float, n_days
|
|
| 40 |
|
| 41 |
fig.add_trace(go.Scatter(x=close_prices[buy_signals].index, y=close_prices[buy_signals],
|
| 42 |
mode='markers', marker=dict(color='green', symbol='triangle-up', size=10),
|
| 43 |
-
# name=f'Buy Signal {period} days (Correct: {buy_correct_pct:.1f}% in {n_days} days)'), row=1, col=1)
|
| 44 |
name=f'Buy Signal {period} days'), row=1, col=1)
|
| 45 |
fig.add_trace(go.Scatter(x=close_prices[sell_signals].index, y=close_prices[sell_signals],
|
| 46 |
mode='markers', marker=dict(color='red', symbol='triangle-down', size=10),
|
| 47 |
-
# name=f'Sell Signal {period} days (Correct: {sell_correct_pct:.1f}% in {n_days} days)'), row=1, col=1)
|
| 48 |
name=f'Sell Signal {period} days'), row=1, col=1)
|
| 49 |
fig.add_trace(go.Scatter(x=close_prices.index, y=z_scores, mode='lines', name=f'Rolling Z-Score {period}'), row=2, col=1)
|
| 50 |
|
| 51 |
-
|
| 52 |
# Add threshold lines
|
| 53 |
fig.add_hline(y=z_thresh, line=dict(color='red', dash='dash'), row=2, col=1)
|
| 54 |
fig.add_hline(y=-z_thresh, line=dict(color='green', dash='dash'), row=2, col=1)
|
|
@@ -288,13 +285,14 @@ st.set_page_config(page_title="Technical Analysis", layout="wide")
|
|
| 288 |
st.title('Technical Analysis Indicators')
|
| 289 |
|
| 290 |
# Sidebar for method selection
|
| 291 |
-
|
|
|
|
| 292 |
|
| 293 |
# Sidebar for input parameters
|
| 294 |
-
st.sidebar.
|
| 295 |
-
ticker = st.
|
| 296 |
-
start_date = st.
|
| 297 |
-
end_date = st.
|
| 298 |
|
| 299 |
# Fetch data
|
| 300 |
if 'data' not in st.session_state or st.sidebar.button('Fetch Data'):
|
|
@@ -303,40 +301,51 @@ if 'data' not in st.session_state or st.sidebar.button('Fetch Data'):
|
|
| 303 |
data = st.session_state.data
|
| 304 |
close_prices = data['Close']
|
| 305 |
|
| 306 |
-
#
|
| 307 |
-
|
| 308 |
st.markdown("""
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
1. **Calculate Rolling Mean and Standard Deviation:**
|
| 316 |
-
- For each time period (e.g., 20 days), compute the rolling mean and rolling standard deviation of the stock prices.
|
| 317 |
-
|
| 318 |
-
2. **Compute Z-Score:**
|
| 319 |
-
- For each day, calculate the z-score using:
|
| 320 |
-
""")
|
| 321 |
-
st.latex(r'''
|
| 322 |
-
\text{Z-Score} = \frac{\text{Close Price} - \text{Rolling Mean}}{\text{Rolling Standard Deviation}}
|
| 323 |
-
''')
|
| 324 |
-
st.markdown("""
|
| 325 |
-
3. **Identify Signals:**
|
| 326 |
-
- **Overbought Condition:** Z-score above a set threshold (e.g., 2.0) suggests the stock may be overbought.
|
| 327 |
-
- **Oversold Condition:** Z-score below a set threshold (e.g., -2.0) suggests the stock may be oversold.
|
| 328 |
-
|
| 329 |
-
**How to Use:**
|
| 330 |
-
1. Enter the stock ticker, start date, and end date.
|
| 331 |
-
2. Set the number of days for the z-score calculation.
|
| 332 |
-
3. Set the z-score threshold.
|
| 333 |
-
4. Click 'Fetch Data' to load the stock data.
|
| 334 |
-
5. The chart will display the rolling z-scores and highlight buy/sell signals based on the thresholds.
|
| 335 |
-
|
| 336 |
-
**Results:**
|
| 337 |
-
The chart shows the close prices with highlighted buy/sell signals and their correctness percentage over a specified period.
|
| 338 |
""")
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
periods = st.sidebar.multiselect('Periods to Compare', options=[10, 20, 30, 40, 50], default=[20])
|
| 341 |
z_thresh = st.sidebar.slider('Z-Score Threshold', min_value=0.5, max_value=3.0, value=2.0, step=0.1)
|
| 342 |
n_days = st.sidebar.number_input('Number of Days', min_value=1, value=10)
|
|
@@ -344,68 +353,59 @@ if selected == "Rolling Z-Score":
|
|
| 344 |
st.plotly_chart(fig)
|
| 345 |
|
| 346 |
elif selected == "Rate of Change (ROC)":
|
| 347 |
-
st.
|
| 348 |
-
|
| 349 |
-
|
| 350 |
-
|
| 351 |
-
|
| 352 |
-
|
| 353 |
-
|
| 354 |
-
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
|
| 363 |
-
|
| 364 |
-
|
| 365 |
-
|
| 366 |
-
|
| 367 |
-
|
| 368 |
-
|
| 369 |
-
|
| 370 |
-
|
| 371 |
-
**Results:**
|
| 372 |
-
The chart shows the stock prices with highlighted buy/sell signals based on ROC.
|
| 373 |
-
""")
|
| 374 |
|
| 375 |
n_days = st.sidebar.number_input('Number of Days', min_value=1, value=14)
|
| 376 |
fig = plot_roc(close_prices, n_days)
|
| 377 |
st.plotly_chart(fig)
|
| 378 |
|
| 379 |
elif selected == "Stochastic Oscillator":
|
| 380 |
-
st.
|
| 381 |
-
|
| 382 |
-
|
| 383 |
-
|
| 384 |
-
|
| 385 |
-
|
| 386 |
-
|
| 387 |
-
|
| 388 |
-
|
| 389 |
-
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
|
| 399 |
-
|
| 400 |
-
|
| 401 |
-
|
| 402 |
-
|
| 403 |
-
|
| 404 |
-
4. The chart will display the Stochastic Oscillator and highlight buy/sell signals based on thresholds.
|
| 405 |
-
|
| 406 |
-
**Results:**
|
| 407 |
-
The chart shows the closing prices with highlighted buy/sell signals and the %K and %D lines.
|
| 408 |
-
""")
|
| 409 |
|
| 410 |
buy_thresh = st.sidebar.slider('Stochastic Buy Threshold', min_value=0, max_value=100, value=5)
|
| 411 |
sell_thresh = st.sidebar.slider('Stochastic Sell Threshold', min_value=0, max_value=100, value=95)
|
|
@@ -413,34 +413,30 @@ elif selected == "Stochastic Oscillator":
|
|
| 413 |
st.plotly_chart(fig)
|
| 414 |
|
| 415 |
elif selected == "Relative Strength Index (RSI)":
|
| 416 |
-
st.
|
| 417 |
-
|
| 418 |
-
|
| 419 |
-
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
**Results:**
|
| 442 |
-
The chart shows the stock prices with highlighted buy/sell signals and the RSI line.
|
| 443 |
-
""")
|
| 444 |
|
| 445 |
buy_thresh = st.sidebar.slider('RSI Buy Threshold', min_value=0, max_value=100, value=30)
|
| 446 |
sell_thresh = st.sidebar.slider('RSI Sell Threshold', min_value=0, max_value=100, value=70)
|
|
@@ -448,106 +444,92 @@ elif selected == "Relative Strength Index (RSI)":
|
|
| 448 |
st.plotly_chart(fig)
|
| 449 |
|
| 450 |
elif selected == "MACD":
|
| 451 |
-
st.
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
| 456 |
-
|
| 457 |
-
|
| 458 |
-
|
| 459 |
-
|
| 460 |
-
|
| 461 |
-
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
3. The chart will display the MACD line, Signal line, and Histogram, and highlight buy/sell signals based on MACD crossovers.
|
| 476 |
-
|
| 477 |
-
**Results:**
|
| 478 |
-
The chart shows the stock prices with highlighted buy/sell signals, MACD line, Signal line, and Histogram.
|
| 479 |
-
""")
|
| 480 |
|
| 481 |
fig = plot_macd(close_prices)
|
| 482 |
st.plotly_chart(fig)
|
| 483 |
|
| 484 |
elif selected == "Bollinger Bands":
|
| 485 |
-
st.
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
|
| 489 |
-
|
| 490 |
-
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
| 496 |
-
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
3. The chart will display the Bollinger Bands and highlight buy/sell signals based on price crossing the bands.
|
| 513 |
-
|
| 514 |
-
**Results:**
|
| 515 |
-
The chart shows the stock prices with highlighted buy/sell signals and the Bollinger Bands.
|
| 516 |
-
""")
|
| 517 |
|
| 518 |
fig = plot_bollinger_bands(close_prices)
|
| 519 |
st.plotly_chart(fig)
|
| 520 |
|
| 521 |
elif selected == "K Reversal":
|
| 522 |
-
st.
|
| 523 |
-
|
| 524 |
-
|
| 525 |
-
|
| 526 |
-
|
| 527 |
-
|
| 528 |
-
|
| 529 |
-
|
| 530 |
-
|
| 531 |
-
|
| 532 |
-
|
| 533 |
-
|
| 534 |
-
|
| 535 |
-
|
| 536 |
-
|
| 537 |
-
|
| 538 |
-
|
| 539 |
-
|
| 540 |
-
|
| 541 |
-
|
| 542 |
-
|
| 543 |
-
|
| 544 |
-
|
| 545 |
-
|
| 546 |
-
|
| 547 |
-
|
| 548 |
-
**Results:**
|
| 549 |
-
The chart shows the stock prices with the K Reversal indicator and highlighted buy/sell signals.
|
| 550 |
-
""")
|
| 551 |
|
| 552 |
k_period = st.sidebar.number_input('K Reversal Period', min_value=1, value=14)
|
| 553 |
k_buy_thresh = st.sidebar.slider('K Reversal Buy Threshold', min_value=0.0, max_value=100.0, value=10.0)
|
|
@@ -556,44 +538,39 @@ elif selected == "K Reversal":
|
|
| 556 |
st.plotly_chart(fig)
|
| 557 |
|
| 558 |
elif selected == "Awesome Oscillator":
|
| 559 |
-
st.
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
|
| 565 |
-
|
| 566 |
-
|
| 567 |
-
|
| 568 |
-
|
| 569 |
-
|
| 570 |
-
|
| 571 |
-
|
| 572 |
-
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
| 578 |
-
|
| 579 |
-
|
| 580 |
-
|
| 581 |
-
|
| 582 |
-
|
| 583 |
-
|
| 584 |
-
|
| 585 |
-
|
| 586 |
-
|
| 587 |
-
|
| 588 |
-
|
| 589 |
-
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
5. The chart will display the Awesome Oscillator and highlight buy/sell signals based on thresholds.
|
| 593 |
-
|
| 594 |
-
**Results:**
|
| 595 |
-
The chart shows the stock prices with the Awesome Oscillator and highlighted buy/sell signals.
|
| 596 |
-
""")
|
| 597 |
|
| 598 |
signal_period = st.sidebar.number_input('Signal Line Period', min_value=1, value=9)
|
| 599 |
ao_buy_thresh = st.sidebar.slider('AO Buy Threshold', min_value=-100.0, max_value=100.0, value=0.0)
|
|
@@ -602,35 +579,31 @@ elif selected == "Awesome Oscillator":
|
|
| 602 |
st.plotly_chart(fig)
|
| 603 |
|
| 604 |
elif selected == "Williams %R":
|
| 605 |
-
st.
|
| 606 |
-
|
| 607 |
-
|
| 608 |
-
|
| 609 |
-
|
| 610 |
-
|
| 611 |
-
|
| 612 |
-
|
| 613 |
-
|
| 614 |
-
|
| 615 |
-
|
| 616 |
-
|
| 617 |
-
|
| 618 |
-
|
| 619 |
-
|
| 620 |
-
|
| 621 |
-
|
| 622 |
-
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
|
| 626 |
-
|
| 627 |
-
|
| 628 |
-
|
| 629 |
-
|
| 630 |
-
|
| 631 |
-
**Results:**
|
| 632 |
-
The chart shows the stock prices with the Williams %R and highlighted buy/sell signals.
|
| 633 |
-
""")
|
| 634 |
|
| 635 |
williams_r_period = st.sidebar.number_input('Look-back Period', min_value=1, value=14)
|
| 636 |
williams_r_buy_thresh = st.sidebar.slider('Williams %R Buy Threshold', min_value=-100.0, max_value=0.0, value=-90.0)
|
|
@@ -639,46 +612,42 @@ elif selected == "Williams %R":
|
|
| 639 |
st.plotly_chart(fig)
|
| 640 |
|
| 641 |
elif selected == "Aroon Oscillator":
|
| 642 |
-
st.
|
| 643 |
-
|
| 644 |
-
|
| 645 |
-
|
| 646 |
-
|
| 647 |
-
|
| 648 |
-
|
| 649 |
-
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
| 654 |
-
|
| 655 |
-
|
| 656 |
-
|
| 657 |
-
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
| 661 |
-
|
| 662 |
-
|
| 663 |
-
|
| 664 |
-
|
| 665 |
-
|
| 666 |
-
|
| 667 |
-
|
| 668 |
-
|
| 669 |
-
|
| 670 |
-
|
| 671 |
-
|
| 672 |
-
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
| 678 |
-
|
| 679 |
-
**Results:**
|
| 680 |
-
The chart shows the stock prices with the Aroon Oscillator and highlighted buy/sell signals.
|
| 681 |
-
""")
|
| 682 |
|
| 683 |
aroon_period = st.sidebar.number_input('Look-back Period', min_value=1, value=25)
|
| 684 |
aroon_osc = aroon_oscillator(data, aroon_period)
|
|
@@ -693,4 +662,4 @@ hide_streamlit_style = """
|
|
| 693 |
footer {visibility: hidden;}
|
| 694 |
</style>
|
| 695 |
"""
|
| 696 |
-
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|
|
|
|
| 11 |
|
| 12 |
# Helper functions
|
| 13 |
def fetch_stock_data(ticker: str, start_date: str, end_date: str) -> pd.DataFrame:
|
| 14 |
+
"""Fetch stock or crypto data from Yahoo Finance."""
|
| 15 |
return yf.download(ticker, start=start_date, end=end_date)
|
| 16 |
|
| 17 |
def plot_z_score(close_prices: pd.Series, periods: list, z_thresh: float, n_days: int) -> go.Figure:
|
|
|
|
| 40 |
|
| 41 |
fig.add_trace(go.Scatter(x=close_prices[buy_signals].index, y=close_prices[buy_signals],
|
| 42 |
mode='markers', marker=dict(color='green', symbol='triangle-up', size=10),
|
|
|
|
| 43 |
name=f'Buy Signal {period} days'), row=1, col=1)
|
| 44 |
fig.add_trace(go.Scatter(x=close_prices[sell_signals].index, y=close_prices[sell_signals],
|
| 45 |
mode='markers', marker=dict(color='red', symbol='triangle-down', size=10),
|
|
|
|
| 46 |
name=f'Sell Signal {period} days'), row=1, col=1)
|
| 47 |
fig.add_trace(go.Scatter(x=close_prices.index, y=z_scores, mode='lines', name=f'Rolling Z-Score {period}'), row=2, col=1)
|
| 48 |
|
|
|
|
| 49 |
# Add threshold lines
|
| 50 |
fig.add_hline(y=z_thresh, line=dict(color='red', dash='dash'), row=2, col=1)
|
| 51 |
fig.add_hline(y=-z_thresh, line=dict(color='green', dash='dash'), row=2, col=1)
|
|
|
|
| 285 |
st.title('Technical Analysis Indicators')
|
| 286 |
|
| 287 |
# Sidebar for method selection
|
| 288 |
+
with st.sidebar.expander("Method Selection", expanded=True):
|
| 289 |
+
selected = st.radio("Select Indicator", ["Rolling Z-Score", "Rate of Change (ROC)", "Stochastic Oscillator", "Relative Strength Index (RSI)", "MACD", "Bollinger Bands", "K Reversal", "Awesome Oscillator", "Williams %R", "Aroon Oscillator"])
|
| 290 |
|
| 291 |
# Sidebar for input parameters
|
| 292 |
+
with st.sidebar.expander("Input Parameters", expanded=True):
|
| 293 |
+
ticker = st.text_input('Enter Stock or Crypto Symbol (e.g., AAPL or BTC-USD)', 'AAPL')
|
| 294 |
+
start_date = st.date_input('Start Date', pd.to_datetime('2019-01-01'))
|
| 295 |
+
end_date = st.date_input('End Date', pd.to_datetime(pd.Timestamp.now().date() + pd.Timedelta(days=1)))
|
| 296 |
|
| 297 |
# Fetch data
|
| 298 |
if 'data' not in st.session_state or st.sidebar.button('Fetch Data'):
|
|
|
|
| 301 |
data = st.session_state.data
|
| 302 |
close_prices = data['Close']
|
| 303 |
|
| 304 |
+
# Expander for "How to" section
|
| 305 |
+
with st.expander("How to Use This App", expanded=False):
|
| 306 |
st.markdown("""
|
| 307 |
+
1. Use the sidebar to select an indicator and input parameters.
|
| 308 |
+
2. Enter the stock or cryptocurrency symbol (e.g., 'AAPL' for Apple or 'BTC-USD' for Bitcoin).
|
| 309 |
+
3. Choose the date range for the data.
|
| 310 |
+
4. Click 'Fetch Data' to load and visualize the data.
|
| 311 |
+
5. Use the parameter settings for each method to fine-tune the analysis.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 312 |
""")
|
| 313 |
|
| 314 |
+
# Display results based on the selected method
|
| 315 |
+
if selected == "Rolling Z-Score":
|
| 316 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 317 |
+
st.markdown("""
|
| 318 |
+
### Rolling Z-Score
|
| 319 |
+
|
| 320 |
+
The rolling z-score method identifies overbought and oversold conditions by standardizing stock prices over different periods.
|
| 321 |
+
|
| 322 |
+
**How it Works:**
|
| 323 |
+
|
| 324 |
+
1. **Calculate Rolling Mean and Standard Deviation:**
|
| 325 |
+
- For each time period (e.g., 20 days), compute the rolling mean and rolling standard deviation of the stock prices.
|
| 326 |
+
|
| 327 |
+
2. **Compute Z-Score:**
|
| 328 |
+
- For each day, calculate the z-score using:
|
| 329 |
+
""")
|
| 330 |
+
st.latex(r'''
|
| 331 |
+
\text{Z-Score} = \frac{\text{Close Price} - \text{Rolling Mean}}{\text{Rolling Standard Deviation}}
|
| 332 |
+
''')
|
| 333 |
+
st.markdown("""
|
| 334 |
+
3. **Identify Signals:**
|
| 335 |
+
- **Overbought Condition:** Z-score above a set threshold (e.g., 2.0) suggests the stock may be overbought.
|
| 336 |
+
- **Oversold Condition:** Z-score below a set threshold (e.g., -2.0) suggests the stock may be oversold.
|
| 337 |
+
|
| 338 |
+
**How to Use:**
|
| 339 |
+
1. Enter the stock ticker, start date, and end date.
|
| 340 |
+
2. Set the number of days for the z-score calculation.
|
| 341 |
+
3. Set the z-score threshold.
|
| 342 |
+
4. Click 'Fetch Data' to load the stock data.
|
| 343 |
+
5. The chart will display the rolling z-scores and highlight buy/sell signals based on the thresholds.
|
| 344 |
+
|
| 345 |
+
**Results:**
|
| 346 |
+
The chart shows the close prices with highlighted buy/sell signals and their correctness percentage over a specified period.
|
| 347 |
+
""")
|
| 348 |
+
|
| 349 |
periods = st.sidebar.multiselect('Periods to Compare', options=[10, 20, 30, 40, 50], default=[20])
|
| 350 |
z_thresh = st.sidebar.slider('Z-Score Threshold', min_value=0.5, max_value=3.0, value=2.0, step=0.1)
|
| 351 |
n_days = st.sidebar.number_input('Number of Days', min_value=1, value=10)
|
|
|
|
| 353 |
st.plotly_chart(fig)
|
| 354 |
|
| 355 |
elif selected == "Rate of Change (ROC)":
|
| 356 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 357 |
+
st.markdown("""
|
| 358 |
+
### Rate of Change (ROC)
|
| 359 |
+
The Rate of Change (ROC) method measures the percentage change in stock prices over a specified period. It helps identify momentum and potential reversal points in the stock price.
|
| 360 |
+
**How it Works:**
|
| 361 |
+
1. **Calculate ROC:**
|
| 362 |
+
- For each day, calculate the ROC using the formula:
|
| 363 |
+
""")
|
| 364 |
+
st.latex(r'''
|
| 365 |
+
\text{ROC} = \frac{\text{Current Price} - \text{Price} \, n \, \text{days ago}}{\text{Price} \, n \, \text{days ago}} \times 100
|
| 366 |
+
''')
|
| 367 |
+
st.markdown("""
|
| 368 |
+
2. **Identify Signals:**
|
| 369 |
+
- **Buy Signal:** Occurs when the ROC crosses above zero, indicating potential upward momentum.
|
| 370 |
+
- **Sell Signal:** Occurs when the ROC crosses below zero, indicating potential downward momentum.
|
| 371 |
+
**How to Use:**
|
| 372 |
+
1. Enter the stock ticker, start date, and end date.
|
| 373 |
+
2. Set the number of days for the ROC calculation.
|
| 374 |
+
3. Click 'Fetch Data' to load the stock data.
|
| 375 |
+
4. The chart will display the ROC and highlight buy/sell signals based on the ROC crossing zero.
|
| 376 |
+
**Results:**
|
| 377 |
+
The chart shows the stock prices with highlighted buy/sell signals based on ROC.
|
| 378 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 379 |
|
| 380 |
n_days = st.sidebar.number_input('Number of Days', min_value=1, value=14)
|
| 381 |
fig = plot_roc(close_prices, n_days)
|
| 382 |
st.plotly_chart(fig)
|
| 383 |
|
| 384 |
elif selected == "Stochastic Oscillator":
|
| 385 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 386 |
+
st.markdown("""
|
| 387 |
+
### Stochastic Oscillator
|
| 388 |
+
The Stochastic Oscillator compares a stock's closing price to its price range over a specified period. It helps identify overbought and oversold conditions.
|
| 389 |
+
**How it Works:**
|
| 390 |
+
1. **Calculate %K and %D:**
|
| 391 |
+
- The %K line is calculated as follows:
|
| 392 |
+
""")
|
| 393 |
+
st.latex(r'''
|
| 394 |
+
\%K = \frac{\text{Current Close} - \text{Lowest Low}}{\text{Highest High} - \text{Lowest Low}} \times 100
|
| 395 |
+
''')
|
| 396 |
+
st.markdown("""
|
| 397 |
+
- The %D line is the 3-period moving average of %K.
|
| 398 |
+
2. **Identify Signals:**
|
| 399 |
+
- **Buy Signal:** Occurs when %K crosses above a set threshold (e.g., 20), indicating potential upward momentum.
|
| 400 |
+
- **Sell Signal:** Occurs when %K crosses below a set threshold (e.g., 80), indicating potential downward momentum.
|
| 401 |
+
**How to Use:**
|
| 402 |
+
1. Enter the stock ticker, start date, and end date.
|
| 403 |
+
2. Set the buy and sell thresholds.
|
| 404 |
+
3. Click 'Fetch Data' to load the stock data.
|
| 405 |
+
4. The chart will display the Stochastic Oscillator and highlight buy/sell signals based on thresholds.
|
| 406 |
+
**Results:**
|
| 407 |
+
The chart shows the closing prices with highlighted buy/sell signals and the %K and %D lines.
|
| 408 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 409 |
|
| 410 |
buy_thresh = st.sidebar.slider('Stochastic Buy Threshold', min_value=0, max_value=100, value=5)
|
| 411 |
sell_thresh = st.sidebar.slider('Stochastic Sell Threshold', min_value=0, max_value=100, value=95)
|
|
|
|
| 413 |
st.plotly_chart(fig)
|
| 414 |
|
| 415 |
elif selected == "Relative Strength Index (RSI)":
|
| 416 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 417 |
+
st.markdown("""
|
| 418 |
+
### Relative Strength Index (RSI)
|
| 419 |
+
The RSI measures the magnitude of recent price changes to evaluate overbought or oversold conditions.
|
| 420 |
+
**How it Works:**
|
| 421 |
+
1. **Calculate RSI:**
|
| 422 |
+
- Compute the average gains and average losses over a specified period (typically 14 days).
|
| 423 |
+
- Calculate the RSI using the formula:
|
| 424 |
+
""")
|
| 425 |
+
st.latex(r'''
|
| 426 |
+
\text{RSI} = 100 - \frac{100}{1 + \frac{\text{Average Gain}}{\text{Average Loss}}}
|
| 427 |
+
''')
|
| 428 |
+
st.markdown("""
|
| 429 |
+
2. **Identify Signals:**
|
| 430 |
+
- **Buy Signal:** Occurs when the RSI crosses below a set threshold (e.g., 30), indicating the stock may be oversold.
|
| 431 |
+
- **Sell Signal:** Occurs when the RSI crosses above a set threshold (e.g., 70), indicating the stock may be overbought.
|
| 432 |
+
**How to Use:**
|
| 433 |
+
1. Enter the stock ticker, start date, and end date.
|
| 434 |
+
2. Set the buy and sell thresholds.
|
| 435 |
+
3. Click 'Fetch Data' to load the stock data.
|
| 436 |
+
4. The chart will display the RSI and highlight buy/sell signals based on thresholds.
|
| 437 |
+
**Results:**
|
| 438 |
+
The chart shows the stock prices with highlighted buy/sell signals and the RSI line.
|
| 439 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 440 |
|
| 441 |
buy_thresh = st.sidebar.slider('RSI Buy Threshold', min_value=0, max_value=100, value=30)
|
| 442 |
sell_thresh = st.sidebar.slider('RSI Sell Threshold', min_value=0, max_value=100, value=70)
|
|
|
|
| 444 |
st.plotly_chart(fig)
|
| 445 |
|
| 446 |
elif selected == "MACD":
|
| 447 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 448 |
+
st.markdown("""
|
| 449 |
+
### Moving Average Convergence Divergence (MACD)
|
| 450 |
+
The MACD is a trend-following momentum indicator that shows the relationship between two moving averages of a stock's price.
|
| 451 |
+
**How it Works:**
|
| 452 |
+
1. **Calculate MACD:**
|
| 453 |
+
- Compute the MACD line using the formula:
|
| 454 |
+
""")
|
| 455 |
+
st.latex(r'''
|
| 456 |
+
\text{MACD} = \text{EMA}_{12} - \text{EMA}_{26}
|
| 457 |
+
''')
|
| 458 |
+
st.markdown("""
|
| 459 |
+
- Compute the Signal line as the 9-day EMA of the MACD line.
|
| 460 |
+
- The MACD Histogram is the difference between the MACD line and the Signal line.
|
| 461 |
+
2. **Identify Signals:**
|
| 462 |
+
- **Buy Signal:** Occurs when the MACD line crosses above the Signal line, indicating potential upward momentum.
|
| 463 |
+
- **Sell Signal:** Occurs when the MACD line crosses below the Signal line, indicating potential downward momentum.
|
| 464 |
+
**How to Use:**
|
| 465 |
+
1. Enter the stock ticker, start date, and end date.
|
| 466 |
+
2. Click 'Fetch Data' to load the stock data.
|
| 467 |
+
3. The chart will display the MACD line, Signal line, and Histogram, and highlight buy/sell signals based on MACD crossovers.
|
| 468 |
+
**Results:**
|
| 469 |
+
The chart shows the stock prices with highlighted buy/sell signals, MACD line, Signal line, and Histogram.
|
| 470 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
|
| 472 |
fig = plot_macd(close_prices)
|
| 473 |
st.plotly_chart(fig)
|
| 474 |
|
| 475 |
elif selected == "Bollinger Bands":
|
| 476 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 477 |
+
st.markdown("""
|
| 478 |
+
### Bollinger Bands
|
| 479 |
+
Bollinger Bands consist of a middle band (Simple Moving Average) and two outer bands (standard deviations from the SMA). They help identify overbought and oversold conditions.
|
| 480 |
+
**How it Works:**
|
| 481 |
+
1. **Calculate Bollinger Bands:**
|
| 482 |
+
- Compute the middle band as the Simple Moving Average (SMA) of the stock prices over a specified period (typically 20 days).
|
| 483 |
+
- Calculate the upper and lower bands using the formulas:
|
| 484 |
+
""")
|
| 485 |
+
st.latex(r'''
|
| 486 |
+
\text{Upper Band} = \text{SMA} + k \cdot \text{Standard Deviation}
|
| 487 |
+
''')
|
| 488 |
+
st.latex(r'''
|
| 489 |
+
\text{Lower Band} = \text{SMA} - k \cdot \text{Standard Deviation}
|
| 490 |
+
''')
|
| 491 |
+
st.markdown("""
|
| 492 |
+
- Where \( k \) is a factor typically set to 2.
|
| 493 |
+
2. **Identify Signals:**
|
| 494 |
+
- **Buy Signal:** Occurs when the stock price crosses below the lower band, indicating the stock may be oversold.
|
| 495 |
+
- **Sell Signal:** Occurs when the stock price crosses above the upper band, indicating the stock may be overbought.
|
| 496 |
+
**How to Use:**
|
| 497 |
+
1. Enter the stock ticker, start date, and end date.
|
| 498 |
+
2. Click 'Fetch Data' to load the stock data.
|
| 499 |
+
3. The chart will display the Bollinger Bands and highlight buy/sell signals based on price crossing the bands.
|
| 500 |
+
**Results:**
|
| 501 |
+
The chart shows the stock prices with highlighted buy/sell signals and the Bollinger Bands.
|
| 502 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 503 |
|
| 504 |
fig = plot_bollinger_bands(close_prices)
|
| 505 |
st.plotly_chart(fig)
|
| 506 |
|
| 507 |
elif selected == "K Reversal":
|
| 508 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 509 |
+
st.markdown("""
|
| 510 |
+
### K Reversal
|
| 511 |
+
The K Reversal indicator helps identify potential reversal points based on the stock's high and low prices over a specified period.
|
| 512 |
+
**How it Works:**
|
| 513 |
+
1. **Calculate K Reversal:**
|
| 514 |
+
- Compute the highest high and lowest low over a specified period (e.g., 14 days).
|
| 515 |
+
- Calculate the K value using the formula:
|
| 516 |
+
""")
|
| 517 |
+
st.latex(r'''
|
| 518 |
+
K = \frac{\text{Close Price} - \text{Lowest Low}}{\text{Highest High} - \text{Lowest Low}} \times 100
|
| 519 |
+
''')
|
| 520 |
+
st.markdown("""
|
| 521 |
+
2. **Identify Signals:**
|
| 522 |
+
- **Buy Signal:** Occurs when the K value crosses below a set threshold (e.g., 20), indicating the stock may be oversold.
|
| 523 |
+
- **Sell Signal:** Occurs when the K value crosses above a set threshold (e.g., 80), indicating the stock may be overbought.
|
| 524 |
+
**How to Use:**
|
| 525 |
+
1. Enter the stock ticker, start date, and end date.
|
| 526 |
+
2. Set the period for the K Reversal calculation.
|
| 527 |
+
3. Set the buy and sell thresholds.
|
| 528 |
+
4. Click 'Fetch Data' to load the stock data.
|
| 529 |
+
5. The chart will display the K Reversal indicator and highlight buy/sell signals.
|
| 530 |
+
**Results:**
|
| 531 |
+
The chart shows the stock prices with the K Reversal indicator and highlighted buy/sell signals.
|
| 532 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 533 |
|
| 534 |
k_period = st.sidebar.number_input('K Reversal Period', min_value=1, value=14)
|
| 535 |
k_buy_thresh = st.sidebar.slider('K Reversal Buy Threshold', min_value=0.0, max_value=100.0, value=10.0)
|
|
|
|
| 538 |
st.plotly_chart(fig)
|
| 539 |
|
| 540 |
elif selected == "Awesome Oscillator":
|
| 541 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 542 |
+
st.markdown("""
|
| 543 |
+
### Awesome Oscillator
|
| 544 |
+
The Awesome Oscillator measures market momentum by comparing the 34-period and 5-period simple moving averages of the midpoints of each candlestick.
|
| 545 |
+
**How it Works:**
|
| 546 |
+
1. **Calculate the Midpoint:**
|
| 547 |
+
- For each candlestick, compute the midpoint using:
|
| 548 |
+
""")
|
| 549 |
+
st.latex(r'''
|
| 550 |
+
\text{Midpoint} = \frac{\text{High} + \text{Low}}{2}
|
| 551 |
+
''')
|
| 552 |
+
st.markdown("""
|
| 553 |
+
2. **Compute the Moving Averages:**
|
| 554 |
+
- Calculate the 34-period and 5-period simple moving averages (SMA) of the midpoints.
|
| 555 |
+
3. **Calculate the Awesome Oscillator:**
|
| 556 |
+
- Use the formula:
|
| 557 |
+
""")
|
| 558 |
+
st.latex(r'''
|
| 559 |
+
\text{AO} = \text{SMA}_{5}(\text{Midpoint}) - \text{SMA}_{34}(\text{Midpoint})
|
| 560 |
+
''')
|
| 561 |
+
st.markdown("""
|
| 562 |
+
4. **Identify Signals:**
|
| 563 |
+
- **Buy Signal:** Occurs when the AO crosses above the signal line (e.g., 0), indicating potential upward momentum.
|
| 564 |
+
- **Sell Signal:** Occurs when the AO crosses below the signal line, indicating potential downward momentum.
|
| 565 |
+
**How to Use:**
|
| 566 |
+
1. Enter the stock ticker, start date, and end date.
|
| 567 |
+
2. Set the signal line period.
|
| 568 |
+
3. Set the buy and sell thresholds.
|
| 569 |
+
4. Click 'Fetch Data' to load the stock data.
|
| 570 |
+
5. The chart will display the Awesome Oscillator and highlight buy/sell signals based on thresholds.
|
| 571 |
+
**Results:**
|
| 572 |
+
The chart shows the stock prices with the Awesome Oscillator and highlighted buy/sell signals.
|
| 573 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 574 |
|
| 575 |
signal_period = st.sidebar.number_input('Signal Line Period', min_value=1, value=9)
|
| 576 |
ao_buy_thresh = st.sidebar.slider('AO Buy Threshold', min_value=-100.0, max_value=100.0, value=0.0)
|
|
|
|
| 579 |
st.plotly_chart(fig)
|
| 580 |
|
| 581 |
elif selected == "Williams %R":
|
| 582 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 583 |
+
st.markdown("""
|
| 584 |
+
### Williams %R
|
| 585 |
+
The Williams %R measures overbought and oversold levels.
|
| 586 |
+
**How it Works:**
|
| 587 |
+
1. **Calculate Williams %R:**
|
| 588 |
+
- Compute the highest high and lowest low over a specified look-back period (e.g., 14 days).
|
| 589 |
+
- Calculate the Williams %R using the formula:
|
| 590 |
+
""")
|
| 591 |
+
st.latex(r'''
|
| 592 |
+
\text{Williams \%R} = \frac{\text{Highest High} - \text{Close}}{\text{Highest High} - \text{Lowest Low}} \times -100
|
| 593 |
+
''')
|
| 594 |
+
st.markdown("""
|
| 595 |
+
2. **Identify Signals:**
|
| 596 |
+
- **Buy Signal:** Occurs when the Williams %R crosses below a set threshold (e.g., -80), indicating the stock may be oversold.
|
| 597 |
+
- **Sell Signal:** Occurs when the Williams %R crosses above a set threshold (e.g., -20), indicating the stock may be overbought.
|
| 598 |
+
**How to Use:**
|
| 599 |
+
1. Enter the stock ticker, start date, and end date.
|
| 600 |
+
2. Set the look-back period.
|
| 601 |
+
3. Set the buy and sell thresholds.
|
| 602 |
+
4. Click 'Fetch Data' to load the stock data.
|
| 603 |
+
5. The chart will display the Williams %R and highlight buy/sell signals based on thresholds.
|
| 604 |
+
**Results:**
|
| 605 |
+
The chart shows the stock prices with the Williams %R and highlighted buy/sell signals.
|
| 606 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 607 |
|
| 608 |
williams_r_period = st.sidebar.number_input('Look-back Period', min_value=1, value=14)
|
| 609 |
williams_r_buy_thresh = st.sidebar.slider('Williams %R Buy Threshold', min_value=-100.0, max_value=0.0, value=-90.0)
|
|
|
|
| 612 |
st.plotly_chart(fig)
|
| 613 |
|
| 614 |
elif selected == "Aroon Oscillator":
|
| 615 |
+
with st.expander("Formula and Method Description", expanded=False):
|
| 616 |
+
st.markdown("""
|
| 617 |
+
### Aroon Oscillator
|
| 618 |
+
The Aroon Oscillator measures the strength of a trend in the stock's price.
|
| 619 |
+
**How it Works:**
|
| 620 |
+
1. **Calculate Aroon Up and Aroon Down:**
|
| 621 |
+
- Compute the Aroon Up, which measures the time since the highest high during the look-back period:
|
| 622 |
+
""")
|
| 623 |
+
st.latex(r'''
|
| 624 |
+
\text{Aroon Up} = \frac{N - \text{Days Since Highest High}}{N} \times 100
|
| 625 |
+
''')
|
| 626 |
+
st.markdown("""
|
| 627 |
+
- Compute the Aroon Down, which measures the time since the lowest low during the look-back period:
|
| 628 |
+
""")
|
| 629 |
+
st.latex(r'''
|
| 630 |
+
\text{Aroon Down} = \frac{N - \text{Days Since Lowest Low}}{N} \times 100
|
| 631 |
+
''')
|
| 632 |
+
st.markdown("""
|
| 633 |
+
2. **Calculate the Aroon Oscillator:**
|
| 634 |
+
- Use the formula:
|
| 635 |
+
""")
|
| 636 |
+
st.latex(r'''
|
| 637 |
+
\text{Aroon Oscillator} = \text{Aroon Up} - \text{Aroon Down}
|
| 638 |
+
''')
|
| 639 |
+
st.markdown("""
|
| 640 |
+
3. **Identify Signals:**
|
| 641 |
+
- **Buy Signal:** Occurs when the Aroon Oscillator crosses above zero, indicating a potential upward trend.
|
| 642 |
+
- **Sell Signal:** Occurs when the Aroon Oscillator crosses below zero, indicating a potential downward trend.
|
| 643 |
+
**How to Use:**
|
| 644 |
+
1. Enter the stock ticker, start date, and end date.
|
| 645 |
+
2. Set the look-back period.
|
| 646 |
+
3. Click 'Fetch Data' to load the stock data.
|
| 647 |
+
4. The chart will display the Aroon Oscillator and highlight buy/sell signals based on thresholds.
|
| 648 |
+
**Results:**
|
| 649 |
+
The chart shows the stock prices with the Aroon Oscillator and highlighted buy/sell signals.
|
| 650 |
+
""")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 651 |
|
| 652 |
aroon_period = st.sidebar.number_input('Look-back Period', min_value=1, value=25)
|
| 653 |
aroon_osc = aroon_oscillator(data, aroon_period)
|
|
|
|
| 662 |
footer {visibility: hidden;}
|
| 663 |
</style>
|
| 664 |
"""
|
| 665 |
+
st.markdown(hide_streamlit_style, unsafe_allow_html=True)
|