Coverage for core/models/asset.py: 100.00%
189 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 18:58 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-10-13 18:58 +0000
1"""
2资产相关数据模型
3"""
5from datetime import datetime
6from decimal import Decimal
7from enum import Enum
8from typing import Dict, List, Optional
10from pydantic import BaseModel, Field
13class CurrencyType(str, Enum):
14 """货币类型枚举"""
16 USD = "USD" # 美元
17 HKD = "HKD" # 港币
18 CNY = "CNY" # 人民币
21class MarketType(str, Enum):
22 """市场类型枚举"""
24 US = "US" # 美股
25 HK = "HK" # 港股
26 CN = "CN" # A股
27 SG = "SG" # 新加坡
28 CRYPTO = "CRYPTO" # 加密货币
31class AssetType(str, Enum):
32 """资产类型枚举"""
34 STOCK = "stock" # 股票
35 FUND = "fund" # 基金
36 CASH = "cash" # 现金
37 BOND = "bond" # 债券
38 OPTION = "option" # 期权
39 WARRANT = "warrant" # 权证
42class CashInfo(BaseModel):
43 """现金信息"""
45 withdraw_cash: Decimal = Field(..., description="可提取现金")
46 available_cash: Decimal = Field(..., description="可用现金")
47 frozen_cash: Decimal = Field(..., description="冻结现金")
48 settling_cash: Decimal = Field(..., description="待结算现金")
49 currency: CurrencyType = Field(..., description="货币类型")
52class AccountBalance(BaseModel):
53 """账户余额"""
55 total_cash: Decimal = Field(..., description="总现金")
56 max_finance_amount: Decimal = Field(..., description="最大融资额度")
57 remaining_finance_amount: Decimal = Field(..., description="剩余融资额度")
58 risk_level: int = Field(..., description="风险等级")
59 margin_call: Decimal = Field(..., description="保证金追缴")
60 currency: CurrencyType = Field(..., description="货币类型")
61 cash_infos: List[CashInfo] = Field(..., description="现金详情")
62 net_assets: Decimal = Field(..., description="净资产")
63 init_margin: Decimal = Field(..., description="初始保证金")
64 maintenance_margin: Decimal = Field(..., description="维持保证金")
65 buy_power: Decimal = Field(..., description="购买力")
68class StockPosition(BaseModel):
69 """股票持仓"""
71 symbol: str = Field(..., description="股票代码")
72 symbol_name: str = Field(..., description="股票名称")
73 quantity: Decimal = Field(..., description="持仓数量")
74 available_quantity: Decimal = Field(..., description="可用数量")
75 currency: CurrencyType = Field(..., description="货币类型")
76 cost_price: Decimal = Field(..., description="成本价")
77 market: MarketType = Field(..., description="市场类型")
78 init_quantity: Optional[Decimal] = Field(None, description="开盘前初始持仓")
81class FundPosition(BaseModel):
82 """基金持仓"""
84 symbol: str = Field(..., description="基金代码")
85 current_net_asset_value: Decimal = Field(..., description="当前净值")
86 net_asset_value_day: datetime = Field(..., description="净值日期")
87 symbol_name: str = Field(..., description="基金名称")
88 currency: CurrencyType = Field(..., description="货币类型")
89 cost_net_asset_value: Decimal = Field(..., description="成本净值")
90 holding_units: Decimal = Field(..., description="持有份额")
93class UserAsset(BaseModel):
94 """用户资产(只存储现金,总资产动态计算)"""
96 user_id: str = Field(..., description="用户ID")
97 cash_assets: Decimal = Field(..., description="现金资产")
98 currency: CurrencyType = Field(default=CurrencyType.USD, description="默认货币")
99 updated_at: datetime = Field(..., description="更新时间")
102class UserAssetCreate(BaseModel):
103 """创建用户资产(只存储现金,总资产动态计算)"""
105 user_id: str = Field(..., description="用户ID")
106 cash_assets: Decimal = Field(..., description="现金资产")
107 currency: CurrencyType = Field(default=CurrencyType.USD, description="默认货币")
110class UserAssetUpdate(BaseModel):
111 """更新用户资产"""
113 total_assets: Optional[Decimal] = None
114 cash_assets: Optional[Decimal] = None
115 position_assets: Optional[Decimal] = None
116 today_pnl: Optional[Decimal] = None
117 currency: Optional[CurrencyType] = None
120class UserAssetResponse(UserAsset):
121 """用户资产响应"""
123 id: str = Field(..., description="资产ID")
124 created_at: datetime = Field(..., description="创建时间")
126 class Config:
127 from_attributes = True
130class UserPosition(BaseModel):
131 """用户持仓"""
133 user_id: str = Field(..., description="用户ID")
134 symbol: str = Field(..., description="证券代码")
135 symbol_name: str = Field(..., description="证券名称")
136 asset_type: AssetType = Field(..., description="资产类型")
137 quantity: Decimal = Field(..., description="持仓数量")
138 available_quantity: Decimal = Field(..., description="可用数量")
139 cost_price: Decimal = Field(..., description="成本价")
140 current_price: Optional[Decimal] = Field(None, description="当前价格")
141 market: MarketType = Field(..., description="市场类型")
142 currency: CurrencyType = Field(..., description="货币类型")
143 updated_at: datetime = Field(..., description="更新时间")
146class UserPositionCreate(BaseModel):
147 """创建用户持仓"""
149 user_id: str = Field(..., description="用户ID")
150 symbol: str = Field(..., description="证券代码")
151 symbol_name: str = Field(..., description="证券名称")
152 asset_type: AssetType = Field(..., description="资产类型")
153 quantity: Decimal = Field(..., description="持仓数量")
154 available_quantity: Decimal = Field(..., description="可用数量")
155 cost_price: Decimal = Field(..., description="成本价")
156 current_price: Optional[Decimal] = Field(None, description="现价")
157 market: MarketType = Field(..., description="市场")
158 currency: CurrencyType = Field(..., description="货币")
161class UserPositionUpdate(BaseModel):
162 """更新用户持仓"""
164 symbol_name: Optional[str] = None
165 quantity: Optional[Decimal] = None
166 available_quantity: Optional[Decimal] = None
167 cost_price: Optional[Decimal] = None
168 current_price: Optional[Decimal] = None
169 currency: Optional[CurrencyType] = None
172class UserPositionResponse(UserPosition):
173 """用户持仓响应"""
175 id: str = Field(..., description="持仓ID")
176 created_at: datetime = Field(..., description="创建时间")
178 class Config:
179 from_attributes = True
182# 模拟资产相关模型
183class SimulatedAsset(BaseModel):
184 """模拟资产(只存储现金,总资产动态计算)"""
186 user_id: str = Field(..., description="用户ID")
187 cash_assets: Decimal = Field(..., description="现金资产")
188 currency: CurrencyType = Field(default=CurrencyType.USD, description="默认货币")
189 updated_at: datetime = Field(..., description="更新时间")
192class SimulatedAssetCreate(BaseModel):
193 """创建模拟资产(只存储现金,总资产动态计算)"""
195 user_id: str = Field(..., description="用户ID")
196 cash_assets: Decimal = Field(..., description="现金资产")
197 currency: CurrencyType = Field(default=CurrencyType.USD, description="默认货币")
200class SimulatedAssetUpdate(BaseModel):
201 """更新模拟资产(只支持现金编辑)"""
203 cash_assets: Decimal = Field(..., description="现金资产")
204 currency: CurrencyType = Field(..., description="货币类型")
207class SimulatedAssetResponse(SimulatedAsset):
208 """模拟资产响应"""
210 id: str = Field(..., description="模拟资产ID")
211 created_at: datetime = Field(..., description="创建时间")
213 class Config:
214 from_attributes = True
217class SimulatedPosition(BaseModel):
218 """模拟持仓"""
220 user_id: str = Field(..., description="用户ID")
221 symbol: str = Field(..., description="证券代码")
222 symbol_name: str = Field(..., description="证券名称")
223 asset_type: AssetType = Field(..., description="资产类型")
224 quantity: Decimal = Field(..., description="持仓数量")
225 cost_price: Decimal = Field(..., description="成本价")
226 current_price: Optional[Decimal] = Field(None, description="当前价格")
227 market: MarketType = Field(..., description="市场类型")
228 currency: CurrencyType = Field(..., description="货币类型")
229 updated_at: datetime = Field(..., description="更新时间")
232class SimulatedPositionCreate(BaseModel):
233 """创建模拟持仓"""
235 user_id: str = Field(..., description="用户ID")
236 symbol: str = Field(..., description="证券代码")
237 symbol_name: str = Field(..., description="证券名称")
238 asset_type: AssetType = Field(..., description="资产类型")
239 quantity: Decimal = Field(..., description="持仓数量")
240 cost_price: Decimal = Field(..., description="成本价")
241 current_price: Optional[Decimal] = Field(None, description="现价")
242 market: MarketType = Field(..., description="市场")
243 currency: CurrencyType = Field(..., description="货币")
246class SimulatedPositionUpdate(BaseModel):
247 """更新模拟持仓"""
249 symbol_name: Optional[str] = None
250 quantity: Optional[Decimal] = None
251 cost_price: Optional[Decimal] = None
252 current_price: Optional[Decimal] = None
253 currency: Optional[CurrencyType] = None
256class SimulatedPositionResponse(SimulatedPosition):
257 """模拟持仓响应"""
259 id: str = Field(..., description="模拟持仓ID")
260 created_at: datetime = Field(..., description="创建时间")
262 class Config:
263 from_attributes = True
266# 同步相关模型
267class SyncRequest(BaseModel):
268 """同步请求"""
270 user_id: str = Field(..., description="用户ID")
271 broker_id: Optional[str] = Field(None, description="券商ID")
274class SyncResponse(BaseModel):
275 """同步响应"""
277 success: bool = Field(..., description="同步结果")
278 message: str = Field(..., description="同步消息")
279 synced_assets: Optional[UserAssetResponse] = Field(None, description="同步后的资产")
280 synced_positions: Optional[List[UserPositionResponse]] = Field(
281 None, description="同步后的持仓"
282 )
285# 资产概览响应模型
286class AssetOverview(BaseModel):
287 """资产概览(支持多货币)"""
289 # 多货币资产数据
290 total_assets_by_currency: Optional[Dict[CurrencyType, Dict[str, Decimal]]] = Field(
291 None, description="按货币分组的总资产"
292 )
293 cash_assets_by_currency: Optional[Dict[CurrencyType, Decimal]] = Field(
294 None, description="按货币分组的现金资产"
295 )
296 position_assets_by_currency: Optional[Dict[CurrencyType, Decimal]] = Field(
297 None, description="按货币分组的持仓资产"
298 )
299 positions_by_currency: Optional[Dict[CurrencyType, List[UserPositionResponse]]] = (
300 Field(None, description="按货币分组的持仓")
301 )
303 # 兼容性字段(用于单货币显示)
304 total_assets: Optional[Decimal] = Field(None, description="总资产(主要货币)")
305 cash_assets: Optional[Decimal] = Field(None, description="现金资产(主要货币)")
306 position_assets: Optional[Decimal] = Field(None, description="持仓资产(主要货币)")
307 today_pnl: Optional[Decimal] = Field(None, description="今日盈亏")
308 currency: Optional[CurrencyType] = Field(None, description="主要货币类型")
309 positions: List[UserPositionResponse] = Field(
310 default=[], description="所有持仓列表"
311 )
314class SimulatedAssetOverview(BaseModel):
315 """模拟资产概览(支持多货币)"""
317 # 多货币资产数据
318 total_assets_by_currency: Optional[Dict[CurrencyType, Dict[str, Decimal]]] = Field(
319 None, description="按货币分组的总资产"
320 )
321 positions_by_currency: Optional[
322 Dict[CurrencyType, List[SimulatedPositionResponse]]
323 ] = Field(None, description="按货币分组的持仓")
325 # 兼容性字段(用于单货币显示)
326 total_assets: Optional[Decimal] = Field(None, description="总资产(主要货币)")
327 cash_assets: Optional[Decimal] = Field(None, description="现金资产(主要货币)")
328 position_assets: Optional[Decimal] = Field(None, description="持仓资产(主要货币)")
329 today_pnl: Optional[Decimal] = Field(None, description="今日盈亏")
330 currency: Optional[CurrencyType] = Field(None, description="主要货币类型")
331 positions: List[SimulatedPositionResponse] = Field(
332 default=[], description="所有模拟持仓列表"
333 )