Hi, I have tweaked the code you provided in the course, and it seemd to work until the "redistribute_weights" function is used to set a weight limit to my problem. Then my kernel dies when I run the formula.
This is the tweaked code used for the formula:
def redistribute_weights(data, weight_limit=0.10):
"""
Code to redistribute weights between funds.
"""
"""Check if weight redistribution is possible"""
# Get the total number of funds available
num_funds = len(data.index)
# Calculate the minimum number of funds needed for the given weight_limit
num_funds_needed = int(1 / weight_limit)
# Proceed if sufficient funds are available
if (num_funds >= num_funds_needed):
# Sort the dataframe to get the fund with maximum weight
data = data.sort_values(by=data.columns.to_list(), ascending=False)
# Base case
# If fund with maximum weights is less than or equal to the
# weight_limit, return data
if data.iloc[0][0] <= weight_limit:
data.rename(columns={"Original": "New"}, inplace=True)
return data
# If fund with maximum weights is greater than the weight_limit,
# reassign weights
if data.iloc[0][0] > weight_limit:
# Calculate excess weight
excess_weight = data.iloc[0][0] - weight_limit
# Assign weight_limit to fund with excess weight
data.iloc[0][0] = weight_limit
# Calculate ratio of distribution of excess weight
ratio = (data.iloc[1:] / data.iloc[1:].sum())
# Distribute excess weight
excess_weight_distribution = data.iloc[1:] + (ratio * excess_weight)
# Update the weights
data.iloc[1:, :] = excess_weight_distribution
return redistribute_weights(data)
else:
print(
f"Weight redistribution is not possible. Add {num_funds_needed - num_funds} more funds or reduce the weight limit to {round(1 / num_funds, 2)}.")
return data
And this is the code that causes the kernel to die:
# Calculating the new weights after redistribution
new_weights = redistribute_weights(weights, weight_limit=0.10)
Can you help me please?
Thanks!
Luca
Hello Luca,
I ran the 'redistribute_weights' function you have shared in my local system and it gave me new weights without any kernel issues.
Can you share your 'weights' CSV file? I will try running the 'redistribute_weights' function on the 'weights' CSV file in my local system and check if the issue exists.
Thanks
Hello Varun,
I have tried to re-run the same function with a new weight limit equal to 0.15 on a portfolio of 7 assets, and I am experiencing the same issue again. The weights used are stored in a DataFrame and are:
weights_hrp =
CDF: 0.07
MTR: 0.09
NAF: 0.04
SEB: 0.12
ADT: 0.06
AEA: 0.03
BSF: 0.6
These are "re-tickerized" funds, not stocks tickers.
And this is the function code snippet:
def redistribute_weights(data, weight_limit=0.15):
"""
Code to redistribute weights between stocks.
"""
"""Check if weight redistribution is possible"""
# Get the total number of stocks available
num_stocks = len(data.index)
# Calculate the minimum number of stocks needed for the given weight_limit
num_stocks_needed = int(1 / weight_limit)
# Proceed if sufficient stocks are available
if (num_stocks >= num_stocks_needed):
# Sort the dataframe to get the stock with maximum weight
data = data.sort_values(by=data.columns.to_list(), ascending=False)
# Base case
# If stock with maximum weights is less than or equal to the
# weight_limit, return data
if data.iloc[0][0] <= weight_limit:
data.rename(columns={"Original": "New"}, inplace=True)
return data
# If stock with maximum weights is greater than the weight_limit,
# reassign weights
if data.iloc[0][0] > weight_limit:
# Calculate excess weight
excess_weight = data.iloc[0][0] - weight_limit
# Assign weight_limit to stock with excess weight
data.iloc[0][0] = weight_limit
# Calculate ratio of distribution of excess weight
ratio = (data.iloc[1:] / data.iloc[1:].sum())
# Distribute excess weight
excess_weight_distribution = data.iloc[1:] + (ratio * excess_weight)
# Update the weights
data.iloc[1:, :] = excess_weight_distribution
return redistribute_weights(data)
else:
print(
f"Weight redistribution is not possible. Add {num_stocks_needed - num_stocks} more stocks or reduce the weight limit to {round(1 / num_stocks, 2)}.")
return data
Then, when I run the following line of code I got the error killing my kernel:
# Calculating the new weights after redistribution
new_weights = redistribute_weights(weights_hrp, weight_limit=0.15)
It tells me: "
The kernel appears to have died. It will restart automatically."
Can you please help me?
Luca
Hello Luca,
The code has been updated in the course and with the updated code, you will be able to generate new weights for your HRP portfolio. You can find the code here.
Here is the output for your data with re-assigned weights.
Here is an observation of the result.
As you can see, the first six contracts have maximum weightage allowed and the rest was allocated to 'AEA'. This is (almost) equal weightage allocation. So, this negates the purpose of using HRP for weight allocation.
Hence, in your case, if you want to retain the HRP weights and maintain an optimum portfolio, you can't have the weights limitation of 15%.
Hope this helps!