# Import required libraries import streamlit as st import yfinance as yf from datetime import date import pandas as pd import os import matplotlib.pyplot as plt import pandas_ta as ta # Import pandas_ta for technical indicators # Set the title of the app st.title('Indian Stock Data Downloader and Volume Analyzer') # Sidebar for user inputs st.sidebar.header('Select Stocks and Options') # Path to your new CSV file csv_file_path = 'stock_list.csv' #csv_file_path = 'https://huggingface.co/spaces/riteshcp/Indian_Futures_OBV_Downloader/blob/main/ind_nifty500list.csv' # Update this to the path where you saved the CSV # Check if the file exists if not os.path.isfile(csv_file_path): st.error(f"The stock list file was not found at: {csv_file_path}") else: # Read the CSV file into a DataFrame stock_df = pd.read_csv(csv_file_path) # Ensure that the required columns are present required_columns = {'Symbol', 'Company Name'} if not required_columns.issubset(stock_df.columns): st.error(f"The CSV file must contain the following columns: {required_columns}") else: # Create a dictionary mapping company names to stock symbols stock_dict = pd.Series(stock_df['Symbol'].values, index=stock_df['Company Name']).to_dict() # Multiselect widget for stock selection selected_stocks = st.sidebar.multiselect('Select Stocks:', list(stock_dict.keys())) # Date input widgets for date range selection start_date = st.sidebar.date_input('Start Date', date(2021, 1, 1)) end_date = st.sidebar.date_input('End Date', date.today()) # Checkbox for selecting data options st.sidebar.header('Data Options') data_options = st.sidebar.multiselect( 'Select Data to Download:', ['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'], default=['Open', 'High', 'Low', 'Close', 'Volume'] ) # Technical Indicators selection st.sidebar.header('Technical Indicators') indicators = st.sidebar.multiselect( 'Select Technical Indicators to Calculate:', ['OBV (Amount)', 'RSI', 'MACD'] ) # Download button if st.sidebar.button('Download Data'): if selected_stocks: for company_name in selected_stocks: ticker = stock_dict[company_name] # Append '.NS' if not already present for NSE stocks if not ticker.endswith('.NS') and not ticker.endswith('.BO'): ticker += '.NS' # Fetch data from Yahoo Finance try: stock_data = yf.download(ticker, start=start_date, end=end_date) # Check if data is returned if stock_data.empty: st.warning(f"No data found for {company_name} ({ticker}) in the selected date range.") continue # Filter data based on selected options stock_data = stock_data[data_options] st.write(f"**Data for {company_name} ({ticker}):**") st.dataframe(stock_data) # Reset index to get 'Date' as a column stock_data = stock_data.reset_index() # Calculate Amount (Close * Volume) stock_data['Amount'] = stock_data['Close'] * stock_data['Volume'] # OBV in terms of Amount if 'OBV (Amount)' in indicators: # Calculate direction stock_data['Daily_Return'] = stock_data['Close'].pct_change() stock_data['Direction'] = stock_data['Daily_Return'].apply(lambda x: 1 if x > 0 else (-1 if x < 0 else 0)) stock_data['OBV_Amount'] = (stock_data['Amount'] * stock_data['Direction']).cumsum() # Plot OBV in Amount fig_obv_amount, ax = plt.subplots(figsize=(12, 4)) ax.plot(stock_data['Date'], stock_data['OBV_Amount'], label='OBV (Amount)', color='orange') ax.set_xlabel('Date') ax.set_ylabel('On-Balance Volume (Amount)') ax.set_title(f"{company_name} OBV (Amount)") ax.legend() st.pyplot(fig_obv_amount) # RSI if 'RSI' in indicators: stock_data['RSI'] = ta.rsi(stock_data['Close'], length=14) # Plot RSI fig_rsi, ax = plt.subplots(figsize=(12, 4)) ax.plot(stock_data['Date'], stock_data['RSI'], label='RSI', color='green') ax.set_xlabel('Date') ax.set_ylabel('RSI') ax.set_title(f"{company_name} RSI") ax.axhline(70, color='red', linestyle='--') ax.axhline(30, color='blue', linestyle='--') ax.legend() st.pyplot(fig_rsi) # MACD if 'MACD' in indicators: macd = ta.macd(stock_data['Close']) stock_data = pd.concat([stock_data, macd], axis=1) # Plot MACD fig_macd, ax = plt.subplots(figsize=(12, 4)) ax.plot(stock_data['Date'], stock_data['MACD_12_26_9'], label='MACD', color='purple') ax.plot(stock_data['Date'], stock_data['MACDs_12_26_9'], label='Signal', color='red') ax.bar(stock_data['Date'], stock_data['MACDh_12_26_9'], label='Histogram', color='grey') ax.set_xlabel('Date') ax.set_ylabel('MACD') ax.set_title(f"{company_name} MACD") ax.legend() st.pyplot(fig_macd) # Calculate moving averages stock_data['Volume_MA_5'] = stock_data['Volume'].rolling(window=5).mean() stock_data['Volume_MA_20'] = stock_data['Volume'].rolling(window=20).mean() # Plotting price and volume fig, ax1 = plt.subplots(figsize=(12, 6)) # Plot the closing price ax1.plot(stock_data['Date'], stock_data['Close'], color='blue', label='Close Price') ax1.set_xlabel('Date') ax1.set_ylabel('Close Price', color='blue') ax1.tick_params(axis='y', labelcolor='blue') # Create a second y-axis for volume ax2 = ax1.twinx() ax2.bar(stock_data['Date'], stock_data['Volume'], color='gray', alpha=0.3, label='Volume') # Plot moving averages of volume ax2.plot(stock_data['Date'], stock_data['Volume_MA_5'], color='red', label='5-Day MA') ax2.plot(stock_data['Date'], stock_data['Volume_MA_20'], color='green', label='20-Day MA') ax2.set_ylabel('Volume', color='gray') ax2.tick_params(axis='y', labelcolor='gray') # Add legends and title fig.legend(loc='upper left', bbox_to_anchor=(0.15, 0.85)) plt.title(f"{company_name} Price and Volume Chart with Moving Averages") fig.tight_layout() st.pyplot(fig) # Volume analysis stock_data['Volume_Pct_Change'] = stock_data['Volume'].pct_change() * 100 average_volume = stock_data['Volume'].mean() current_volume = stock_data['Volume'].iloc[-1] volume_trend = 'increasing' if current_volume > average_volume else 'decreasing' st.subheader(f"Volume Analysis for {company_name}") st.write(f"- **Average Volume:** {average_volume:,.0f}") st.write(f"- **Current Volume:** {current_volume:,.0f}") st.write(f"- **Volume is currently {volume_trend}.**") # Convert data to CSV csv = stock_data.to_csv(index=False).encode('utf-8') # Download button for CSV st.download_button( label=f"Download {company_name} Data as CSV", data=csv, file_name=f"{ticker}_{start_date}_{end_date}.csv", mime='text/csv' ) except Exception as e: st.error(f"Error fetching data for {company_name} ({ticker}): {e}") else: st.warning("Please select at least one stock.")