80 lines
2.4 KiB
Markdown
80 lines
2.4 KiB
Markdown
Quick attempt at an optimal portfolio balancer.
|
|
|
|
## Notes:
|
|
1. The balancing algorithm is not currently optimal (Work in progress). [See Closeness section](#closeness)
|
|
1. 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.
|