2026-09-03 11:33:43 +08:00
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from typing import Any
|
|
|
|
|
|
|
2026-09-06 14:49:46 +08:00
|
|
|
|
from .models import Assets, DealItem, OrderItem, Portfolio, PositionItem
|
2026-09-03 11:33:43 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PortfolioMixin:
|
2026-09-06 11:34:23 +08:00
|
|
|
|
def org(self, datatype: str) -> list[dict[str, Any]]:
|
|
|
|
|
|
"""查询 account、order、deal 或 position,返回原始字段字典列表。"""
|
|
|
|
|
|
datatype = str(datatype).strip().lower()
|
|
|
|
|
|
if datatype not in {"account", "order", "deal", "position"}:
|
|
|
|
|
|
raise ValueError(f"unsupported org datatype: {datatype}")
|
|
|
|
|
|
response = self._get_json(f"/api/portfolio/org/{datatype}")
|
|
|
|
|
|
return response["data"]
|
|
|
|
|
|
|
2026-09-03 11:33:43 +08:00
|
|
|
|
def portfolio(self) -> Portfolio:
|
|
|
|
|
|
data = self._get_json("/api/portfolio") or {}
|
|
|
|
|
|
positions = {
|
2026-09-07 14:04:26 +08:00
|
|
|
|
code: PositionItem(**value)
|
2026-09-03 11:33:43 +08:00
|
|
|
|
for code, value in data.get("positions", {}).items()
|
|
|
|
|
|
}
|
|
|
|
|
|
return Portfolio(
|
2026-09-07 14:04:26 +08:00
|
|
|
|
assets=Assets(**data.get("assets", {})),
|
2026-09-03 11:33:43 +08:00
|
|
|
|
positions=positions,
|
2026-09-07 14:04:26 +08:00
|
|
|
|
orders=[OrderItem(**row) for row in data.get("orders", [])],
|
2026-09-03 11:33:43 +08:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def positions(self) -> tuple[list[str], list[PositionItem]]:
|
|
|
|
|
|
data = self._get_json("/api/portfolio/positions") or {}
|
|
|
|
|
|
positions = [
|
2026-09-07 14:04:26 +08:00
|
|
|
|
PositionItem(**value)
|
|
|
|
|
|
for value in data.values()
|
2026-09-03 11:33:43 +08:00
|
|
|
|
]
|
2026-09-07 14:04:26 +08:00
|
|
|
|
return list(data), positions
|
2026-09-03 11:33:43 +08:00
|
|
|
|
|
|
|
|
|
|
def assets(self) -> Assets:
|
2026-09-07 14:04:26 +08:00
|
|
|
|
return Assets(**(self._get_json("/api/portfolio/assets") or {}))
|
2026-09-03 11:33:43 +08:00
|
|
|
|
|
|
|
|
|
|
def orders(self) -> list[OrderItem]:
|
|
|
|
|
|
data = self._get_json("/api/portfolio/order") or []
|
2026-09-07 14:04:26 +08:00
|
|
|
|
return [OrderItem(**row) for row in data]
|
2026-09-03 11:33:43 +08:00
|
|
|
|
|
2026-09-06 14:49:46 +08:00
|
|
|
|
def deals(self) -> list[DealItem]:
|
2026-09-07 00:27:33 +08:00
|
|
|
|
data = self._get_json("/api/portfolio/deal") or []
|
2026-09-07 14:04:26 +08:00
|
|
|
|
return [DealItem(**row) for row in data]
|
2026-09-03 11:33:43 +08:00
|
|
|
|
|
|
|
|
|
|
def trade_detail_data(self, datatype: str) -> Any:
|
|
|
|
|
|
datatype = str(datatype).strip().lower()
|
|
|
|
|
|
handlers = {
|
|
|
|
|
|
"account": self.assets,
|
|
|
|
|
|
"position": lambda: self.positions()[1],
|
|
|
|
|
|
"order": self.orders,
|
|
|
|
|
|
"deal": self.deals,
|
|
|
|
|
|
}
|
|
|
|
|
|
handler = handlers.get(datatype)
|
|
|
|
|
|
if handler is None:
|
|
|
|
|
|
raise ValueError(f"unsupported trade detail datatype: {datatype}")
|
|
|
|
|
|
result = handler()
|
|
|
|
|
|
return [result] if datatype == "account" else result
|