I'm trying to build a Capped Index Fund of crypto currencies. As Investopedia explains, a "Capped index is an equity index that has a limit on the weight of any single security. Thus, a capped index sets a maximum percentage on the relative weighting of a component that is determined by its market capitalization. The rationale behind a capped index is to prevent any single security from exerting a disproportionate influence on an index."

I need an algorithm or a spreadsheet that calculates the capped weightings of the currencies. Page 6 of Morningstar Index Calculation Methodology seems to discuss the formulas I need to calculate the capped weightings but I'm having trouble translating these into an code.

As I think about the algorithm needed, it seems some sort of nested or recursive loop would be necessary. Every time the weighting of one currency is capped, the weightings of the remaining currencies need to go up proportionally. Perhaps this could be accomplished by recursively calling the capping algorithm on the remaining currencies with a modified cap for each recursive call. Or maybe I'm confused and over thinking it.

Here's a spreadsheet based on my first attempt to solve this.

Is anyone aware of some sample code or a spreadsheet that accomplishes this? Anyone want to take a crack as some pseudo code?

Many thanks.


2 Answers 2


I figured it out! See the second tab of my spreadsheet for the solution.

And for what it's worth, here's my Java code. No recursion needed!

final double totalMarketCap = filteredTickers.stream().mapToDouble(ticker -> ticker.getMarketCapUSD().doubleValue()).sum();
double cappedRemaining = 1d;
double marketRemaining = 1d;
for (CoinMarketCapTicker ticker : filteredTickers) {
    double marketPercentage = ticker.getMarketCapUSD().doubleValue() / totalMarketCap;
    double uncappedPercentage = marketPercentage * cappedRemaining / marketRemaining;
    double cappedPercentage = Math.min(uncappedPercentage, _indexCap);

    _indexTickers.add(new IndexTicker(ticker, marketPercentage, cappedPercentage));

    marketRemaining -= marketPercentage;
    cappedRemaining -= cappedPercentage;
  • $\begingroup$ could you please reply with the link to Morningstar Index Calculation Methodology? Link in a questions points me to Morningstar Indexes Website. Thanks $\endgroup$
    – user38932
    Commented Feb 22, 2019 at 23:57
  • $\begingroup$ Hmm. I guess it was removed. You could try an archive site like Wayback Machine. $\endgroup$
    – Corey
    Commented Feb 24, 2019 at 0:27
  • $\begingroup$ How would you you calculate the base value of the index? $\endgroup$
    – user38932
    Commented Feb 27, 2019 at 20:47
  • $\begingroup$ You need a source of market caps like CoinMarketCap.com. $\endgroup$
    – Corey
    Commented Mar 1, 2019 at 0:48
  • $\begingroup$ here's Edu writing from 2021! I'm interested on the google sheet you made, and update it to create an index for crypto in 2021. Can I get an editable version of the document? I will be much appreciated. my email: [email protected] THX so much! $\endgroup$
    – Edu Forte
    Commented Apr 9, 2021 at 20:37

I think it can be done iteratively.

For each security you need a boolean variable Capped which is 1 if the security is currently at its cap or 0 otherwise. Initially Capped[i]=0 for all securities i and initially Weight[i]=the market value based weight of security i.

Then you go onto a loop:

You set Finished to TRUE

First you examine all uncapped securities and if Weight[i]> Cap you set Weight[i]=Cap; Capped[i]=1 and Finshed=FALSE

Second you compute the free (or uncapped) weight, which is equal to 1 minus the sum of the weights of the capped securities.

Third for all uncapped securities, you assign them a weight proportional to their market value and such that their sum is equal to the free weight computed in step 2.

If FINSHED=FALSE (meaning that some security was capped in this iteration) you go back to the top of this loop, else you exit this loop.

(A word of warning, however, this pseudo-code has not been debugged).

  • $\begingroup$ Thanks for the suggestion! I think that would work. But I like my solution. :) $\endgroup$
    – Corey
    Commented May 16, 2018 at 3:44

Not the answer you're looking for? Browse other questions tagged or ask your own question.