feat(PORTFOLIO-002): add position storage costs
This commit is contained in:
@@ -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,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user