Files
Grid_Trading/src/grid_trading/domain/models.py
2026-07-09 10:50:25 +08:00

174 lines
3.7 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
from enum import StrEnum
class TradeSide(StrEnum):
BUY = "buy"
SELL = "sell"
class TradeGroup(StrEnum):
BASE = "base"
GRID = "grid"
OTHER = "other"
@dataclass(frozen=True)
class Account:
id: int | None
name: str
initial_cash: Decimal
notes: str = ""
@dataclass(frozen=True)
class Instrument:
id: int | None
code: str
name: str
market: str = "A"
lot_size: int = 100
manual_price: Decimal | None = None
allow_odd_lot: bool = False
active: bool = True
@dataclass(frozen=True)
class StrategyTemplate:
id: int | None
name: str
grid_spacing_pct: Decimal
amount_per_grid: Decimal
base_target_amount: Decimal
max_position_amount: Decimal
min_lot: int = 100
is_default: bool = False
@dataclass(frozen=True)
class StrategyOverride:
instrument_id: int
template_id: int | None = None
grid_spacing_pct: Decimal | None = None
amount_per_grid: Decimal | None = None
base_target_amount: Decimal | None = None
max_position_amount: Decimal | None = None
min_lot: int | None = None
@dataclass(frozen=True)
class Trade:
id: int | None
account_id: int
instrument_id: int
trade_date: date
side: TradeSide
price: Decimal
quantity: int
commission: Decimal = Decimal("0")
stamp_tax: Decimal = Decimal("0")
transfer_fee: Decimal = Decimal("0")
trade_group: TradeGroup = TradeGroup.GRID
notes: str = ""
@property
def gross_amount(self) -> Decimal:
return self.price * Decimal(self.quantity)
@property
def total_fee(self) -> Decimal:
return self.commission + self.stamp_tax + self.transfer_fee
@dataclass(frozen=True)
class CashLedgerEntry:
id: int | None
account_id: int
entry_date: date
amount: Decimal
category: str
instrument_id: int | None = None
notes: str = ""
@dataclass(frozen=True)
class FeeRules:
commission_rate: Decimal
min_commission: Decimal
stamp_tax_rate: Decimal
transfer_fee_rate: Decimal
@dataclass(frozen=True)
class FeeEstimate:
commission: Decimal
stamp_tax: Decimal
transfer_fee: Decimal
@property
def total(self) -> Decimal:
return self.commission + self.stamp_tax + self.transfer_fee
@dataclass(frozen=True)
class GridLevelSuggestion:
level: int
buy_price: Decimal
buy_amount: Decimal
suggested_quantity: int
actual_investment: Decimal
sell_price: Decimal
estimated_gross_profit: Decimal
@dataclass(frozen=True)
class QuoteSnapshot:
symbol: str
code: str
name: str
price: Decimal
source: str
quote_time: str | None = None
previous_close: Decimal | None = None
open_price: Decimal | None = None
high: Decimal | None = None
low: Decimal | None = None
change: Decimal | None = None
change_percent: Decimal | None = None
@dataclass(frozen=True)
class PositionSummary:
instrument_id: int
code: str
name: str
market: str
current_price: Decimal | None
price_source: str
total_quantity: int
available_quantity: int
base_quantity: int
grid_quantity: int
other_quantity: int
remaining_cost: Decimal
cost_price: Decimal | None
position_breakeven_price: Decimal | None
account_breakeven_price: Decimal | None
realized_pnl: Decimal
grid_profit: Decimal
floating_pnl: Decimal | None
market_value: Decimal | None
@dataclass(frozen=True)
class AccountSummary:
total_assets: Decimal
cash: Decimal
market_value: Decimal
floating_pnl: Decimal
capital_usage_rate: Decimal