Introduction

A Portfolio Analyzer allows analysts to create custom portfolios with selected stocks, and watch their overall returns depending on timeframe since portfolio inception. With this application, you can choose a set of stocks to add into a custom portfolio (stocks can be from any timeframe). You can view analysis such as market sector breakdown, monthly returns, total portfolio value, and more.

This project was the top 2 project for this year’s cohort. Won some gifts from GS (thanks GS!).

Goldman Portfolio Analzyer Photo

Overview

The portfolio analyzer has quite a lot of functionality. There were 4 mandatory features, and 6 other optional features to complete. We completed 9 out of 10 total features.

Features

Analysts have a secure way to register for an account, inclusive of password reset and email validation features using JWTs.

Analysts can then create their own porfolio and choose to make their portfolios public in order to share them with other analysts. These portfolios have advanced graphical analysis for standard and additional metrics, like daily PNL and market sector breakdown. This allows analysts to get an easy snapshot into their current portfolio performance.

We also included permission control, such that administrators will be able to check access logs and understand which users have logged in at which specific timeframes, and also the actions that they have performed (LOGIN, RESET_PASSWORD, REGISTER etc)

Features

There were 3 main sections of the application. First, the application handles stocks and portfolios. Second, the application implements a secure authentication and authorization flow. Last, the application has a asynchronous jobber that runs daily and populates the database with up-to-date EOD stock market data. Due to API call limits, we chose to only contain DJIA-tracked stocks. The API we used was Alphavantage API.

Architecture

Architecture

We decided on a simple technology stack that was easy to pick up and navigate because there were no specific requirements on what technologies should be used (except Spring Boot).

Layers

For our application design, we split the backend application into a simple 3 tier layered architecture:

  1. Presentation Layer - Controllers only handle API interactions with the client (frontend)
  2. Business Logic Layer - Services do the bulk of business logic handling where application, and orchestrate the interaction between services and the database.
  3. Data Access Layer - Repositories handle anything to do with data retrieval from MongoDB, and the model is basically a class of the entities in the DBs.

Additionally, we externalised the configuration files. We utilised a utility folder for custom-made helper functions for specific tasks (e.g serialization into a specific format), and we utilised Enums for specific values that wouldn’t change. E.g user state (if user is LOGGED_IN vs LOGGED_OUT).

Spring Boot File Structure

Notably, we decided to group our directories based on Entities since this was a smaller project, and we didn’t feel the need to venture too deep into Domain Driven Design.

We extracted our application configurations such that they could be changed during runtime. They were not hardcoded into application, and we have different configurations for dev vs prod environments. We also produced reusable templates for our emails instead of hardcoding them.

Directory

Libraries

To speed up development, we utilised a few open source libraries. These libraries were chosen as they were actively maintained and had a strong community behind them.

Libraries

As an overview:

  1. Spring Security - Helps to form the backbone of authentication and authorization
  2. Java Mail - Sending out emails for password reset and email verification.
  3. Spring-Flux- Allows you to make requests to external APIs
  4. Spring-Data Mongo - Connector to MongoDB, and comes with some great classes like MongoRepository.
  5. Jackson - Serialization and Deserialization
  6. Lombok - Provides a suite of “Power Decorators” that help to reduce the number of lines of code written.
  7. Actuator - Powerful development tool that gives you insight into your application (health etc.)
  8. Spring-dotenv - to load dotenv files at runtime.

Key Components

There were 2 huge components that took a lot of time.

Scheduler

It isn’t practical to have to manually run scripts to retrieve daily EOD stock data from APIs. This would take a lot of time. Additionally, it’s best to make DB-affecting API calls during low-traffic periods.

Scheduler

To solve this, we created a CRON scheduler that will do the following:

  1. Call Alphavantage API
  2. Clean data and transform data from API format to DB schema
  3. Load data into DB
  4. Validate steps (2-3)

Authentication

Spring Security formed the backbone for authE and authZ. We used JWT tokens to encode user-related information to be passed around (securely) between the client and server. The token doesn’t contain private data, but only an identifier that could identify which user was trying to login.

Registration

Design

It was paramount to ensure good code quality and we tried to adhere to OO principles + clean coding standards as much as we could. At a high level:

  1. Proper variable naming (long but readable vs short but ambiguous, same naming convention for whole application, same variable = same name throughout different files)
  2. Proper indentation throughout application
  3. No God Class - Keep classes small and related to 1 specific function
  4. High Cohesion - Functions that make use of each other should be written near each other
  5. Low Coupling - Try not to have too much strong association, focus on dependency injection
  6. OO Principles.
  7. Domain Driven Design - Usage of some patterns such as repository to help separate the infrastructure layer
  8. And More

Design

Creational Pattern

GOF Creational Pattern

To allow easy creation of common complex objects, we introduced builders when needed. Builders allow us to construct complex objects step by step, making the code extremely clear and readable. This was used mainly for constructing complex queries for the alphavantage API, and also for the construction of our JWT tokens.

Structural Pattern

GOF Structural Pattern

To aid in abstraction, we introduced a facade that masked the complexity of converting and managing external API data. This helps us ensure that the services do not incur the cost of having to have complex logic that does deserialization or transformation. Hence, the API can even be swapped out in future, if we decide on using other APIs for stock details.

Improvements

Improvements

There were many areas we could’ve done better. Here are 4 key areas:

  1. Including Unit Tests - Due to the lack of time, we were unable to write Unit Test. This resulted in some inefficiencies during our debugging and refactoring.
  2. Performance Testing - We were unable to test our application performance, and it would be ideal to understand how scalable the current application is. This would help us understand areas for optimization.
  3. Screaming Architecture - A screaming architecture is a folder structure that screams out the domain. While our current structure is good for simple projects, it is not scalabe for large projects because it is unclear which entities interact with each other just by looking at the folder structure. Swapping to a more DDD-focused directory would greatly aid maintainability and readability for future developers.
  4. HA, DR and More - We did not deploy the application as it was not in the requirements. This meant that we were unable to make use of all the benefits of the cloud. It would be ideal to have deployed the application on one of the key cloud providers.

Conclusion

This was a great project, even though challenging. It gave me great insight into OO principles, and allowed me to pick up the Spring Framework.

Hope you learnt something today!