 ().
I.
Let me run through each entry and hopefully clarify them somewhat:
Firstly, as we will be using the ‘SLSQP’ method in our “minimize” function (which stands for Sequential Least Squares Programming), the constraints argument must be in the format of a list of dictionaries, containing the fields “type” and “fun”, with the optional fields “jac” and “args”.
How can I plot AAPL, MSFT, GOOGL portfolios with 1 individually to see their individual risk and return?
If just considering one single stock I guess the risk and return would just be the historic CAGR and the annualised standard deviation of the stock returns no?
Hi,
I have many difficulties to introduce the “Short” possibility. I can’t find how to tel to the program that weights can take value between -1;1
Can You help me ?
Hi there, it depends whether you are working with the monte carol style random portfolio method, or the method using the scipy “optimize” approach. Which one are you trying yo implement please?
Hi,
Is it possible to include dividends on returns?
Thanks,
Thank you S666 for another solid piece of financial code in Python! I really like your professional, storytelling-like approach for optimisation and previous topic.
Dear Mandar,
There have been some changes in ‘data reader’ library.
You can use this piece of code a modify accordingly:
import library
import pandas_datareader as pdr
.
cme = pdr.get_data_stooq(‘CME’, start, end)
I hope you will find this helpful.
Piotr
Hi and thank you for sharing this!
I have two questions for which your advice would be much appreciated:
1. How can I provide my own historical data from a csv or spreadsheet file instead of reading from on online source?
2. What happens if the starting date of the timeseries of the securities/instruments used is not matching?
e.g. let’s say that one instrument starts only in 2010 while another starts in 2005. How will the return calculations and the correlation matrix take this into account?
Keep up the good work!
Best,
AK
Impressive work! Thanks for the intellectually stimulating content. In the calculation of the portfolio standard deviation, where do you factor the multiplication of the constant ‘2’ in the calculus?
I remember it now, deriving the formula for modern portfolio theory. Thanks for the impressive work.
You should to a youtube video on this!!!
Hi Greg,
I think you are right, it seems there is a small mistake regarding the annualization of the returns. Multiplying by 252 is only right if we’re dealing with log returns but it’s not the case here.
Anyway, it’s a great and inspiring article
wow i did not get any notification for you reply.. haha.. i just saw it. is there a way to add shorting for only selected securities?
Thanks for the great post!
It would also be nice if you can update the code adding a constraint for minimum % holding position and a max % holding position. I.e. the max you can allocate for each stock is 20%..
Thanks much!
You look like a remarkable dad! That is a tremendous accomplishment!! Congrats!!
In what way am I a remarkable dad? I’m sorry, Im not understanding…
Excellent analysis. You obviously have a deep understanding of finance and programming. I am just starting with programming and I want to deepen my knowledge in data analysis and financial analysis. This helped me a lot. Thank you so much for sharing it.
Hello Stuart,
I’m trying to follow this amazing investment tutorial/Python-code, and in my PC (Linux/Python 3.6.9), it runs well till it reaches the “localization of the portfolio with minimum VaR” (after the random portfolios simulation). It fails there with the following error code:
“/home/ni/.local/lib/python3.6/site-packages/pandas/core/indexing.py”, line 1493, in _getitem_axis
raise TypeError(“Cannot index by location index with a non-integer key”)
Have you, or any of the people on this forum, had this issue?
Thank you for your time,
Gus
Hi Gus – I assume you are referring to the line that reads:
#locate positon of portfolio with minimum VaR
min_VaR_port = results_frame.iloc[results_frame[‘VaR’].idxmin()]
The error message is telling you that you are trying to use a label based key but the method you are using only accepts an integer as an index key.
You notice the use of “.iloc” – the i stands for “integer” and the loc stands for “location” – using “iloc” requires that you pass it an integer, which seemingly you are not.
Either you have made a typo and used an integer key with “.loc” (notice the lack of i) which only accepts label based keys, or vice versa you are using a label with iloc.
Hopefully that makes sense – let me know if you cant resolve it 😉
Hi Stuart,
thank you for your comments.
(I understand the “panda-restrictions” about the “i.loc”.)
Anyway, I started from scratch, and got (not null) values for VaR (results_frame).
So, the “min-VaR_port” calculation run without complains.
Regards,
Gus
Hey Stuart,
Hats off for this superb article. It is a pleasure to read for someone who isn’t as proficient in Python yet, because the explanations for the different lines of code are extremely helpful.
I just have a few issues when running the code. I am trying to do the exact same thing as you do in the first approach but with 24 different stocks. Everything runs fine except for the fact that my graph looks off and it doesn’t have the typical minimum variance frontier. I am not able to post a picture here so it might be difficult to illustrate, but basically my graph looks more like a circle with the different portfolio points. Any guess what the problem could be?
Your help would mean a lot.
Cheers,
Youri
If you would like to post your code here I am happy to take a look. If possible try to get it correctly formatted as python code by wrapping it with:
<_pre lang="python"_>
</pre>
at the start and end – NOTE: DONT include the underscores at the start and end of each line -I have just added them to allow the actual wrappers to be visible and not changed into HTML themselves…
Hello,
I have actually been working on it since my original post and it now looks a lot better. The frontier is visible. My guess is that it was due to the fact that too many ‘Adj. Close’ values were missing (probably because I didn’t choose the correct ticker), which I then replaced using a simple Forward Fill.
I do have a different question though, related to the individual stock weights. Is it possible to cap the weights at 8% so that no stock is attributed more than that and further that the excess weight is then evenly distributed to other stocks. If yes, how can I implement this using the code you provided.
I know this question has been asked under a different article of yours, but I couldn’t find the answer yet.
Thank you very much for taking the time to help out.
Cheers,
Youri
Hi Youri – A very quick way to do it would be to change you “bounds” within the “max_sharpe_ratio” function. Change it from “bound = (0.0,1.0)” to “bound = (0.0,0.08)”.
That will set an upper bound of 8% on each holding. I’m not certain the outcome will be EXACTLY as it would be if you strictly followed the method of “evenly distributing to other stocks” but this will get you closer to what could be considered “mean-variance” efficient, with your required upper bound of 8%.
Hope that helps.
Hi Stuart,
Thanks a lot, it worked!
Cheers,
Youri
The weights are not between the range -1 and 1…
Do you have another solution?
Honestly, I am not even sure if it can be done – and if it can, it is by no means a trivial problem when negative weights are allowed and then also must be forced to sum to 1.0. I have played around and there are solutions where by there are only positive weights of individual stocks which can sum to 1.0 of course.
There are also solutions whereby negative weights are allowed but the result sums to equality, i.e. zero. This problem is really solved by allowing a portion of the weights to be determined by the values of the earlier weights, hence is no longer “random” in the true sense.
I’ve hacked together something, although I am not certain it is really fit for purpose. here it is anyway as you may find it helpful:
//
//
That will produce a list of floating point numbers between -1 and 1 that all sum to 0.0.
If you really want it to sum to 1 then the only thing I can think of on the spot is to then just iterate over the numbers and adjust them accordingly, by adding 1/n to each of them. However this risks pushing some of the values up above the 1.0 threshold so you may want to come up with your own adjustment method.
Just be reminded this is a pretty horrible hack and you may well find that when run through a large number of simulations the numbers that are produced end up being skewed massively one way or another and the lack of randomness is revealed. Best I can do just for now I am afraid.
Hello S666,
let’s imagine we would like to implement a buy and hold strategy for the above portfolio (tickers = [‘AAPL’, ‘MSFT’, ‘NFLX’, ‘AMZN’, ‘GOOG’]), based on the weighting of the Maximum Sharp Ratio portfolio.
How would the code look like?
Best
Nicole