0

Given a lower bound of 0.025, I want a vector consisting of weights that sum up to 1 and satisfy this lower bound. Starting from a vector with an arbitrary length and the values ranging from 0.025 (lower bound) to 1.

For example,

[0.025, 0.8, 0.7]

Then a normalization where you divide by the sum of the numbers gives you roughly the following:

[0.016, 0.524, 0.459]

Now this does not satisfy the lower bound, any ideas on how I can get this to work?

  • When you say "then a normalization", what do you mean exactly? Now it seems like you say you want to divide each element by the sum of all elements, which does not really make sense to me. – Andre Sep 30 '21 at 20:31
  • The objective is to get weights that sum up to 1 while satisfying the lower bound. A normalization method does not work on this. Weights do end up summing to 1, but the lower bound is not satisfied. – Jaques duBalzac Sep 30 '21 at 20:56

2 Answers2

2

If you want the weights (values in an array) to sum up to 1, you can divide each value by the sum of all values (i.e. normalize by the sum). This procedure keeps the relative sizes of each pair of values I means: before and after the step, the second item will be 5 times as large as the fourth item.

On the other hand you want all values to be larger than 0.025. Imagine if one item is 50 times larger than another before normalization, and the smallest value must be 0.025, the other item would need to be 1.25, which is already larger than the sum has to be.

You can figure out that you cannot (given any array) just scale all values equally so that they sum up to 1 AND the smallest value is 0.025.

Then the question is what relation between the values do you want to keep in the procedure?

As a side not, you cannot have more than 40 items, all bigger than 0.025, summ up to 1. So "arbitrary length" just cannot work either.

Andre
  • 760
  • 3
  • 13
0

Add the lower bound to the dividend and divisor:

I used numpy for readability:

import numpy as np

v = np.array([0.025, 0.8, 0.7])

v2 = (v + min(v)) / sum(v + min(v))

Output:

>>> v2
array([0.03125 , 0.515625, 0.453125])

>>> sum(v2)
1.0
Corralien
  • 109,409
  • 8
  • 28
  • 52
  • For this example it seems to work. However, when evaluating the following code I do obtain values below the min_weight, which is set at 0.025; weights = np.random.rand(len(assets)), normalized_weights = (weights + min_weight) / sum(weights + min_weight), print(normalized_weights), where len(assets) is 33. – Jaques duBalzac Sep 30 '21 at 20:50