chore: initial project scaffold and gitignore
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Pydantic schemas for PortfolioHub."""
|
||||
@@ -0,0 +1,121 @@
|
||||
"""Portfolio request and response schemas."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class StrategySetResponse(BaseModel):
|
||||
id: str
|
||||
strategy_name: str
|
||||
strategy_config: str
|
||||
created_at: datetime | None = None
|
||||
|
||||
|
||||
class LedgerEntryResponse(BaseModel):
|
||||
portfolio_id: str
|
||||
recorded_at: datetime
|
||||
action: str
|
||||
price: float
|
||||
quantity: float
|
||||
fee_amount: float = 0.0
|
||||
tax_amount: float = 0.0
|
||||
cash_balance_after: float
|
||||
asset_quantity_after: float
|
||||
total_value_after: float
|
||||
profit_buffer_after: float = 0.0
|
||||
strategy_set_id: str = "manual"
|
||||
note: str = ""
|
||||
|
||||
|
||||
class PortfolioBase(BaseModel):
|
||||
broker: str = "kis"
|
||||
status: str = "enabled"
|
||||
symbol: str
|
||||
strategy_name: str = "target_value"
|
||||
strategy_params: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class PortfolioSummary(BaseModel):
|
||||
portfolio_id: str
|
||||
broker: str
|
||||
status: str
|
||||
symbol: str
|
||||
strategy_name: str
|
||||
strategy_params: dict[str, Any] = Field(default_factory=dict)
|
||||
cash_balance: float = 0.0
|
||||
asset_quantity: float = 0.0
|
||||
price: float = 0.0
|
||||
profit_buffer: float = 0.0
|
||||
current_strategy_set_id: str | None = None
|
||||
created_at: datetime | None = None
|
||||
updated_at: datetime | None = None
|
||||
last_trade_at: datetime | None = None
|
||||
|
||||
|
||||
class PortfolioListItem(PortfolioSummary):
|
||||
total_value: float = 0.0
|
||||
|
||||
|
||||
class PortfolioDetailResponse(BaseModel):
|
||||
portfolio: PortfolioSummary
|
||||
recent_entries: list[LedgerEntryResponse] = Field(default_factory=list)
|
||||
strategy_set: StrategySetResponse | None = None
|
||||
live_quantity: float | None = None
|
||||
|
||||
|
||||
class CreatePortfolioRequest(PortfolioBase):
|
||||
portfolio_id: str
|
||||
cash_balance: float = Field(default=0.0, ge=0.0)
|
||||
asset_quantity: float = Field(default=0.0, ge=0.0)
|
||||
asset_price: float = Field(default=0.0, ge=0.0)
|
||||
profit_buffer: float = Field(default=0.0, ge=0.0)
|
||||
|
||||
|
||||
class UpdatePortfolioRequest(BaseModel):
|
||||
broker: str | None = None
|
||||
status: str | None = None
|
||||
symbol: str | None = None
|
||||
strategy_name: str | None = None
|
||||
strategy_params: dict[str, Any] | None = None
|
||||
asset_price: float | None = Field(default=None, ge=0.0)
|
||||
|
||||
|
||||
class BuyRequest(BaseModel):
|
||||
quantity: float = Field(gt=0.0)
|
||||
price: float = Field(gt=0.0)
|
||||
fee: float = Field(default=0.0, ge=0.0)
|
||||
tax: float = Field(default=0.0, ge=0.0)
|
||||
note: str = ""
|
||||
|
||||
|
||||
class SellRequest(BaseModel):
|
||||
quantity: float = Field(gt=0.0)
|
||||
price: float = Field(gt=0.0)
|
||||
fee: float = Field(default=0.0, ge=0.0)
|
||||
tax: float = Field(default=0.0, ge=0.0)
|
||||
note: str = ""
|
||||
|
||||
|
||||
class InvestRequest(BaseModel):
|
||||
movement_type: Literal["deposit", "profit", "withdraw"]
|
||||
amount: float = Field(gt=0.0)
|
||||
note: str = ""
|
||||
|
||||
|
||||
class TransferRequest(BaseModel):
|
||||
direction: Literal["to-buffer", "from-buffer"]
|
||||
amount: float = Field(gt=0.0)
|
||||
note: str = ""
|
||||
|
||||
|
||||
class ResetPortfolioRequest(BaseModel):
|
||||
infer_symbol: str | None = None
|
||||
|
||||
|
||||
class ErrorResponse(BaseModel):
|
||||
detail: str
|
||||
model_config = ConfigDict(extra="ignore")
|
||||
Reference in New Issue
Block a user