Go to file
2020-07-12 23:38:28 -04:00
src First commit 2020-07-12 23:38:28 -04:00
.gitignore First commit 2020-07-12 23:38:28 -04:00
.prettierrc First commit 2020-07-12 23:38:28 -04:00
package.json First commit 2020-07-12 23:38:28 -04:00
README.md First commit 2020-07-12 23:38:28 -04:00
test First commit 2020-07-12 23:38:28 -04:00
yarn.lock First commit 2020-07-12 23:38:28 -04:00

Quick attempt at an optimal portfolio balancer.

Notes:

  1. The balancing algorithm is not currently optimal (Work in progress). See Closeness section
  2. No external stock API is used. The given API gives only daily time-series output. This application is built as a stream processing system which would allow automatic rebalancing for specific events such as a price change of more than X%. I may add a randomized price generator as an input.

Install

yarn

To run

Using the pre-seed file with pricing from Jul 12th:

< test node .

Using the pre-seed file and allowing interactive commands:

cat test - | node .

Interactive Commands:

<TICKER>:<price> Sets the stock price for the given ticker

example:

AAPL:152.3

rebalance:<account_id> Triggers a rebalance for the given account ID

example:

rebalance:1

note: Account 1 is there by default.

Closeness

The problem of portfolio balancing can be described as such:

Minimize:
   w_f - w_t
   e.g.
      SUM( |c_i*p_i - t_i| ) for stocks i
   or
      SUM( (c_i*p_i - t_i)^2 ) for stocks i

Subject to:
   SUM( c_i*p_i ) <= T
   c_i are Integers >= 0

Where
   w_f is the final portfolio
   w_t is the target portfolio
   c_i is the number of shares of stock i
   p_i is the price of stock i
   t_i is the total optimal fractional amount invested in stock i
      e.g. % allocation * total portfolio value

This problem statement falls in the Mixed Integers Quadratic Programming category. This problem can be solved through enumeration in exponential time 2^n where n is the total number of possible stocks purchase (not just ticker), which is very much impractical. Optimisations can be applied to reduce it to 2^n where n is the total number of tickers, although still exponential. From there (or possibly through a simplified problem statement), this can possibly be solved in pseudo-polynomial time using algorithms such as branch-and-bound or Quadknap.

Currently, the algorithm used is non-optimal in some edge-cases but produces very close results in most cases. That algorithm runs in linear time (quasilinear if tickers are not previously sorted) and can be used to evaluate the bounds in a branch-and-bound algorithm for potentially optimal results.

Unfortunately, time constraints prevented me from finishing the implementation as of Sunday July 12th. I will update this README if that changes.