QuantumLearner commited on
Commit
b03b4db
·
verified ·
1 Parent(s): 265cecc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +291 -322
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
- selected = st.sidebar.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"])
 
292
 
293
  # Sidebar for input parameters
294
- st.sidebar.header("Input Parameters")
295
- ticker = st.sidebar.text_input('Enter Stock Ticker', 'ASML.AS')
296
- start_date = st.sidebar.date_input('Start Date', pd.to_datetime('2019-01-01'))
297
- end_date = st.sidebar.date_input('End Date', pd.to_datetime('2024-12-31'))
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
- # Display results based on the selected method
307
- if selected == "Rolling Z-Score":
308
  st.markdown("""
309
- ### Rolling Z-Score
310
-
311
- The rolling z-score method identifies overbought and oversold conditions by standardizing stock prices over different periods.
312
-
313
- **How it Works:**
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.markdown("""
348
- ### Rate of Change (ROC)
349
-
350
- 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.
351
-
352
- **How it Works:**
353
-
354
- 1. **Calculate ROC:**
355
- - For each day, calculate the ROC using the formula:
356
- """)
357
- st.latex(r'''
358
- \text{ROC} = \frac{\text{Current Price} - \text{Price} \, n \, \text{days ago}}{\text{Price} \, n \, \text{days ago}} \times 100
359
- ''')
360
- st.markdown("""
361
- 2. **Identify Signals:**
362
- - **Buy Signal:** Occurs when the ROC crosses above zero, indicating potential upward momentum.
363
- - **Sell Signal:** Occurs when the ROC crosses below zero, indicating potential downward momentum.
364
-
365
- **How to Use:**
366
- 1. Enter the stock ticker, start date, and end date.
367
- 2. Set the number of days for the ROC calculation.
368
- 3. Click 'Fetch Data' to load the stock data.
369
- 4. The chart will display the ROC and highlight buy/sell signals based on the ROC crossing zero.
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.markdown("""
381
- ### Stochastic Oscillator
382
-
383
- The Stochastic Oscillator compares a stock's closing price to its price range over a specified period. It helps identify overbought and oversold conditions.
384
-
385
- **How it Works:**
386
-
387
- 1. **Calculate %K and %D:**
388
- - The %K line is calculated as follows:
389
- """)
390
- st.latex(r'''
391
- \%K = \frac{\text{Current Close} - \text{Lowest Low}}{\text{Highest High} - \text{Lowest Low}} \times 100
392
- ''')
393
- st.markdown("""
394
- - The %D line is the 3-period moving average of %K.
395
-
396
- 2. **Identify Signals:**
397
- - **Buy Signal:** Occurs when %K crosses above a set threshold (e.g., 20), indicating potential upward momentum.
398
- - **Sell Signal:** Occurs when %K crosses below a set threshold (e.g., 80), indicating potential downward momentum.
399
-
400
- **How to Use:**
401
- 1. Enter the stock ticker, start date, and end date.
402
- 2. Set the buy and sell thresholds.
403
- 3. Click 'Fetch Data' to load the stock data.
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.markdown("""
417
- ### Relative Strength Index (RSI)
418
-
419
- The RSI measures the magnitude of recent price changes to evaluate overbought or oversold conditions.
420
-
421
- **How it Works:**
422
-
423
- 1. **Calculate RSI:**
424
- - Compute the average gains and average losses over a specified period (typically 14 days).
425
- - Calculate the RSI using the formula:
426
- """)
427
- st.latex(r'''
428
- \text{RSI} = 100 - \frac{100}{1 + \frac{\text{Average Gain}}{\text{Average Loss}}}
429
- ''')
430
- st.markdown("""
431
- 2. **Identify Signals:**
432
- - **Buy Signal:** Occurs when the RSI crosses below a set threshold (e.g., 30), indicating the stock may be oversold.
433
- - **Sell Signal:** Occurs when the RSI crosses above a set threshold (e.g., 70), indicating the stock may be overbought.
434
-
435
- **How to Use:**
436
- 1. Enter the stock ticker, start date, and end date.
437
- 2. Set the buy and sell thresholds.
438
- 3. Click 'Fetch Data' to load the stock data.
439
- 4. The chart will display the RSI and highlight buy/sell signals based on thresholds.
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.markdown("""
452
- ### Moving Average Convergence Divergence (MACD)
453
-
454
- The MACD is a trend-following momentum indicator that shows the relationship between two moving averages of a stock's price.
455
-
456
- **How it Works:**
457
-
458
- 1. **Calculate MACD:**
459
- - Compute the MACD line using the formula:
460
- """)
461
- st.latex(r'''
462
- \text{MACD} = \text{EMA}_{12} - \text{EMA}_{26}
463
- ''')
464
- st.markdown("""
465
- - Compute the Signal line as the 9-day EMA of the MACD line.
466
- - The MACD Histogram is the difference between the MACD line and the Signal line.
467
-
468
- 2. **Identify Signals:**
469
- - **Buy Signal:** Occurs when the MACD line crosses above the Signal line, indicating potential upward momentum.
470
- - **Sell Signal:** Occurs when the MACD line crosses below the Signal line, indicating potential downward momentum.
471
-
472
- **How to Use:**
473
- 1. Enter the stock ticker, start date, and end date.
474
- 2. Click 'Fetch Data' to load the stock data.
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.markdown("""
486
- ### Bollinger Bands
487
-
488
- 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.
489
-
490
- **How it Works:**
491
-
492
- 1. **Calculate Bollinger Bands:**
493
- - Compute the middle band as the Simple Moving Average (SMA) of the stock prices over a specified period (typically 20 days).
494
- - Calculate the upper and lower bands using the formulas:
495
- """)
496
- st.latex(r'''
497
- \text{Upper Band} = \text{SMA} + k \cdot \text{Standard Deviation}
498
- ''')
499
- st.latex(r'''
500
- \text{Lower Band} = \text{SMA} - k \cdot \text{Standard Deviation}
501
- ''')
502
- st.markdown("""
503
- - Where \( k \) is a factor typically set to 2.
504
-
505
- 2. **Identify Signals:**
506
- - **Buy Signal:** Occurs when the stock price crosses below the lower band, indicating the stock may be oversold.
507
- - **Sell Signal:** Occurs when the stock price crosses above the upper band, indicating the stock may be overbought.
508
-
509
- **How to Use:**
510
- 1. Enter the stock ticker, start date, and end date.
511
- 2. Click 'Fetch Data' to load the stock data.
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.markdown("""
523
- ### K Reversal
524
-
525
- The K Reversal indicator helps identify potential reversal points based on the stock's high and low prices over a specified period.
526
-
527
- **How it Works:**
528
-
529
- 1. **Calculate K Reversal:**
530
- - Compute the highest high and lowest low over a specified period (e.g., 14 days).
531
- - Calculate the K value using the formula:
532
- """)
533
- st.latex(r'''
534
- K = \frac{\text{Close Price} - \text{Lowest Low}}{\text{Highest High} - \text{Lowest Low}} \times 100
535
- ''')
536
- st.markdown("""
537
- 2. **Identify Signals:**
538
- - **Buy Signal:** Occurs when the K value crosses below a set threshold (e.g., 20), indicating the stock may be oversold.
539
- - **Sell Signal:** Occurs when the K value crosses above a set threshold (e.g., 80), indicating the stock may be overbought.
540
-
541
- **How to Use:**
542
- 1. Enter the stock ticker, start date, and end date.
543
- 2. Set the period for the K Reversal calculation.
544
- 3. Set the buy and sell thresholds.
545
- 4. Click 'Fetch Data' to load the stock data.
546
- 5. The chart will display the K Reversal indicator and highlight buy/sell signals.
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.markdown("""
560
- ### Awesome Oscillator
561
-
562
- The Awesome Oscillator measures market momentum by comparing the 34-period and 5-period simple moving averages of the midpoints of each candlestick.
563
-
564
- **How it Works:**
565
-
566
- 1. **Calculate the Midpoint:**
567
- - For each candlestick, compute the midpoint using:
568
- """)
569
- st.latex(r'''
570
- \text{Midpoint} = \frac{\text{High} + \text{Low}}{2}
571
- ''')
572
- st.markdown("""
573
- 2. **Compute the Moving Averages:**
574
- - Calculate the 34-period and 5-period simple moving averages (SMA) of the midpoints.
575
-
576
- 3. **Calculate the Awesome Oscillator:**
577
- - Use the formula:
578
- """)
579
- st.latex(r'''
580
- \text{AO} = \text{SMA}_{5}(\text{Midpoint}) - \text{SMA}_{34}(\text{Midpoint})
581
- ''')
582
- st.markdown("""
583
- 4. **Identify Signals:**
584
- - **Buy Signal:** Occurs when the AO crosses above the signal line (e.g., 0), indicating potential upward momentum.
585
- - **Sell Signal:** Occurs when the AO crosses below the signal line, indicating potential downward momentum.
586
-
587
- **How to Use:**
588
- 1. Enter the stock ticker, start date, and end date.
589
- 2. Set the signal line period.
590
- 3. Set the buy and sell thresholds.
591
- 4. Click 'Fetch Data' to load the stock data.
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.markdown("""
606
- ### Williams %R
607
-
608
- The Williams %R measures overbought and oversold levels.
609
-
610
- **How it Works:**
611
-
612
- 1. **Calculate Williams %R:**
613
- - Compute the highest high and lowest low over a specified look-back period (e.g., 14 days).
614
- - Calculate the Williams %R using the formula:
615
- """)
616
- st.latex(r'''
617
- \text{Williams \%R} = \frac{\text{Highest High} - \text{Close}}{\text{Highest High} - \text{Lowest Low}} \times -100
618
- ''')
619
- st.markdown("""
620
- 2. **Identify Signals:**
621
- - **Buy Signal:** Occurs when the Williams %R crosses below a set threshold (e.g., -80), indicating the stock may be oversold.
622
- - **Sell Signal:** Occurs when the Williams %R crosses above a set threshold (e.g., -20), indicating the stock may be overbought.
623
-
624
- **How to Use:**
625
- 1. Enter the stock ticker, start date, and end date.
626
- 2. Set the look-back period.
627
- 3. Set the buy and sell thresholds.
628
- 4. Click 'Fetch Data' to load the stock data.
629
- 5. The chart will display the Williams %R and highlight buy/sell signals based on thresholds.
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.markdown("""
643
- ### Aroon Oscillator
644
-
645
- The Aroon Oscillator measures the strength of a trend in the stock's price.
646
-
647
- **How it Works:**
648
-
649
- 1. **Calculate Aroon Up and Aroon Down:**
650
- - Compute the Aroon Up, which measures the time since the highest high during the look-back period:
651
- """)
652
- st.latex(r'''
653
- \text{Aroon Up} = \frac{N - \text{Days Since Highest High}}{N} \times 100
654
- ''')
655
- st.markdown("""
656
- - Compute the Aroon Down, which measures the time since the lowest low during the look-back period:
657
- """)
658
- st.latex(r'''
659
- \text{Aroon Down} = \frac{N - \text{Days Since Lowest Low}}{N} \times 100
660
- ''')
661
- st.markdown("""
662
- 2. **Calculate the Aroon Oscillator:**
663
- - Use the formula:
664
- """)
665
- st.latex(r'''
666
- \text{Aroon Oscillator} = \text{Aroon Up} - \text{Aroon Down}
667
- ''')
668
- st.markdown("""
669
- 3. **Identify Signals:**
670
- - **Buy Signal:** Occurs when the Aroon Oscillator crosses above zero, indicating a potential upward trend.
671
- - **Sell Signal:** Occurs when the Aroon Oscillator crosses below zero, indicating a potential downward trend.
672
-
673
- **How to Use:**
674
- 1. Enter the stock ticker, start date, and end date.
675
- 2. Set the look-back period.
676
- 3. Click 'Fetch Data' to load the stock data.
677
- 4. The chart will display the Aroon Oscillator and highlight buy/sell signals based on thresholds.
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)