42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
from datetime import date, datetime
|
|
from decimal import Decimal
|
|
from typing import Literal
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
|
|
|
|
|
# Corporate actions (stock_consolidation-only, issue #34)
|
|
class CorporateActionRequest(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
action_type: Literal["stock_consolidation"] = "stock_consolidation"
|
|
effective_date: date
|
|
quantity_before: Decimal = Field(..., gt=0, max_digits=20, decimal_places=8)
|
|
quantity_after: Decimal = Field(..., gt=0, max_digits=20, decimal_places=8)
|
|
evidence_ref: str = Field(..., min_length=1, max_length=500)
|
|
confirm_daemon_managed: bool = False
|
|
resume_partial: bool = False
|
|
|
|
@model_validator(mode="after")
|
|
def valid_ratio(self):
|
|
if self.quantity_after >= self.quantity_before:
|
|
raise ValueError("quantity_after must be less than quantity_before")
|
|
return self
|
|
|
|
class CorporateActionResponse(BaseModel):
|
|
corporate_action_id: str
|
|
ledger_entry_id: int
|
|
portfolio_id: str
|
|
action_type: Literal["stock_consolidation"]
|
|
effective_date: date
|
|
quantity_before: Decimal
|
|
quantity_after: Decimal
|
|
average_price_before: Decimal
|
|
average_price_after: Decimal
|
|
total_cost_basis: Decimal
|
|
cash_balance: Decimal
|
|
profit_buffer: Decimal
|
|
evidence_ref: str
|
|
actor_user_id: str | None = None
|
|
recorded_at: datetime
|
|
idempotent_replay: bool = False
|