|
5 | 5 | a structured investment portfolio recommendation. |
6 | 6 | """ |
7 | 7 |
|
8 | | -import math |
9 | 8 | from enum import Enum |
10 | 9 | from typing import List |
11 | 10 |
|
@@ -98,55 +97,12 @@ class Portfolio(BaseModel): |
98 | 97 | }, |
99 | 98 | ) |
100 | 99 |
|
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 |
112 | 100 | @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.""" |
121 | 103 | 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 | + ) |
152 | 108 | return self |
0 commit comments