Skip to content

Commit 1e8f28a

Browse files
committed
refactor: update percentage validation logic in Portfolio model
1 parent 8be408d commit 1e8f28a

File tree

1 file changed

+6
-50
lines changed

1 file changed

+6
-50
lines changed

src/models/portfolio.py

Lines changed: 6 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
a structured investment portfolio recommendation.
66
"""
77

8-
import math
98
from enum import Enum
109
from typing import List
1110

@@ -98,55 +97,12 @@ class Portfolio(BaseModel):
9897
},
9998
)
10099

101-
# @model_validator(mode="after")
102-
# def validate_total_percentage(self):
103-
# """Validate that asset percentages sum to approximately 100."""
104-
# total = sum(asset.percentage for asset in self.assets)
105-
# if not (99 <= total <= 101):
106-
# raise ValueError(
107-
# f"Asset percentages must sum to 100%, got {total}% instead"
108-
# )
109-
# return self
110-
111-
# TODO: completare nuova versione del model validator e eliminare la vecchia qui sopra
112100
@model_validator(mode="after")
113-
def normalize_total_percentage(self):
114-
"""
115-
Auto-correct asset percentages to ensure they sum to exactly 100%.
116-
Instead of raising an error, specifically re-proportions the values.
117-
"""
118-
if not self.assets:
119-
return self
120-
101+
def validate_total_percentage(self):
102+
"""Validate that asset percentages sum to approximately 100."""
121103
total = sum(asset.percentage for asset in self.assets)
122-
123-
# Se il totale è 0, non possiamo normalizzare (evitiamo divisione per zero)
124-
if total == 0:
125-
# In questo caso estremo, assegniamo tutto al primo asset o lanciamo errore
126-
# Qui scegliamo di distribuire equamente per non rompere l'app
127-
share = 100.0 / len(self.assets)
128-
for asset in self.assets:
129-
asset.percentage = round(share, 2)
130-
return self
131-
132-
# Se la somma è già corretta (con tolleranza), non facciamo nulla
133-
if 99.0 <= total <= 101.0:
134-
return self
135-
136-
# LOGICA DI NORMALIZZAZIONE
137-
# Esempio: Se il totale è 60%, il fattore è 100/60 = 1.666...
138-
factor = 100.0 / total
139-
140-
for asset in self.assets:
141-
# Scaliamo ogni asset
142-
asset.percentage = round(asset.percentage * factor, 2)
143-
144-
# Controllo finale per arrotondamenti (es. somma 99.99 o 100.01)
145-
new_total = sum(asset.percentage for asset in self.assets)
146-
diff = 100.0 - new_total
147-
148-
if diff != 0:
149-
# Aggiungiamo/togliamo la piccola differenza al primo asset (spesso il più grande)
150-
self.assets[0].percentage = round(self.assets[0].percentage + diff, 2)
151-
104+
if not (99 <= total <= 101):
105+
raise ValueError(
106+
f"Asset percentages must sum to 100%, got {total}% instead"
107+
)
152108
return self

0 commit comments

Comments
 (0)