revert: restore original portfolio allocation logic

This commit is contained in:
Pascal BIBEHE 2025-05-27 23:53:08 +02:00
parent 57862a1e98
commit 1fc54d5ea9

View File

@ -473,11 +473,6 @@ def optimize_portfolio_allocation(etf_metrics: List[Dict[str, Any]], risk_tolera
logger.info(f"Optimizing portfolio allocation for {risk_tolerance} risk tolerance") logger.info(f"Optimizing portfolio allocation for {risk_tolerance} risk tolerance")
logger.info(f"ETF metrics: {etf_metrics}") logger.info(f"ETF metrics: {etf_metrics}")
# Calculate risk scores for each ETF
for etf in etf_metrics:
etf['risk_score'] = calculate_etf_risk_score(etf)
logger.info(f"Risk score for {etf['Ticker']}: {etf['risk_score']:.2f}")
# Sort ETFs by yield (higher yield = higher risk) # Sort ETFs by yield (higher yield = higher risk)
sorted_etfs = sorted(etf_metrics, key=lambda x: x.get('Yield (%)', 0), reverse=True) sorted_etfs = sorted(etf_metrics, key=lambda x: x.get('Yield (%)', 0), reverse=True)
logger.info(f"Sorted ETFs by yield: {[etf['Ticker'] for etf in sorted_etfs]}") logger.info(f"Sorted ETFs by yield: {[etf['Ticker'] for etf in sorted_etfs]}")
@ -489,29 +484,55 @@ def optimize_portfolio_allocation(etf_metrics: List[Dict[str, Any]], risk_tolera
if risk_tolerance == "Conservative": if risk_tolerance == "Conservative":
# For conservative, allocate more to lower yielding ETFs # For conservative, allocate more to lower yielding ETFs
# This will require more capital to achieve the same income # This naturally requires more capital for the same income
base_allocations = [0.4] + [0.3] + [0.2] + [0.1] + [0.0] * (num_etfs - 4) base_allocations = []
remaining_alloc = 100
for i in range(num_etfs):
if i < num_etfs - 1:
# Allocate more to lower yielding ETFs
alloc = remaining_alloc * 0.4 # 40% of remaining
base_allocations.append(alloc)
remaining_alloc -= alloc
else:
# Last ETF gets remaining allocation
base_allocations.append(remaining_alloc)
elif risk_tolerance == "Moderate": elif risk_tolerance == "Moderate":
# For moderate, balance between yield and risk # For moderate, allocate more to middle yielding ETFs
base_allocations = [0.3] + [0.3] + [0.2] + [0.2] + [0.0] * (num_etfs - 4) # This naturally requires medium capital for the same income
base_allocations = []
remaining_alloc = 100
for i in range(num_etfs):
if i < num_etfs - 1:
# Allocate more to middle yielding ETFs
alloc = remaining_alloc * 0.5 # 50% of remaining
base_allocations.append(alloc)
remaining_alloc -= alloc
else:
# Last ETF gets remaining allocation
base_allocations.append(remaining_alloc)
else: # Aggressive else: # Aggressive
# For aggressive, allocate more to higher yielding ETFs # For aggressive, allocate more to higher yielding ETFs
# This will require less capital to achieve the same income # This naturally requires less capital for the same income
base_allocations = [0.4] + [0.3] + [0.2] + [0.1] + [0.0] * (num_etfs - 4) base_allocations = []
remaining_alloc = 100
# Adjust allocations based on number of ETFs for i in range(num_etfs):
if num_etfs < len(base_allocations): if i < num_etfs - 1:
base_allocations = base_allocations[:num_etfs] # Allocate more to higher yielding ETFs
# Normalize to ensure sum is 1 alloc = remaining_alloc * 0.6 # 60% of remaining
total = sum(base_allocations) base_allocations.append(alloc)
base_allocations = [alloc/total for alloc in base_allocations] remaining_alloc -= alloc
else:
# Last ETF gets remaining allocation
base_allocations.append(remaining_alloc)
# Create final allocation list # Create final allocation list
final_allocations = [] final_allocations = []
for etf, allocation in zip(sorted_etfs, base_allocations): for etf, allocation in zip(sorted_etfs, base_allocations):
final_allocations.append({ final_allocations.append({
"ticker": etf["Ticker"], "ticker": etf["Ticker"],
"allocation": allocation * 100 # Convert to percentage "allocation": allocation # Already in percentage
}) })
logger.info(f"Final allocations: {final_allocations}") logger.info(f"Final allocations: {final_allocations}")
@ -1217,7 +1238,7 @@ def allocate_for_income(df: pd.DataFrame, target: float, etf_allocations: List[D
logger.error("Weighted yield is zero") logger.error("Weighted yield is zero")
return None return None
# Calculate required capital # Calculate required capital based on weighted yield
required_capital = (annual_income / weighted_yield) * 100 required_capital = (annual_income / weighted_yield) * 100
# Calculate capital allocation and income # Calculate capital allocation and income