Trading Demo

Trading Demo is a paper trading application via which you can monitor live stock prices and make informed decisions for portfolio growth. I built this project from scratch using the Flask framework for Python along with JavaScript, PostgreSQL, and Redis.

Role

As the sole creator, I worked on all stages of the development process including research, user testing, prototyping, and web development.

Period

Dec 2023 - Jan 2024

Trading Demo

Trading Demo is a paper trading application via which you can monitor live stock prices and make informed decisions for portfolio growth. I built this project from scratch using the Flask framework for Python along with JavaScript, PostgreSQL, and Redis.

Role

As the sole creator, I worked on all stages of the development process including research, user testing, prototyping, and web development.

Period

Dec 2023 - Jan 2024

Background

Trading Demo is a stock market simulator for practicing investment strategies in a realistic environment. I built the application for my final project in Harvard's Introduction to Computer Science, CS50. As an extension of my solution to CS50's Problem Set 9: Finance, the first iteration of the project began with a simple framework for user account creation, stock price lookups, and portfolio management using Flask and the Yahoo Finance API.

After researching other stock trading simulators in the market, I discovered a limited availability of free trading demo accounts. To address this gap, I enhanced the application by introducing features such as an interactive graph with historical data. These additions make Trading Demo an excellent choice for novice traders seeking a risk-free environment to learn the ropes. Its comprehensive set of tools and user-friendly interface set it apart, providing valuable insights and a seamless learning experience for those new to trading.

Features

  • Real-Time Market Data: Access to real-time stock prices via the Yahoo Finance API.

  • Performance Analytics: An interactive chart to track gains and losses over standard timescales, allowing users to monitor their overall performance.

  • Secure Online Storage: Trading Demo uses a range of security measures for online data storage such as password hashing and session tokens, enabling users to securely access their Trading Demo accounts anywhere.

Web Stack

I chose Flask as the framework for the web application based on its lightweight and modular architecture, enabling rapid development and scalability. Flask's simplicity and flexibility played a crucial role in streamlining the development process, allowing for efficient integration of database queries while maintaining a clean and maintainable codebase.

Moreover, I implemented PostgreSQL and Redis session storage across the project to effectively manage user data, ensuring seamless user experiences and efficient handling of dynamic content updates.

In terms of deployment, I chose Vercel as my preferred platform due to its built-in PostgreSQL and Redis integrations.

Information Architecture

Object-Oriented Design

I applied object-oriented design principles to improve code organisation, readability, and maintainability.

The Timescale class defined in helpers.py is designed to manage different time intervals used within the application. It provides a convenient way to define and retrieve time-related parameters. This class initializes a dictionary, timescale, with keys representing different time intervals (e.g., "1D" for one day, "1M" for one month) and corresponding values representing the number of days in each interval.

The Timescale() class serves as a compact repository for handling time intervals, adopting a modular approach by bundling related functionalities into one class. By encapsulating both the timescale dictionary and its associated methods, I ensure adherence to the encapsulation principle, enabling the abstraction of time-related functionalities. Additionally, I've designed the class to provide a straightforward interface for obtaining keys, values, and date references, promoting a clean separation of concerns.

class Timescale:
    def __init__(self):
        self.timescale = {
            "1D": 1,
            "5D": 5,
            "1M": 30,
            "6M": 180,
            "YTD": (datetime.now() 
            - datetime(datetime.now().year, 1, 1)).days,
            "1Y": 365,
            "5Y": 5 * 365,
        }

    def get_keys(self):
        keys = list(self.timescale.keys())
        return keys

    def get_value(self, key):
        num_days = self.timescale.get(key)
        date = datetime.now() - timedelta(days=num_days)
        return date
class Database:
    def __init__(self):
        self.db = SQL(postgres_url + "?sslmode=require")

    # ... (methods for user-related queries, 
    # portfolio operations, and historical data)

    def get_total(self):
        rows = self.get_portfolio()
        column = self.get_cash()

        for row in rows:
            row["price"] = lookup(row["symbol"])["price"]
            row["total"] = row["price"] * row["shares"]
            column += row["total"]
        return column

The Database() class in helpers.py encapsulates the interaction with the database, utilising CS50's SQL module. It includes methods to perform various database operations, such as retrieving user information, updating portfolios, managing historical data, and handling user authentication.

The Database() class provides an abstraction layer for database operations, enhancing modularity and maintainability. It encapsulates SQL queries, making it easier to manage changes in the database schema or switch to a different database system in the future. Moreover, the class strictly adheres to the single responsibility principle by focusing solely on database-related functionalities, ultimately contributing to a more maintainable and comprehensible codebase.

Dynamic Data Rendering

I incorporated dynamic data rendering to enhance the user experience without the need for complete page reloads.

The get_timescale() route defined in app.py returns data intended for processing with JavaScript. This facilitates the dynamic fetching and updating of time-sensitive data associated with the user's portfolio. The asynchronous data retrieval allows for real-time updates on the client side, ensuring that users receive the most current information without disrupting their overall interaction with the application.

The utilisation of asynchronous data fetching aligns with modern web development practices, offering a more responsive and interactive interface. This dynamic data approach contributes to a smoother user experience, providing users with up-to-date financial information and facilitating a more engaging and efficient interaction with Trading Demo.

@app.route('/timescale', methods=['GET'])
@login_required
def get_timescale():
    tab = request.args.get("tab")
    totals_history = db.get_totals_history(tab)
    gain_loss, percent_change = 
    db.get_totals_difference(tab)
    data = {}
    chart_data = {}

    for date, balance in totals_history.items():
        chart_data[date] = balance

    data[tab] = {
        "gain_loss": gain_loss,
        "percent_change": percent_change,
        "chart_data": chart_data
    }

    return data

Next Steps

There is a number of potential enhancements for future iterations:

  • Performance Analytics for Individual Shares: Currently, the performance analytics feature only tracks the overall performance of the user's portfolio. In the future, I plan to add a similar feature for individual shares, allowing users to monitor the performance of their holdings over time.

  • Improved Data Source: The Yahoo Finance API is no longer accessible to new users. Moreover, it has a limited number of endpoints and does not provide access crucial data such as EPS and P/E ratios. In the future, I plan to switch to a more robust API, such as the one from Financial Modeling Prep, which offers a wider range of endpoints and more comprehensive data.

  • Additional Features: I plan to add more features to Trading Demo, including a feed for aggregating financial news, a watchlist, and a leaderboard. These features will enhance the user experience and provide users with more opportunities to explore financial data and learn about investment strategies.

You can try Trading Demo by creating a free account here.