Creating this project to solve personally encountered problem of how much to invest in each stock out of a basket to achieve a target % allocation for each stock.
Let's say you have invested in 3 stocks (or any other instruments for that matter) viz. INFOSYS, TCS and WIPRO. Your initial investment in as follows:
Instrument | Initial Investment | Initial Investment % | Target Investment % |
---|---|---|---|
INFOSYS | ₹30 | 30% | 33% |
TCS | ₹50 | 50% | 33% |
WIPRO | ₹20 | 20% | 34% |
Now, you want to invest an additional sum of
If we assume that we invest
Instrument | Allocation % |
---|---|
INFOSYS | 30.7% |
TCS | 42.3% |
WIPRO | 26.9% |
However, these might not be the most optimal allocation. Our objective here is to find the most optimal allocation.
Running the code gives that we should split the amount of
>> python -m src.views.file
Optimizing the MSE to compute optimal allocation. Sit tight!
Final allocation of investment of unit 30 is as follows:
Instrument | Initial Investment % |
Target Investment % |
Suggested Investment |
Final % |
---|---|---|---|---|
INFOSYS | 30 | 33 | 10 | 30.7692 |
TCS | 50 | 33 | 10 | 46.1538 |
WIPRO | 20 | 34 | 10 | 23.0769 |
You have a portfolio of
This means that your current investment allocation ratio (between
Now, suppose you want to invest an additional amount of
This implies that:
where,
To solve this problem, we have converted it into an optimizing problem. If we assume
some initial allocation for each instrument and calculate the Mean Squared Error (
So,
And, we can minimize this function to find all
- No selling. The whole point of writing this code is that we don't want to sell any existing instruments to adjust to the target allocation.
- We assume that we would want to invest whole amount of
new_investment
i.e. if you input$₹30$ as new investment to be allocated, the model would try to allocate the full amount between the instruments. - We don't solve for the problem in a rigorous way. The correct way would be create
$n$ equations for$n$ variables and solve them using some equation solver. However if that were easy, we wouldn't have invented Machine Learning. So, we instead solve the problem by minimizing the MSE between target and actual instrument allocation using a minimizer function (similar to how Gradient Descent would minimize error function in Machine Learning).
Right now there are two ways of using the code. But first setup a virtual environment
and install the requirements using pip install poetry
and then, poetry install
command. If there's an interest and people find it useful, I can build a simple UI for
usage.
If you wish to easily change values to play around, you can directly modify the file
src/views/file.py
. It already contains example values from the README
file. To run
the code, run command python -m src.views.file
from project directory.
If you do not wish to temper with any file, simply run code python -m src.views.terminal
and follow the terminal instructions. Example usage given below:
>> python -m src.views.terminal
Please add identifier/names of financial instruments separated by comma(,)
INFOSYS,TCS,WIPRO
Please add initial investment (all in same currency) of financial instruments separated by comma(,)
30,50,20
How much money do you want to invest?
30
Please add target investment ratio (between 0 and 1) of financial instruments separated by comma(,)
.33,.33,.34
It's a simple program with scary looking but simplistic mathematics behind it as
explained above. We have used scipy.optimizers.minimize
function (with SLSQP
method)
to minimize the Mean Squared Error function. There are two more methods defined in the
models viz. TRUST_CONSTR
and COBYLA
but they are not supported atm to keep things
simple and avoid over engineering for a plain use case.
The repository contains three parts:
controller
: It contains the core logic of the application.models
: It contains standard pydantic/enum models used across the code.views
: It provides interface to end users to interact with the code. Currently there are two interfaces viz. a terminal basedsrc/views/terminal.py
and a file basedsrc/views/file.py
.
v.0.1.0
- first working release.