Benjamin-eecs/openrsi-commit-runtime-assets
0168
1diff --git a/casparser/parsers/cdsl.py b/casparser/parsers/cdsl.py2index ae5dfb8..2ce58e8 1006443--- a/casparser/parsers/cdsl.py4+++ b/casparser/parsers/cdsl.py5@@ -492,25 +492,30 @@ def _parse_mf_holdings_row(6 block: Block,7 scheme_meta: Dict[str, Dict[str, str]],8 ) -> Optional[MutualFund]:9- """MF holdings table row. Two known templates:10+ """MF holdings table row. Known templates:11 12- - **With distribution-mode column (13 cells)**:13+ - **Full, with distribution-mode column (13 cells)**:14 name | ISIN | folio | ARN-or-DIRECT | units | NAV | invested15 | value | TER% | direct | commission | profit | return%16 17 - **Without distribution-mode column (7 cells)**:18 name | ISIN | folio | units | NAV | invested | value19 20- Discriminator: the cell two positions after the ISIN. In the21- 13-cell layout it carries an alphanumeric distribution-mode label22- (`ARN-####`, `DIRECT`, sometimes a folio-split fragment like23- `4/0`). In the 7-cell layout it carries the units value (a pure24- number). So if that cell isn't a clean number, we treat the row25- as the 13-cell template.26+ - **Reduced, with distribution-mode column (7 cells)**:27+ name | ISIN | folio | ARN-or-DIRECT | units | NAV | value28+ (no separate "invested / total cost" column)29 30- Either way, we then filter the cells after `data_start` to numeric31- tokens only — that picks the right values for balance/NAV/invested/32- valuation regardless of whether the row had a split-folio quirk.33+ Discriminator: the cell two positions after the ISIN. In the34+ distribution-mode layouts it carries an alphanumeric label35+ (`ARN-####`, `DIRECT`, sometimes a folio-split fragment like36+ `4/0`); otherwise it's the units value (a pure number).37+38+ We then filter the cells after `data_start` to numeric tokens. The39+ leading two are always units + NAV; the *current value* is the next40+ column when it's the last one (reduced row) or the column after41+ "invested" otherwise. A holdings statement always prints the42+ current value, so when only three numerics survive we treat the43+ third as the value (not the optional invested/cost column).44 """45 if len(block.cells) < 5:46 return None47@@ -548,8 +553,14 @@ def _parse_mf_holdings_row(48 return None49 balance = _to_decimal(numerics[0])50 nav = _to_decimal(numerics[1])51- invested = _opt_decimal(numerics[2])52- value = _to_decimal(numerics[3]) if len(numerics) >= 4 else Decimal(0)53+ if len(numerics) >= 4:54+ # units | NAV | invested | value | [TER, commission, profit, return]55+ invested = _opt_decimal(numerics[2])56+ value = _to_decimal(numerics[3])57+ else:58+ # Reduced row: units | NAV | value (no separate invested/cost).59+ invested = None60+ value = _to_decimal(numerics[2])61 pnl = _opt_decimal(numerics[-2]) if has_distrib_col and len(numerics) >= 6 else None62 ret = _opt_decimal(numerics[-1]) if has_distrib_col and len(numerics) >= 5 else None63 64 