Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looking for some guidance on combinatorics in python

Still new to python and coding, only about 6 weeks into this adventure. I started a finance project to try and figure out what % of the portfolio should be in cash, and how much should be invested based on the current market performance. No idea if this research will have any relevance but it has been helpful getting stuck on every step and learning new things.

For anyone interested, this is the google collab Jupiter notebook https://github.com/Jakub-MFP/My_FIRE_Project/blob/master/portfolio_management/cashposition_backtest.ipynb

In Step 4, I am trying to run sorta a combinatorics simulation. I have been reading up on https://docs.python.org/3/library/itertools.html but it's a little overwhelming on where I need to get started. Just looking for some guidance on like what the terms or stuff I should be looking into, to solve this specific question.

Also, looked and saw something called tpot was good for combinatorics?

Combinatorics Question

Currently, in Step 3, I did a predefined loop for the various drops in the market. It looked like this

   if (current_market_status == 0):  # all time high record
        current_cash_required_equity = 0.3
    elif (current_market_status < -0.05): #less than 5%
        current_cash_required_equity = 0.25
    elif (current_market_status < -0.10): #less than 10%
        current_cash_required_equity = 0.20 
    elif (current_market_status < -0.15): #less than 15%
        current_cash_required_equity = 0.15
    elif (current_market_status < -0.20): #less than 20%
        current_cash_required_equity = 0.10
    elif (current_market_status < -0.25): #less than 25%
        current_cash_required_equity = 0.05
    elif (current_market_status < -0.30): #less than 30%
        current_cash_required_equity = 0

Now what I would like to do is try every combination for market status between 0.50 and -0.50 incremented by 0.01. For each market status to try a cash position between 0.50 and 0.

Should I set a limit to try only like 5 elif settings? Or is there a way to do a more combinatoric way?

I setup this for options

options_market_status = [0.50,0.49,0.48,0.47,0.46,0.45,0.44,0.43,0.42,0.41,
                         0.40,0.39,0.38,0.37,0.36,0.35,0.34,0.33,0.32,0.31,
                         0.30,0.29,0.28,0.27,0.26,0.25,0.24,0.23,0.22,0.21,
                         0.20,0.19,0.18,0.17,0.16,0.15,0.14,0.13,0.12,0.11,
                         0.10,0.09,0.08,0.07,0.06,0.05,0.04,0.03,0.02,0.01,0,
                         -0.50,-0.49,-0.48,-0.47,-0.46,-0.45,-0.44,-0.43,-0.42,-0.41,
                         -0.40,-0.39,-0.38,-0.37,-0.36,-0.35,-0.34,-0.33,-0.32,-0.31,
                         -0.30,-0.29,-0.28,-0.27,-0.26,-0.25,-0.24,-0.23,-0.22,-0.21,
                         -0.20,-0.19,-0.18,-0.17,-0.16,-0.15,-0.14,-0.13,-0.12,-0.11,
                         -0.10,-0.09,-0.08,-0.07,-0.06,-0.05,-0.04,-0.03,-0.02,-0.01
                    ]


options_cash_req = [0.50,0.49,0.48,0.47,0.46,0.45,0.44,0.43,0.42,0.41,
                         0.40,0.39,0.38,0.37,0.36,0.35,0.34,0.33,0.32,0.31,
                         0.30,0.29,0.28,0.27,0.26,0.25,0.24,0.23,0.22,0.21,
                         0.20,0.19,0.18,0.17,0.16,0.15,0.14,0.13,0.12,0.11,
                         0.10,0.09,0.08,0.07,0.06,0.05,0.04,0.03,0.02,0.01,0
                    ]

So the rules for the combinatorics would be like

  1. For every market status, to try cash req from highest to lowest
  2. First if the statement is 0.50 then the next one can only be 0.5 - 0
  3. Second if the statement lets say is 0.45, then the next one can only be 0.45 - 0

Like if the market status is 0, and we need to required 50% cash. Then it drops 5%, and we now require 40% cash. Then it drops 5% more to be down -10%, we can only require between 40% and 0% cash. We can't increase our cash required if the market drops only to keep it the same or drop it. The idea is the more the market is discounted, the less cash we should keep on the side. So we should invest more the cheaper the market is, and invest less the higher the market goes. This whole simulation starts with 10,000 and has 1,000 added to portfolio each month.

Thank you in advance to anyone that has taken the time to read this post and posted a link to some documentation or words of advice on how I can go about learning how to figure this out.

like image 907
Jakub Avatar asked Nov 07 '22 04:11

Jakub


1 Answers

I didn't understand the question, I think you assume familiarity with some concepts here. If you can phrase your question more simply and shortly it would help me help you. Then again it might be only my inability.

I will try to give you my 2 cents, according to what you I can understand from the post.

First of all, I would like to point out that the way you initialized your lists is not optimal. Numpy has two very important functions:

  1. np.linspace: https://numpy.org/doc/stable/reference/generated/numpy.linspace.html

  2. np.arange: https://numpy.org/doc/stable/reference/generated/numpy.arange.html

So for example, you should replace your options_market_status initialization with the simple one-liner numpy call: np.arange(0.5, -0.02, -0.01).

Now, if I understand your main question, it is how to iterate over options_market_status and options_cash_req, such that the element from options_market_status is bigger or equal to the options_cash_req option, right? Since they have the same values in your question, I will give a general solution. If we are given an array a, and want to iterate over it in a nested loop, one solution can be:

a = np.arange(0.5, -0.01, -0.01)
for i in range(len(a)):
    first_element = round(a[i], 2) # this is the 1st element, rounded to 2 digit
    for j in range(i, len(a)):
        second_element = round(a[j], 2) # same with 2nd element
        print(first_element, second_element) # you can replace this with your function

I hope I understood you question correctly, and haven't explained things which you already know. Good luck!

like image 145
yonatansc97 Avatar answered Nov 14 '22 23:11

yonatansc97