File size: 9,890 Bytes
8b9d246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aec6489
8b9d246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# app.py

# Import required libraries
import streamlit as st
import yfinance as yf
from datetime import date
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import os

# 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 CSV file
csv_file_path = 'ind_nifty500list.csv'  # Ensure this file is uploaded to your Hugging Face Space

# Check if the file exists
if not os.path.isfile(csv_file_path):
    st.error("The stock list file was not found. Please upload 'stock_list.csv' to your app.")
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:
                            delta = stock_data['Close'].diff()
                            up = delta.clip(lower=0)
                            down = -1 * delta.clip(upper=0)
                            roll_up = up.rolling(window=14).mean()
                            roll_down = down.rolling(window=14).mean()
                            RS = roll_up / roll_down
                            stock_data['RSI'] = 100.0 - (100.0 / (1.0 + RS))
                            # 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:
                            exp1 = stock_data['Close'].ewm(span=12, adjust=False).mean()
                            exp2 = stock_data['Close'].ewm(span=26, adjust=False).mean()
                            stock_data['MACD'] = exp1 - exp2
                            stock_data['MACD_Signal'] = stock_data['MACD'].ewm(span=9, adjust=False).mean()
                            stock_data['MACD_Hist'] = stock_data['MACD'] - stock_data['MACD_Signal']
                            # Plot MACD
                            fig_macd, ax = plt.subplots(figsize=(12, 4))
                            ax.plot(stock_data['Date'], stock_data['MACD'], label='MACD', color='purple')
                            ax.plot(stock_data['Date'], stock_data['MACD_Signal'], label='Signal', color='red')
                            ax.bar(stock_data['Date'], stock_data['MACD_Hist'], 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.")