1

I'm building a basic stock watcher application - let's call the currently-watched stock N. When the stock moves by X%, trigger a notification / event. X is defined on a per user basis.

The server holds the stock's current price, alongside the users last-known price (the last alert each user received)

What is the best way to architect this? I don't want to loop through each user upon any price movement to check if their set moved-percentage was reached, as that is quite obviously a huge performance issue.

Resources and links for further researching would be greatly appreciated.

I am building this in Javascript ( nodeJS to be precise), but I'm more interested in the concepts behind building this rather than direct code samples.

Thanks!

Life
  • 67
  • 1
  • 6

2 Answers2

1

You could have a list of watchers for each stock that would be a list of users watching that stock and what their notification trigger price is. If you keep the list sorted by trigger price, then you can easily just traverse from one end of the list to collect the exact list of users who should now be notified. After firing a notification for that user, you then decide whether you set a new trigger price for that user or remove them from the list since their notification was already sent.

This type of scheme has the following advantages:

  1. Finding out which users should be notified after a given price movement to a new price is simple and fast.
  2. There's nothing in this that is related to the total number of users so it can scale to huge numbers of users.
  3. For a given stock, you only have to deal with the users that are watching that specific stock - not the whole user base.
  4. Adding a user notification is just a sorted insertion into the list (binary search on the trigger price and insert into the list - known insertion algorithm).

To make things such as removing a user from your system more efficient, the user object probably also keeps a list of securities that are being watched by that user (and their trigger price) so you could go to each security and remove that user's watch from its list without having to search all securities. So, adding a watch would add an item to the user object list and add the user and trigger price to the security-specific list.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Please be patient - I intended to mark an answer but had things going on last evening that prevented me from immediately checking. Thank you for your response. – Life Jun 21 '17 at 15:06
  • upvoted but how would having watchers per stock not do an O(n) scan? I am assuming each watcher will keep a list of all the prices set under that asset and you are going to loop over them right? – PirateApp Apr 16 '19 at 13:00
  • 1
    @PirateApp - Well, this was a little while ago, but the list of users can be sorted in price trigger order. So, when a price changes, you check the low end of the list and see if the lowest price wants a notification of the change. If so, you notify them and walk up the list to the next. If still below the notification threshold, you notify them. You just walk up the list until the next notification price is above the threshold and you stop. So, you're walking part of the list from low to high, but only the ones that need to be notified anyway (plus one more that doesn't need to). – jfriend00 Apr 16 '19 at 13:32
  • thanks for the clarification, i have more than just the price, hence was wondering how this method would work – PirateApp Apr 16 '19 at 13:43
  • 1
    @PirateApp - Well, you can post your own question with your own specific requirements if you want. – jfriend00 Apr 16 '19 at 19:57
0

The user collection in the database should have a column to hold the user's X percentage. Let's say... x_col

When you are setting up the listener for percentage change, just pass the user's x_col into the conditional. (i.e if the change that just happened is >= user.x_col throw a notification.)

The user object above is assuming you are using a global for your current logged in user. If not, you can just query the collection for what the x_col value is in the document that has info matching with whatever unique info you use to check logged in user.

SidTheBeard
  • 379
  • 3
  • 11