Johan713 commited on
Commit
3318a9f
·
verified ·
1 Parent(s): cbb764c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +209 -106
app.py CHANGED
@@ -516,6 +516,20 @@ def predict_stock_prices():
516
  else:
517
  st.error("Failed to fetch stock data. Please try again.")
518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  def explore_data():
520
  st.header("Explore Stock Data")
521
 
@@ -531,104 +545,203 @@ def explore_data():
531
 
532
  if st.button("Explore Data"):
533
  with st.spinner("Fetching and analyzing data..."):
534
- data = yf.download(ticker, period=period)
 
535
 
536
- if data is not None and not data.empty:
537
- st.subheader(f"{company_name} Stock Data")
538
-
539
- # Create tabs for different visualizations
540
- tab1, tab2, tab3, tab4, tab5 = st.tabs(["Price History", "OHLC", "Technical Indicators", "Volume & Turnover", "Statistics"])
541
-
542
- with tab1:
543
- # Stock Price History
544
- fig = go.Figure()
545
- fig.add_trace(go.Scatter(x=data.index, y=data['Open'], mode='lines', name='Open'))
546
- fig.add_trace(go.Scatter(x=data.index, y=data['High'], mode='lines', name='High'))
547
- fig.add_trace(go.Scatter(x=data.index, y=data['Low'], mode='lines', name='Low'))
548
- fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
549
 
550
- # Add rolling mean and standard deviation
551
- data['Rolling_Mean'] = data['Close'].rolling(window=20).mean()
552
- data['Rolling_Std'] = data['Close'].rolling(window=20).std()
553
- fig.add_trace(go.Scatter(x=data.index, y=data['Rolling_Mean'], mode='lines', name='20-day Rolling Mean', line=dict(dash='dash')))
554
- fig.add_trace(go.Scatter(x=data.index, y=data['Rolling_Std'], mode='lines', name='20-day Rolling Std', line=dict(dash='dot')))
555
 
556
- fig.update_layout(title=f"{company_name} Stock Price History",
557
- xaxis_title="Date",
558
- yaxis_title="Price",
559
- hovermode="x unified",
560
- template="plotly_dark")
561
- st.plotly_chart(fig, use_container_width=True)
562
-
563
- with tab2:
564
- # OHLC Chart
565
- ohlc_fig = go.Figure(data=[go.Candlestick(x=data.index,
566
- open=data['Open'],
567
- high=data['High'],
568
- low=data['Low'],
569
- close=data['Close'])])
570
- ohlc_fig.update_layout(title=f"{company_name} OHLC Chart",
571
- xaxis_title="Date",
572
- yaxis_title="Price",
573
- template="plotly_dark",
574
- xaxis_rangeslider_visible=False)
575
- st.plotly_chart(ohlc_fig, use_container_width=True)
576
-
577
- with tab3:
578
- # Technical Indicators
579
- data['SMA_20'] = SMAIndicator(close=data['Close'], window=20).sma_indicator()
580
- data['EMA_20'] = EMAIndicator(close=data['Close'], window=20).ema_indicator()
581
- bb = BollingerBands(close=data['Close'], window=20, window_dev=2)
582
- data['BB_High'] = bb.bollinger_hband()
583
- data['BB_Low'] = bb.bollinger_lband()
584
- data['RSI'] = RSIIndicator(close=data['Close']).rsi()
585
-
586
- fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
587
- vertical_spacing=0.03,
588
- subplot_titles=("Price and Indicators", "RSI"),
589
- row_heights=[0.7, 0.3])
590
-
591
- fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'), row=1, col=1)
592
- fig.add_trace(go.Scatter(x=data.index, y=data['SMA_20'], mode='lines', name='SMA 20'), row=1, col=1)
593
- fig.add_trace(go.Scatter(x=data.index, y=data['EMA_20'], mode='lines', name='EMA 20'), row=1, col=1)
594
- fig.add_trace(go.Scatter(x=data.index, y=data['BB_High'], mode='lines', name='BB High'), row=1, col=1)
595
- fig.add_trace(go.Scatter(x=data.index, y=data['BB_Low'], mode='lines', name='BB Low'), row=1, col=1)
596
-
597
- fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], mode='lines', name='RSI'), row=2, col=1)
598
- fig.add_hline(y=70, line_dash="dash", line_color="red", row=2, col=1)
599
- fig.add_hline(y=30, line_dash="dash", line_color="green", row=2, col=1)
600
-
601
- fig.update_layout(height=800, title_text=f"{company_name} Technical Indicators",
602
- hovermode="x unified", template="plotly_dark")
603
- fig.update_xaxes(rangeslider_visible=False, row=2, col=1)
604
- fig.update_yaxes(title_text="Price", row=1, col=1)
605
- fig.update_yaxes(title_text="RSI", row=2, col=1)
606
-
607
- st.plotly_chart(fig, use_container_width=True)
608
-
609
- with tab4:
610
- # Volume and Turnover
611
- fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
612
- vertical_spacing=0.03,
613
- subplot_titles=("Volume", "Turnover (if available)"),
614
- row_heights=[0.5, 0.5])
615
-
616
- fig.add_trace(go.Bar(x=data.index, y=data['Volume'], name='Volume'), row=1, col=1)
617
-
618
- if 'Turnover' in data.columns:
619
- fig.add_trace(go.Bar(x=data.index, y=data['Turnover'], name='Turnover'), row=2, col=1)
620
- else:
621
- fig.add_annotation(text="Turnover data not available", xref="paper", yref="paper", x=0.5, y=0.25, showarrow=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
622
 
623
- fig.update_layout(height=600, title_text=f"{company_name} Volume and Turnover",
624
- hovermode="x unified", template="plotly_dark")
625
- fig.update_xaxes(rangeslider_visible=False, row=2, col=1)
626
- fig.update_yaxes(title_text="Volume", row=1, col=1)
627
- fig.update_yaxes(title_text="Turnover", row=2, col=1)
628
 
629
- st.plotly_chart(fig, use_container_width=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
 
631
- with tab5:
632
  # Display key statistics
633
  st.subheader("Key Statistics")
634
  col1, col2, col3 = st.columns(3)
@@ -643,20 +756,10 @@ def explore_data():
643
  st.metric("Avg Daily Return", f"{returns.mean():.2f}%")
644
  st.metric("Return Volatility", f"{returns.std():.2f}%")
645
 
646
- # Correlation Heatmap
647
- correlation = data[['Open', 'High', 'Low', 'Close', 'Volume']].corr()
648
- heatmap_fig = px.imshow(correlation, text_auto=True, aspect="auto", color_continuous_scale='Viridis')
649
- heatmap_fig.update_layout(title="Correlation Heatmap", template="plotly_dark")
650
- st.plotly_chart(heatmap_fig, use_container_width=True)
651
-
652
- # Display news
653
- st.subheader("Latest News")
654
- news = fetch_news(company_name)
655
- for item in news:
656
- st.markdown(f"[{item['title']}]({item['link']}) ({item['pubDate']})")
657
-
658
- else:
659
- st.error("Failed to fetch data. Please try again.")
660
 
661
  if __name__ == "__main__":
662
  main()
 
516
  else:
517
  st.error("Failed to fetch stock data. Please try again.")
518
 
519
+ def calculate_bollinger_bands(data, window=20, num_std=2):
520
+ rolling_mean = data.rolling(window=window).mean()
521
+ rolling_std = data.rolling(window=window).std()
522
+ upper_band = rolling_mean + (rolling_std * num_std)
523
+ lower_band = rolling_mean - (rolling_std * num_std)
524
+ return upper_band, lower_band
525
+
526
+ def calculate_rsi(data, window=14):
527
+ delta = data.diff()
528
+ gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
529
+ loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
530
+ rs = gain / loss
531
+ return 100 - (100 / (1 + rs))
532
+
533
  def explore_data():
534
  st.header("Explore Stock Data")
535
 
 
545
 
546
  if st.button("Explore Data"):
547
  with st.spinner("Fetching and analyzing data..."):
548
+ try:
549
+ data = yf.download(ticker, period=period)
550
 
551
+ if data is not None and not data.empty:
552
+ st.subheader(f"{company_name} Stock Data")
 
 
 
 
 
 
 
 
 
 
 
553
 
554
+ # Create tabs for different visualizations
555
+ tab1, tab2, tab3, tab4, tab5, tab6 = st.tabs([
556
+ "Price History", "OHLC", "Technical Indicators",
557
+ "Volume Analysis", "Returns Distribution", "Moving Averages"
558
+ ])
559
 
560
+ with tab1:
561
+ st.markdown("""
562
+ ### Price History
563
+ This chart shows the historical closing prices of the stock over time.
564
+
565
+ **How to use**:
566
+ - Use the slider at the bottom to zoom in on specific time periods.
567
+ - Hover over the line to see exact prices at different dates.
568
+
569
+ **How it helps**:
570
+ - Identify long-term trends in the stock's price.
571
+ - Spot key price levels and potential support/resistance areas.
572
+ - Understand the overall price movement and volatility of the stock.
573
+ """)
574
+
575
+ fig = go.Figure()
576
+ fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
577
+
578
+ fig.update_layout(title=f"{company_name} Stock Price History",
579
+ xaxis_title="Date",
580
+ yaxis_title="Price",
581
+ hovermode="x unified",
582
+ template="plotly_dark")
583
+ st.plotly_chart(fig, use_container_width=True)
584
+
585
+ with tab2:
586
+ st.markdown("""
587
+ ### OHLC (Open-High-Low-Close) Chart
588
+ This candlestick chart shows the opening, high, low, and closing prices for each trading day.
589
+
590
+ **How to use**:
591
+ - Green candles indicate days where the closing price was higher than the opening price.
592
+ - Red candles indicate days where the closing price was lower than the opening price.
593
+ - The thin lines (wicks) show the high and low prices for the day.
594
+
595
+ **How it helps**:
596
+ - Identify daily price movements and volatility.
597
+ - Spot potential reversal patterns or trends.
598
+ - Understand the intraday price action of the stock.
599
+ """)
600
+
601
+ ohlc_fig = go.Figure(data=[go.Candlestick(x=data.index,
602
+ open=data['Open'],
603
+ high=data['High'],
604
+ low=data['Low'],
605
+ close=data['Close'])])
606
+ ohlc_fig.update_layout(title=f"{company_name} OHLC Chart",
607
+ xaxis_title="Date",
608
+ yaxis_title="Price",
609
+ template="plotly_dark",
610
+ xaxis_rangeslider_visible=False)
611
+ st.plotly_chart(ohlc_fig, use_container_width=True)
612
+
613
+ with tab3:
614
+ st.markdown("""
615
+ ### Technical Indicators
616
+ This chart displays various technical indicators alongside the stock price.
617
+
618
+ **How to use**:
619
+ - The top chart shows the stock price with SMA (Simple Moving Average), EMA (Exponential Moving Average), and Bollinger Bands.
620
+ - The bottom chart shows the RSI (Relative Strength Index).
621
+
622
+ **How it helps**:
623
+ - Identify potential buy/sell signals using moving average crossovers.
624
+ - Spot overbought or oversold conditions using RSI.
625
+ - Understand price volatility using Bollinger Bands.
626
+ - Combine multiple indicators for more robust trading decisions.
627
+ """)
628
+
629
+ data['SMA_20'] = data['Close'].rolling(window=20).mean()
630
+ data['EMA_20'] = data['Close'].ewm(span=20, adjust=False).mean()
631
+ data['Upper_BB'], data['Lower_BB'] = calculate_bollinger_bands(data['Close'])
632
+ data['RSI'] = calculate_rsi(data['Close'])
633
+
634
+ fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
635
+ vertical_spacing=0.03,
636
+ subplot_titles=("Price and Indicators", "RSI"),
637
+ row_heights=[0.7, 0.3])
638
+
639
+ fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'), row=1, col=1)
640
+ fig.add_trace(go.Scatter(x=data.index, y=data['SMA_20'], mode='lines', name='SMA 20'), row=1, col=1)
641
+ fig.add_trace(go.Scatter(x=data.index, y=data['EMA_20'], mode='lines', name='EMA 20'), row=1, col=1)
642
+ fig.add_trace(go.Scatter(x=data.index, y=data['Upper_BB'], mode='lines', name='Upper BB'), row=1, col=1)
643
+ fig.add_trace(go.Scatter(x=data.index, y=data['Lower_BB'], mode='lines', name='Lower BB'), row=1, col=1)
644
+
645
+ fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], mode='lines', name='RSI'), row=2, col=1)
646
+ fig.add_hline(y=70, line_dash="dash", line_color="red", row=2, col=1)
647
+ fig.add_hline(y=30, line_dash="dash", line_color="green", row=2, col=1)
648
+
649
+ fig.update_layout(height=800, title_text=f"{company_name} Technical Indicators",
650
+ hovermode="x unified", template="plotly_dark")
651
+ fig.update_xaxes(rangeslider_visible=False, row=2, col=1)
652
+ fig.update_yaxes(title_text="Price", row=1, col=1)
653
+ fig.update_yaxes(title_text="RSI", row=2, col=1)
654
+
655
+ st.plotly_chart(fig, use_container_width=True)
656
+
657
+ with tab4:
658
+ st.markdown("""
659
+ ### Volume Analysis
660
+ This chart shows the trading volume alongside the stock price.
661
+
662
+ **How to use**:
663
+ - The top chart displays the daily trading volume.
664
+ - The bottom chart shows the corresponding stock price.
665
+
666
+ **How it helps**:
667
+ - Identify periods of high and low trading activity.
668
+ - Confirm price trends (higher volume often validates price movements).
669
+ - Spot potential reversals (e.g., high volume at price extremes).
670
+ - Understand the liquidity of the stock.
671
+ """)
672
+
673
+ fig = make_subplots(rows=2, cols=1, shared_xaxes=True,
674
+ vertical_spacing=0.03,
675
+ subplot_titles=("Volume", "Price"),
676
+ row_heights=[0.7, 0.3])
677
 
678
+ fig.add_trace(go.Bar(x=data.index, y=data['Volume'], name='Volume'), row=1, col=1)
679
+ fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close Price'), row=2, col=1)
 
 
 
680
 
681
+ fig.update_layout(height=600, title_text=f"{company_name} Volume Analysis",
682
+ hovermode="x unified", template="plotly_dark")
683
+ fig.update_xaxes(rangeslider_visible=False, row=2, col=1)
684
+ fig.update_yaxes(title_text="Volume", row=1, col=1)
685
+ fig.update_yaxes(title_text="Price", row=2, col=1)
686
+
687
+ st.plotly_chart(fig, use_container_width=True)
688
+
689
+ with tab5:
690
+ st.markdown("""
691
+ ### Returns Distribution
692
+ This histogram shows the distribution of daily returns for the stock.
693
+
694
+ **How to use**:
695
+ - The x-axis represents the daily return percentages.
696
+ - The y-axis shows the frequency of each return range.
697
+
698
+ **How it helps**:
699
+ - Understand the volatility and risk profile of the stock.
700
+ - Identify the most common daily return ranges.
701
+ - Spot any skewness or unusual patterns in returns.
702
+ - Compare the stock's return distribution to a normal distribution for risk assessment.
703
+ """)
704
+
705
+ returns = data['Close'].pct_change().dropna()
706
+ fig = go.Figure(data=[go.Histogram(x=returns, nbinsx=50)])
707
+ fig.update_layout(title=f"{company_name} Returns Distribution",
708
+ xaxis_title="Daily Returns",
709
+ yaxis_title="Frequency",
710
+ template="plotly_dark")
711
+ st.plotly_chart(fig, use_container_width=True)
712
+
713
+ with tab6:
714
+ st.markdown("""
715
+ ### Moving Averages
716
+ This chart shows the stock price along with 50-day and 200-day Simple Moving Averages (SMA).
717
+
718
+ **How to use**:
719
+ - The blue line represents the stock's closing price.
720
+ - The orange line is the 50-day SMA.
721
+ - The green line is the 200-day SMA.
722
+
723
+ **How it helps**:
724
+ - Identify long-term trends in the stock price.
725
+ - Spot potential buy/sell signals when the price crosses above/below the moving averages.
726
+ - Recognize "Golden Cross" (50-day crosses above 200-day) and "Death Cross" (50-day crosses below 200-day) signals.
727
+ - Understand the overall momentum of the stock.
728
+ """)
729
+
730
+ data['SMA_50'] = data['Close'].rolling(window=50).mean()
731
+ data['SMA_200'] = data['Close'].rolling(window=200).mean()
732
+
733
+ fig = go.Figure()
734
+ fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines', name='Close'))
735
+ fig.add_trace(go.Scatter(x=data.index, y=data['SMA_50'], mode='lines', name='50-day SMA'))
736
+ fig.add_trace(go.Scatter(x=data.index, y=data['SMA_200'], mode='lines', name='200-day SMA'))
737
+
738
+ fig.update_layout(title=f"{company_name} Moving Averages",
739
+ xaxis_title="Date",
740
+ yaxis_title="Price",
741
+ template="plotly_dark",
742
+ hovermode="x unified")
743
+ st.plotly_chart(fig, use_container_width=True)
744
 
 
745
  # Display key statistics
746
  st.subheader("Key Statistics")
747
  col1, col2, col3 = st.columns(3)
 
756
  st.metric("Avg Daily Return", f"{returns.mean():.2f}%")
757
  st.metric("Return Volatility", f"{returns.std():.2f}%")
758
 
759
+ else:
760
+ st.error("Failed to fetch data. Please try again.")
761
+ except Exception as e:
762
+ st.error(f"An error occurred: {str(e)}. Please try a different time period or check your internet connection.")
 
 
 
 
 
 
 
 
 
 
763
 
764
  if __name__ == "__main__":
765
  main()