Stock Alert

Stock Alert is a personal project that sends me an email every weekday if the closing price reaches a pre-configured threshold such as fixed price or percentage change.

Stack

Node.js, Typescript, Jest, Google Cloud Platform

Example email with alerts

Example email with alerts

Purpose and Goal

As an investor I've been applying the Swing Trading approach - buy when it's cheap and sell when it's expensive. In the short and medium-term the market is volatile, so ideally I should look at the stock prices at least once a week to not miss any opportunity.

This repetitive task became a burden for me as the number of stocks increased, so I had the idea to automate it while learning something new, leading me to the following requirements:

  • it must be free to keep it running;
  • it must be flexible to add more alerts;
  • I need to learn new concepts;

Tech Stack

Cloud providers offers a generous amount of free tier products, usually for serverless ones. So the main logic would be performed by Cloud Functions running Node.js and Typescript.

In order to be make sure that the item would be processed and to be easy to add new type of alerts, I choose an Event Driven Approach using Pub/Sub as the message broker.

The Stock API free tier has an rate limit such as at most 5 requests per second, Cloud Tasks allows me to choose how much tasks will be performed per second.

Finally, in order to run it every weekday, I need a Cloud Scheduler to trigger the system.

Development

I wanted to start delivering value as soon as possible, so first I did the logic to access the API and logging on the console if the value was higher than a threshold. It worked but it required the entire environment setup to run it.

Then I added the database, the stock price was saved and the alert config was pre configured, but I still had to run it manually.

After setting up the infrastructure, I started receiving an email alert every day, but after each change I needed to deploy via command line.

I left this first version running for a while, it was already fulfilling my needs. Some months later I had the idea to have two more alerts, one for missing data and another one for percentage changes.

Before making any changes and seeing how this project could grow, I decided to add automated tests - ideally I should have added since the beginning - and a CI/CD on GitHub Actions to deploy every change automatically. Finally I added the logic and infrastructure for those two new alerts.

The following images show the current architecture:

Parse stock architecture

Parse stock architecture

Alert check architecture

Alert check architecture

Send email architecture

Send email architecture

At that time, I didn't find a way to synchronize on fan-in parts such as starting checking alerts after ALL stock price fetch has been done. My initial solution was executing each part after a specific amount of time, as it worked, I kept it and didn't revisit it.

Current Status and Future

It's been running since 2021, I received more than 600 alert emails and I didn't have any hosting cost.

Looking at the current design today, I would solve the fan-in problem by making the function that starts the fan-out write to the database the number of tasks that needs to be executed and each task executer function would decrement it atomically until the last one writes in a topic to start the next part.

In the future I might implement this solution and create an React UI to manage the alert config - today I input it directly on the database.

Emails received in 2023. I didn't open all of them, sorry me from the past 😅

Emails received in 2023. I didn't open all of them, sorry me from the past 😅

Initial emails received in 2021

Initial emails received in 2021

Lessons Learned

The main takeaway from this experience is delivering value early and iterate through it by running manually on my computer, moving it to the cloud, automating the deploy and then adding more features.

One big mistake I did in previous personal projects was spending months to create the super generic code, losing motivation and moving on to do another thing without having anything usable.

Honorable mention goes to the applied Event Driven Architecture that allowed me to easily create a new alert function.