diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2ab7c6ca1d71a64ff3a9d72135260cb60a27534f Binary files /dev/null and b/.DS_Store differ diff --git a/REAMDE.md b/REAMDE.md new file mode 100644 index 0000000000000000000000000000000000000000..ca33e374febe31236a73e81ee5738a3f4c4622c3 --- /dev/null +++ b/REAMDE.md @@ -0,0 +1,35 @@ +Stock Analyzer +Project Overview +This is a Flask-based stock analysis website that offers user registration, login, stock price querying, and visualization. It leverages Flask, SQLite, Bootstrap, Matplotlib, and the Alpha Vantage API. +Directory Structure +Copy +StockAnalyzer/ +├── app.py +├── templates/ +│ ├── base.html +│ ├── index.html +│ ├── login.html +│ ├── predict_future.html +│ └── register.html +├── static/ +│ └── (images, CSS, JS files) +└── README.md +Installation and Launch +1. Install Dependencies +Ensure you have Python and pip installed. Then, install the required packages: +bashCopy +pip install flask pandas matplotlib requests sqlite3 +2. Get Alpha Vantage API Key +Sign up at Alpha Vantage to get a free API key. Replace 'YOUR_API_KEY' in the get_stock_data_alpha_vantage function in app.py with your key. +3. Start the Flask App +Run the following command in the project root directory to start the Flask app: +bashCopy +python app.py +The app will run locally, accessible at http://127.0.0.1:50582. +4. Access the Website +Open your browser and navigate to http://127.0.0.1:50582 to see the homepage. You can register, log in, query stock prices, and view visualizations. +Features +User registration and login. +Stock price querying and visualization. +Responsive design using Bootstrap. +Immediate user feedback with Flask's flash function. diff --git a/app.py b/app.py new file mode 100644 index 0000000000000000000000000000000000000000..1af3aab9dbe8123424104ae1e30920594e15b6a4 --- /dev/null +++ b/app.py @@ -0,0 +1,164 @@ +import requests +import pandas as pd +import base64 +from flask import Flask, render_template, request, redirect, url_for, flash, session, send_file +import matplotlib +import matplotlib.pyplot as plt +from io import BytesIO +import sqlite3 +matplotlib.use("Agg") + +app = Flask(__name__) +app.secret_key = 'secret_key' + +# init database +def init_db(): + conn = sqlite3.connect('users.db') + c = conn.cursor() + c.execute('''CREATE TABLE IF NOT EXISTS users (username TEXT PRIMARY KEY, password TEXT)''') + conn.commit() + conn.close() + +init_db() + +# connect database +def get_db_connection(): + conn = sqlite3.connect('users.db') + conn.row_factory = sqlite3.Row + return conn + +# sign up +@app.route('/register', methods=['GET', 'POST']) +def register(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + + conn = get_db_connection() + c = conn.cursor() + + # check whether the user exist + c.execute('SELECT * FROM users WHERE username = ?', (username,)) + user = c.fetchone() + + if user: + flash('Username already exists. Please choose a different one.', 'danger') + conn.close() + return redirect(url_for('register')) + + # save into database + c.execute('INSERT INTO users (username, password) VALUES (?, ?)', (username, password)) + conn.commit() + conn.close() + + flash('Registration successful! You can now log in.', 'success') + return redirect(url_for('login')) + + return render_template('register.html') + +# log in +@app.route('/login', methods=['GET', 'POST']) +def login(): + if request.method == 'POST': + username = request.form['username'] + password = request.form['password'] + + conn = get_db_connection() + c = conn.cursor() + + # check user and password + c.execute('SELECT * FROM users WHERE username = ? AND password = ?', (username, password)) + user = c.fetchone() + + conn.close() + + if user: + session['username'] = username + flash('Login successful!', 'success') + return redirect(url_for('index')) + else: + flash('Invalid username or password. Please try again.', 'danger') + + return render_template('login.html') + +# log out +@app.route('/logout') +def logout(): + session.pop('username', None) + flash('You have been logged out.', 'info') + return redirect(url_for('login')) + +# main page +@app.route('/') +def index(): + if 'username' not in session: + flash('Please log in to access the dashboard.', 'warning') + return redirect(url_for('login')) + return render_template('index.html', username=session['username']) + +# plot stock +@app.route('/predict_future', methods=['GET', 'POST']) +def predict_future(): + if 'username' not in session: + flash('Please log in to access this feature.', 'warning') + return redirect(url_for('login')) + + img_base64 = None + stock_symbol = None + start_date = None + end_date = None + + if request.method == 'POST': + stock_symbol = request.form['stock_symbol'] + start_date = request.form['start_date'] + end_date = request.form['end_date'] + + # get stock price data + try: + stock_data = get_stock_data_alpha_vantage(stock_symbol, start_date, end_date, 'VLP8G4UP0NW3RFAA') + print(f"Stock data for {stock_symbol} from {start_date} to {end_date}:") + print(stock_data) + except Exception as e: + flash(f'Error fetching stock data: {e}', 'danger') + return render_template('predict_future.html', stock_symbol=stock_symbol, start_date=start_date, end_date=end_date) + + if stock_data.empty: + flash(f'No data available for {stock_symbol} from {start_date} to {end_date}.', 'warning') + return render_template('predict_future.html', stock_symbol=stock_symbol, start_date=start_date, end_date=end_date) + + # plot + plt.figure(figsize=(10, 5)) + plt.plot(stock_data.index.to_numpy(), stock_data['4. close'].to_numpy(), label='Close Price') + plt.title(f'Stock Price for {stock_symbol}') + plt.xlabel('Date') + plt.ylabel('Price') + plt.legend() + plt.grid(True) + + img = BytesIO() + plt.savefig(img, format='png') + img.seek(0) + img_base64 = base64.b64encode(img.getvalue()).decode('utf8') + plt.close() + + return render_template('predict_future.html', img_base64=img_base64, stock_symbol=stock_symbol, start_date=start_date, end_date=end_date) + + +def get_stock_data_alpha_vantage(symbol, start_date, end_date, api_key): + url = f'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}&apikey={api_key}&outputsize=full' + r = requests.get(url) + data = r.json() + + # decode data + time_series = data.get('Time Series (Daily)', {}) + df = pd.DataFrame.from_dict(time_series, orient='index', dtype=float) + df.index = pd.to_datetime(df.index) + df = df.sort_index() + + # set date + df = df[(df.index >= start_date) & (df.index <= end_date)] + + return df + +if __name__ == '__main__': + app.run(debug=True, port=50582) \ No newline at end of file diff --git a/users.db b/users.db new file mode 100644 index 0000000000000000000000000000000000000000..4fb527ee87a05b18caf81ff464a9f96d83322865 Binary files /dev/null and b/users.db differ