import streamlit as st import pandas as pd import yfinance as yf import numpy as np import datetime def fetch_stock_data(symbol, start_date, end_date, interval): try: valid_intervals = { "1m": 8, # 1-minute data is available for up to 8 days "2m": 60, # 2-minute data is available for up to 60 days "5m": 60, # 5-minute data is available for up to 60 days "15m": 60, # 15-minute data is available for up to 60 days "30m": 60, # 30-minute data is available for up to 60 days "60m": 730, # 60-minute data is available for up to 730 days (2 years) "90m": 730, # 90-minute data is available for up to 730 days (2 years) "1h": 730, # 1-hour data is available for up to 730 days (2 years) "1d": 10000, # Daily data is available for up to maximum available "5d": 10000, # 5-day data is available for up to maximum available "1wk": 10000,# Weekly data is available for up to maximum available "1mo": 10000,# Monthly data is available for up to maximum available "3mo": 10000 # Quarterly data is available for up to maximum available } if interval not in valid_intervals: st.error(f"Invalid interval: {interval}. Please choose from {list(valid_intervals.keys())}") return max_days = valid_intervals[interval] start_date_pd = pd.to_datetime(start_date) end_date_pd = pd.to_datetime(end_date) max_start_date = end_date_pd - pd.to_timedelta(max_days, unit='d') if start_date_pd < max_start_date: st.warning(f"The selected start date exceeds the maximum allowed range for {interval} interval. Adjusting start date to {max_start_date.strftime('%Y-%m-%d')}") start_date_pd = max_start_date ticker = yf.Ticker(symbol) data = ticker.history(start=start_date_pd.strftime('%Y-%m-%d'), end=end_date_pd.strftime('%Y-%m-%d'), interval=interval) if not data.empty: data.reset_index(inplace=True) data.rename(columns={'index': 'Datetime'}, inplace=True) # Calculate On-Balance Volume (OBV) data['OBV'] = (np.sign(data['Close'].diff()) * data['Volume']).fillna(0).cumsum() # Calculate Relative Strength Index (RSI) delta = data['Close'].diff() gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() rs = gain / loss data['RSI'] = 100 - (100 / (1 + rs)) # Calculate Exponential Moving Average (EMA) data['EMA'] = data['Close'].ewm(span=20, adjust=False).mean() # Calculate Simple Moving Average (SMA) data['SMA'] = data['Close'].rolling(window=20).mean() st.write(f"Data for {symbol} fetched successfully with OBV, RSI, EMA, and SMA included.") st.write(data) else: st.error(f"No data available for {symbol}. Please check the symbol or try a different date range.") except Exception as e: st.error(f"Error fetching data for {symbol}: {e}") # Stock List stock_list = [ "RELIANCE.NS", "TCS.NS", "INFY.NS", "HDFCBANK.NS", "ICICIBANK.NS", "KOTAKBANK.NS", "SBIN.NS", "LT.NS", "HINDUNILVR.NS", "BHARTIARTL.NS" ] # Streamlit app layout st.title("Share Market Data") symbol = st.selectbox("Select Stock Symbol", options=stock_list) interval = st.selectbox("Select Data Interval", options=["1m", "2m", "5m", "15m", "30m", "60m", "90m", "1h", "1d", "5d", "1wk", "1mo", "3mo"]) # Allow user to select a start date start_date = st.date_input("Select Start Date", pd.to_datetime('2023-01-01')) end_date = pd.to_datetime('today').strftime('%Y-%m-%d') valid_intervals = { "1m": 8, # 1-minute data is available for up to 8 days "2m": 60, # 2-minute data is available for up to 60 days "5m": 60, # 5-minute data is available for up to 60 days "15m": 60, # 15-minute data is available for up to 60 days "30m": 60, # 30-minute data is available for up to 60 days "60m": 730, # 60-minute data is available for up to 730 days (2 years) "90m": 730, # 90-minute data is available for up to 730 days (2 years) "1h": 730, # 1-hour data is available for up to 730 days (2 years) "1d": 10000, # Daily data is available for up to maximum available "5d": 10000, # 5-day data is available for up to maximum available "1wk": 10000,# Weekly data is available for up to maximum available "1mo": 10000,# Monthly data is available for up to maximum available "3mo": 10000 # Quarterly data is available for up to maximum available } max_days = valid_intervals[interval] end_date_pd = pd.to_datetime('today') max_start_date = end_date_pd - pd.to_timedelta(max_days, unit='d') # Adjust the start date if it exceeds the limit if pd.to_datetime(start_date) < max_start_date: st.warning(f"The selected start date exceeds the maximum allowed range for {interval} interval. Adjusting start date to {max_start_date.strftime('%Y-%m-%d')}") start_date = max_start_date fetch_data = st.button("Fetch and Display Data") if fetch_data and symbol: fetch_stock_data(symbol, start_date.strftime('%Y-%m-%d'), end_date, interval)