Creating an advanced-level Stock Market Prediction System involves designing a robust database structure, implementing backend logic, and creating responsive frontend pages using Flask and Bootstrap 5. Below is a detailed breakdown of the database structure, Flask application code, and related pages.
Database Structure
The database will store user data, stock data, predictions, and user portfolios. We'll use SQLAlchemy (ORM for Flask) to define the database models.
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
email = db.Column(db.String(100), unique=True, nullable=False)
password = db.Column(db.String(200), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
is_admin = db.Column(db.Boolean, default=False)
portfolios = db.relationship('Portfolio', backref='user', lazy=True)
class Stock(db.Model):
id = db.Column(db.Integer, primary_key=True)
symbol = db.Column(db.String(10), unique=True, nullable=False)
name = db.Column(db.String(100), nullable=False)
price = db.Column(db.Float, nullable=False)
historical_data = db.relationship('StockData', backref='stock', lazy=True)
predictions = db.relationship('Prediction', backref='stock', lazy=True)
class StockData(db.Model):
id = db.Column(db.Integer, primary_key=True)
stock_id = db.Column(db.Integer, db.ForeignKey('stock.id'), nullable=False)
date = db.Column(db.DateTime, nullable=False)
open_price = db.Column(db.Float, nullable=False)
high_price = db.Column(db.Float, nullable=False)
low_price = db.Column(db.Float, nullable=False)
close_price = db.Column(db.Float, nullable=False)
volume = db.Column(db.Integer, nullable=False)
class Prediction(db.Model):
id = db.Column(db.Integer, primary_key=True)
stock_id = db.Column(db.Integer, db.ForeignKey('stock.id'), nullable=False)
predicted_price = db.Column(db.Float, nullable=False)
prediction_date = db.Column(db.DateTime, default=datetime.utcnow)
class Portfolio(db.Model):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
stock_id = db.Column(db.Integer, db.ForeignKey('stock.id'), nullable=False)
quantity = db.Column(db.Integer, nullable=False)
purchase_price = db.Column(db.Float, nullable=False)
purchase_date = db.Column(db.DateTime, default=datetime.utcnow)
Flask Application Structure
Here’s the directory structure for the project:
stock_market_prediction/
│
├── app/
│ ├── __init__.py # Initialize the Flask app and database
│ ├── models.py # Database models (User , Stock, StockData, Prediction, Portfolio)
│ ├── routes.py # Application routes and views
│ ├── forms.py # Forms for user input (if using Flask-WTF)
│ ├── static/ # Static files (CSS, JS, images)
│ │ ├── css/
│ │ │ └── styles.css # Custom CSS styles
│ │ └── js/
│ │ └── scripts.js # Custom JavaScript files
│ └── templates/ # HTML templates
│ ├── register.html # Registration page
│ ├── login.html # Login page
│ ├── dashboard.html # User dashboard
│ ├── stock_details.html # Stock details page
│ ├── portfolio.html # User portfolio page
│ └── layout.html # Base layout for templates
│
├── migrations/ # Database migration files (if using Flask-Migrate)
│
├── config.py # Configuration settings for the app
│
├── requirements.txt # Python package dependencies
│
└── run.py # Entry point to run the application
Flask Application Code
Below is the Flask application code with routes, forms, and database integration.
from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash, check_password_hash
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///stock_market.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
# User Registration
@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
email = request.form['email']
password = generate_password_hash(request.form['password'], method='sha256')
new_user = User(username=username, email=email, password=password)
db.session.add(new_user)
db.session.commit()
flash('Registration successful! Please log in.', 'success')
return redirect(url_for('login'))
return render_template('register.html')
# User Login
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
email = request.form['email']
password = request.form['password']
user = User.query.filter_by(email=email).first()
if user and check_password_hash(user.password, password):
session['user_id'] = user.id
session['username'] = user.username
flash('Login successful!', 'success')
return redirect(url_for('dashboard'))
else:
flash('Invalid email or password.', 'danger')
return render_template('login.html')
# Dashboard
@app.route('/')
def dashboard():
if 'user_id' not in session:
return redirect(url_for('login'))
stocks = Stock.query.all()
return render_template('dashboard.html', stocks=stocks)
# Stock Details
@app.route('/stock/<int:id>')
def stock_details(id):
stock = Stock.query.get_or_404(id)
predictions = Prediction.query.filter_by(stock_id=id).all()
return render_template('stock_details.html', stock=stock, predictions=predictions)
# Add to Portfolio
@app.route('/add_to_portfolio/<int:stock_id>', methods=['POST'])
def add_to_portfolio(stock_id):
quantity = request.form.get('quantity', 1, type=int)
purchase_price = request.form.get('purchase_price', type=float)
new_portfolio_item = Portfolio(user_id=session['user_id'], stock_id=stock_id, quantity=quantity, purchase_price=purchase_price)
db.session.add(new_portfolio_item)
db.session.commit()
flash('Stock added to portfolio!', 'success')
return redirect(url_for('dashboard'))
# View Portfolio
@app.route('/portfolio')
def view_portfolio():
portfolio_items = Portfolio.query.filter_by(user_id=session['user_id']).all()
return render_template('portfolio.html', portfolio_items=portfolio_items)
# User Logout
@app.route('/logout')
def logout():
session.pop('user_id', None)
session.pop('username', None)
flash('You have been logged out.', 'success')
return redirect(url_for('dashboard'))
if __name__ == '__main__':
with app.app_context():
db.create_all()
app.run(debug=True)
HTML Templates
Here are some basic HTML templates using Bootstrap 5 for the pages mentioned.
register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Register</title>
</head>
<body>
<div class="container">
<h2 class="mt-5">Register</h2>
<form method="POST">
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Login</title>
</head>
<body>
<div class="container">
<h2 class="mt-5">Login</h2>
<form method="POST">
<div class="mb-3">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" name="email" required>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<button type="submit" class="btn btn-primary">Login</button>
</form>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
dashboard.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Dashboard</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">Stock Market Predictor</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/portfolio">Portfolio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-5">
<h2>Available Stocks</h2>
<div class="row">
{% for stock in stocks %}
<div class="col-md-4">
<div class="card mb-4">
<div class="card-body">
<h5 class="card-title">{{ stock.name }} ({{ stock.symbol }})</h5>
<p class="card-text">Current Price: ${{ stock.price }}</p>
<form action="{{ url_for('add_to_portfolio', stock_id=stock.id) }}" method="POST">
<input type="number" name="quantity" value="1" min="1" class="form-control mb-2" required>
<input type="hidden" name="purchase_price" value="{{ stock.price }}">
<button type="submit" class="btn btn-primary">Add to Portfolio</button>
</form>
<a href="{{ url_for('stock_details', id=stock.id) }}" class="btn btn-info mt-2">View Details</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
stock_details.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>{{ stock.name }} Details</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">Stock Market Predictor</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/portfolio">Portfolio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-5">
<h2>{{ stock.name }} ({{ stock.symbol }})</h2>
<p>Current Price: ${{ stock.price }}</p>
<h4>Predictions</h4>
<ul class="list-group">
{% for prediction in predictions %}
<li class="list-group-item">
Predicted Price: ${{ prediction.predicted_price }} on {{ prediction.prediction_date.strftime('%Y-%m-%d') }}
</li>
{% endfor %}
</ul>
<a href="{{ url_for('dashboard') }}" class="btn btn-secondary mt-3">Back to Dashboard</a>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
portfolio.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<title>Your Portfolio</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">Stock Market Predictor</a>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/dashboard">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container mt-5">
<h2>Your Portfolio</h2>
{% if portfolio_items %}
<table class="table">
<thead>
<tr>
<th>Stock</th>
<th>Quantity</th>
<th>Purchase Price</th>
<th>Purchase Date</th>
</tr>
</thead>
<tbody>
{% for item in portfolio_items %}
<tr>
<td>{{ item.stock.name }} ({{ item.stock.symbol }})</td>
<td>{{ item.quantity }}</td>
<td>${{ item.purchase_price }}</td>
<td>{{ item.purchase_date.strftime('%Y-%m-%d') }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>Your portfolio is empty.</p>
{% endif %}
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
Additional Features and Enhancements
To further enhance the Stock Market Prediction System, consider implementing the following features:
- Stock Price Prediction Model: Integrate a machine learning model to predict stock prices based on historical data.
- User Notifications: Allow users to set alerts for specific stock price changes.
- Market News Section: Provide users with the latest news related to the stock market.
- Advanced Analytics: Implement charts and graphs to visualize stock performance over time.
- Admin Panel: Create an admin interface for managing stocks, users, and predictions.
Conclusion
This advanced Stock Market Prediction System structure provides a comprehensive foundation for building a fully functional application using Flask and Bootstrap 5. You can further enhance the application by integrating machine learning models for predictions, adding user notifications, and implementing advanced analytics features. The modular design allows for easy expansion and maintenance, making it suitable for both beginners and experienced developers.