Buy 10 of 25 stocks?

My ranking system gives roughly the same return if I choose to have 20 or 10 stocks in my portfolio, while in my live portfolio I want to limit myself to 10 stocks.

Is it possible to create a buy rule that selects the 20 shares that are of the highest rank, but then within these 20 , select the 10 stocks with, e.g.:

  • lowest VolM%ShsOut or
  • highest Rating (“Core: Sentiment”) or
  • lowest Correl or
  • lowest #AnalystsCurFY or
  • lowest Pr4W%Chg

In other words, the first 20 stocks are chosen by the ranking system, but then there are more mechanical rules that choose the 10 best of the 20 that the ranking system has chosen.

I don’t know if this can be done with a combination “Rankpos” with a “Frank(”? , or is it even possible to use a Frank in the simulation?

RankPos < 20 and FRank (“Pr4W%Chg”, #previous, #asc ) > 50

Maybe you could use the Portfolio() function?

In the port with 10 holdings, rank by your secondary factor and use Portfolio() as a buy rule.

I haven’t tried this, so it may not work as I expect. Also the Portfolio() doc seems whacked (i.e. it describes the Account() function).

Hi,

I do not do this myself. But that is only because I always just want the highest-ranked stocks. I have considered doing this with Zacks as there are an abundance Zacks Rank #1 stocks to chose from. And you do not have to buy all of them and there are enough of them that you would not have to buy equal weights of all of them—the ones with higher weights could be controlled so as not to affect liquidity by controlling the total number of stocks selected.

And you mentioned Correlation.

So, if it were me I would probably run 20 stocks through Portfolio Visualizer and select the minimum -variance portfolio of the stocks you are considering (using a 3-month look-back period).

You may not get 10 stocks (out of 20) with this. Minimum-variance can select highly concentrated portfolios. I would then go back and include the stocks selected with minimum variance and add enough additional stocks to to get a total of 10 and run a risk parity portfolio. This will give you ten, You can combine the 2 recommended weights in whatever way you want.

But if you are truly interested in the correlations—without any additional information about how the 20 stocks might perform—this will be the nearly-optimal way to address correlations. And maybe the easiest way in the end.

At Zacks and P123 you could also just take the 10 stocks with the most momentum and weight them using risk-parity. I think momentum can work (sometimes) but people overweight momentum (getting a portfolio with too much risk and high drawdowns). Mixing momentum with risk-parity can work sometimes in my experience—by not overweighting a few high-flying stocks, especially in a drawdown.

You could also use sector-momentum and risk-parity—especially with Zacks because of the huge number of choices at Zacks. I have not backtested this but you are guaranteed to get diversification if set up properly. And some of this could be backtested with Python (not Zacks probably). And easier with ETFs which I have done (and doing).

I think an excellent programmer (which does not describe me) could backtest this with stocks.

Jim

How would you backtest such an idea? Is it possible in P123?

I’m not sure if I got the problem right, but maybe shifting your current Rank into ratingPos() < 20 and use a new rank with your mentioned metrics could do this.

HI,

P123 may be working, some, on risk parity: MVP….

But I think it would be hard now.

With something from P123 (API) you could download the stock returns and a matrix of which stocks your sim selects each week. Then it would not really be THAT hard to loop through PyPortfolioOpt to select a risk parity portfolio (or minimum-variance) portfolio from those stocks. And the returns could be calculated from your downloaded returns and plotted with Python.

Admittedly easier with ETFs which I limit myself to now.

I will add that this is really what Korr MAY be asking for in the above link, although he may have some additions or qualifications in what he wants. And I do not know where P123 should put this in their priorities (I am not really asking for it to be a priority). But not a bad think to wish for.

BTW, at one time IB did this with their backtests. I am not honestly sure whether they have a backtest option now, however. It did seem to help when I played with it.

FWIW, I may get time to shrink the expected returns for ETFs using PYMC in Python (a Bayesian Package) and loop through PyPortfolioOPT (using shrunken Ledoit-Wolf convince matrix and the Bayesian expected returns) to get the maximize-Sharpe-Ratio weighing for the next month (with a look-back period to be determined).

Returns are too volatile to use the historical returns without Bayesian methods for sure, I think. Many agree in the literature.

For ETFs it can be tested using walk-forward validation, probably, even by a mediocre programmer. Some of this can be run through Portfolio Visualizer to get the pretty graphics and their metrics.

This is a well-accepted method. ChatGPT likes it too. But I can’t say it works yet. Big maybe.

Jim

Like this?

Creat a new rankingsystem:

image

Make this main system in the simulation that is running with 10 stocks:

image

And make the ranking that normally chooses 20 stocks run like this:

image

“RatingPos(“270523 M AAA - sette mapper til 0 - Copy(2)”) < 20”

That gave me some weird results from my original 25 stock system:

image

to the new:

image

Is this: “RatingPos(“270523 M AAA - sette mapper til 0 - Copy(2)”) < 20”, wrong?, or maybe I have to use this as a sell rule “RatingPos(“270523 M AAA - sette mapper til 0 - Copy(2)”) > 20”

Or, Rating("RatingPos(“270523 M AAA - sette mapper til 0 - Copy(2)”) > 98

You have also to replace your Sell-Rule “Rank<90” by Rating(“270523 M AAA - sette mapper til 0 - Copy(2)”)<90. The new Buy-Rule looks fine. With this change you “re-constructed” your old sim (if you have an equal weighted sim). The new Ranking System can now only choose stocks within the 20 stocks according to your new Buy-Rule.

Great, this seems to be what I was looking for! But the simulation runs extremely slowly. Is that normal?

Yes, unfortunately whenever you use rating() or ratingPos().

Thanks for all the feedback ! :slight_smile:

I have tested various approaches how to select 10 of the 20 stocks that my original ranking system selected. It wasn’t impressive.

I have tried to adjust factorrank, so that the turnover is the same in the various simulations.

The main strategy gives 49.1% annual return.

The only factor that slightly increased the return was low small cap:

This is a test over a long period, but with few stocks, so the fact that smallcap improved returns may also be due to chance which is difficult to replicate,

Do anyone else have any ideas, what to test? How to find the best 10 of the 20 stocks that are the highest ranked.

Here is the result by running some of the same tests in my European rankingsystem:

What surprised me is that I get results that are different from insider data. I didn’t think it was inside data on Europe?

Otherwise, when I see the two together I was surprised that 4w high was much better than 4w low, and that near 4w=0 did not make it better. However, it seems that it is low Mktcap and inside ownership that is the best.

In Europe, it is subindustry momentum and 4w high that is the best.