1 – Building a Portfolio Manager with Python: First steps

This post is the first of a series of posts in which we will start from scratch and build a portfolio management tool using Python.

The full capabilities of this tool will still be discovered as we build it. However, at the very least, we will make it possible for the user to register the positions they hold in the stock market, defining the purchase date and sale date. From this, we will be able to give the user many insights, such as the sectors in which they have the most shares, portfolio distribution, portfolio beta, and many other indicators.

Moreover, as this tends to be a tool involving a lot of code, let’s take it in parts. Finally, I will be posting a link to a code versioning tool in future posts so that anyone can follow the evolution of the code

Some project choices

We will be building the code in Python 3. At first, we will be using basic libraries like json, but we will be improving this as we need.

The project will be done in multiple Python files to keep things organized. Depending on the file we are writing, I will leave a line like $ main.py at the beginning of the code block, to say that we are writing inside the main.

For this first moment, we will keep our “database” as JSON files. In the future, we can opt for migrating this to a more robust database manager.

Starting to code…

The first thing we need to start coding is to define the database. For this, you can create a config.py file so you can define the parameters and names for your code:

$ config.py
DATABASE_NAME = 'database.json'

Well, now that we have the DATABASE_NAME var, we need to create a database_handler.py file that we will define any functions that use/change the dataset.json so we can feed this file and read from it.

It is also interesting to import the JSON library and the config module we defined before, such as:

$ database_handler.py
import json
import config

# this class handle the database files
class databaseHandler:
    def __init__(self, database_name = config.DATABASE_NAME):
        self.database_name = database_name

        self.load_database()
    


    # load database content
    def load_database(self):
        print("Loading database content..")
        try:
            with open(self.database_name, 'r') as file:
                print("Found database, loading it")
                self.database_data = json.load(file)
        except FileNotFoundError:
            print(f"Database '{self.database_name}' not found. Creating a new one.")
            with open(self.database_name, 'w') as new_file:
                new_file.write('{}')
                self.database_data = {}

    def print_full_database(self):
        print("\nPrint database content..")
        try:
            print(json.dumps(self.database_data, indent=2))
        except Exception as e:
            print(f"Error printing database: {e}")

This code defines the class databaseHandler, that will handle the dataset CRUD (create, read, update, delete) operations. It also contains two functions: load_database(), this function reads an existing dataset.json file OR creates a new dataset.json file (if it doesn’t exist) and function print_full_database(), that basically prints the whole database content.

Finally, to request the execution of the methods, we will create a main.py file. This is the file that will be executed so you can interact with your portfolio manager. It will look like this:

$ main.py
from database_handler import databaseHandler

if __name__ == "__main__":
    
    database_handler = databaseHandler()

    while True:
        print("\n--- Operations Menu ---")
        print("1 - Print DATABASE file content")

        print("0 - Exit")

        option = input("Choose an option: ")

        try:
            option = int(option)
        except ValueError:
            print("Invalid option. Please enter a number.")
            continue

        if option == 1:
            database_handler.print_full_database()

        elif option == 0:
            break
        else:
            print("Invalid option. Please try again.")

Once we run this, the code will create a new database_handler instance. This will call the initialization (__init__) method from database_handler.py, creating and loading the database.json file.

Let’s check it out by running ‘python main.py‘ command in the root folder

Great!

After executing the code, you will notice a new file in your root folder: database.json. Our code creates it in case it doesn’t exist. There is a message in the UI explaining this.

Well.. that’s interesting… but how can we add stocks to the database file so we can check them in the portfolio manager?

That’s what we’ll cover in the next post in the series!

I hope you are finding the topic interesting. I would love to hear your suggestions in the comments field for features we should implement in the portfolio manager.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top