fix(portfolio): tolerate consolidation WAC residue
This commit is contained in:
@@ -6,6 +6,13 @@ import json
|
||||
from dataclasses import dataclass
|
||||
from decimal import ROUND_HALF_UP, Decimal
|
||||
|
||||
STORAGE_QUANTUM = Decimal("0.00000001")
|
||||
|
||||
|
||||
def quantize_stored_decimal(value: Decimal) -> Decimal:
|
||||
"""Round a monetary value to the NUMERIC(*, 8) persistence contract."""
|
||||
return value.quantize(STORAGE_QUANTUM, rounding=ROUND_HALF_UP)
|
||||
|
||||
|
||||
def canonical_payload_hash(payload: object) -> str:
|
||||
if hasattr(payload, "model_dump"):
|
||||
@@ -36,11 +43,13 @@ def calculate_stock_consolidation(quantity_before: Decimal, quantity_after: Deci
|
||||
raise CorporateActionError("stock consolidation must reduce quantity")
|
||||
if q1 != q1.to_integral_value() or q0 != q0.to_integral_value():
|
||||
raise CorporateActionError("fractional result unsupported", "FRACTIONAL_RESULT_UNSUPPORTED")
|
||||
total = (q0 * wac).quantize(Decimal("0.00000001"), rounding=ROUND_HALF_UP)
|
||||
after = (total / q1).quantize(Decimal("0.00000001"), rounding=ROUND_HALF_UP)
|
||||
if after * q1 != total:
|
||||
raise CorporateActionError("fractional result unsupported", "FRACTIONAL_RESULT_UNSUPPORTED")
|
||||
return StockConsolidation(q0, q1, wac, after, total, ratio)
|
||||
# Preserve the authoritative pre-action total independently. A per-unit WAC
|
||||
# rounded to the storage scale cannot always multiply back to that total
|
||||
# exactly, and that harmless decimal residue is not a fractional share.
|
||||
total = quantize_stored_decimal(q0 * wac)
|
||||
before = quantize_stored_decimal(wac)
|
||||
after = quantize_stored_decimal(total / q1)
|
||||
return StockConsolidation(q0, q1, before, after, total, ratio)
|
||||
|
||||
def apply_corporate_action_to_wac(quantity: Decimal, wac: Decimal, quantity_after: Decimal) -> tuple[Decimal, Decimal]:
|
||||
result = calculate_stock_consolidation(quantity, quantity_after, wac)
|
||||
|
||||
Reference in New Issue
Block a user