feat(PORTFOLIO-002): add position storage costs

This commit is contained in:
Bu5hm4nn
2026-03-28 23:48:41 +01:00
parent e148d55cda
commit 0e972e9dd6
5 changed files with 501 additions and 1 deletions

View File

@@ -22,6 +22,9 @@ class Position:
entry_date: Date of position entry (for historical conversion lookups)
entry_basis_mode: Entry basis mode ("weight" or "value_price")
notes: Optional notes about this position
storage_cost_basis: Annual storage cost as percentage (e.g., Decimal("0.12") for 0.12%) or fixed amount
storage_cost_period: Period for storage cost ("annual" or "monthly")
storage_cost_currency: Currency for fixed amount costs (default "USD")
created_at: Timestamp when position was created
"""
@@ -33,6 +36,9 @@ class Position:
entry_date: date
entry_basis_mode: str = "weight"
notes: str = ""
storage_cost_basis: Decimal | None = None
storage_cost_period: str | None = None
storage_cost_currency: str = "USD"
created_at: datetime = field(default_factory=lambda: datetime.now(UTC))
def __post_init__(self) -> None:
@@ -67,6 +73,9 @@ class Position:
"entry_date": self.entry_date.isoformat(),
"entry_basis_mode": self.entry_basis_mode,
"notes": self.notes,
"storage_cost_basis": str(self.storage_cost_basis) if self.storage_cost_basis is not None else None,
"storage_cost_period": self.storage_cost_period,
"storage_cost_currency": self.storage_cost_currency,
"created_at": self.created_at.isoformat(),
}
@@ -82,6 +91,11 @@ class Position:
entry_date=date.fromisoformat(data["entry_date"]),
entry_basis_mode=data.get("entry_basis_mode", "weight"),
notes=data.get("notes", ""),
storage_cost_basis=(
Decimal(data["storage_cost_basis"]) if data.get("storage_cost_basis") is not None else None
),
storage_cost_period=data.get("storage_cost_period"),
storage_cost_currency=data.get("storage_cost_currency", "USD"),
created_at=datetime.fromisoformat(data["created_at"]) if "created_at" in data else datetime.now(UTC),
)
@@ -94,6 +108,9 @@ def create_position(
entry_date: date | None = None,
entry_basis_mode: str = "weight",
notes: str = "",
storage_cost_basis: Decimal | None = None,
storage_cost_period: str | None = None,
storage_cost_currency: str = "USD",
) -> Position:
"""Create a new position with sensible defaults.
@@ -105,6 +122,9 @@ def create_position(
entry_date: Entry date (default: today)
entry_basis_mode: Entry basis mode (default: "weight")
notes: Optional notes
storage_cost_basis: Annual storage cost as percentage or fixed amount (default: None)
storage_cost_period: Period for storage cost ("annual" or "monthly", default: None)
storage_cost_currency: Currency for fixed amount costs (default: "USD")
"""
return Position(
id=uuid4(),
@@ -115,4 +135,7 @@ def create_position(
entry_date=entry_date or date.today(),
entry_basis_mode=entry_basis_mode,
notes=notes,
storage_cost_basis=storage_cost_basis,
storage_cost_period=storage_cost_period,
storage_cost_currency=storage_cost_currency,
)