Files
stock/backend/app/commission.py
2026-08-07 16:08:34 +08:00

48 lines
2.1 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""A股交易成本基准日 2026-08已修正历史错误
⚠️ 重要:费率必须是"参数表 + 生效日期版本化 + 显式基准日",不能硬编码成常量。
费率会再变(如 2023-08-28 印花税减半、2022 过户费下调)。
MVP 用单一 CostSchedule阶段1 扩展为按生效日期区间查找的多版本表。
参考(已核实):
印花税 0.05% 单边卖出 —— 2023-08-28 财政部减半(原 0.1%
过户费 0.001% 沪深双边 —— 2022 年统一下调(原沪市万 0.2 单边)
佣金 万1 含规费,最低 5 元 —— 2026 主流
"""
from __future__ import annotations
from dataclasses import dataclass
from .config import settings
@dataclass(frozen=True)
class CostSchedule:
stamp_duty_rate: float = settings.stamp_duty_rate # 印花税,卖出
transfer_fee_rate: float = settings.transfer_fee_rate # 过户费,双边
commission_rate: float = settings.commission_rate # 佣金
commission_min: float = settings.commission_min # 最低佣金
slippage_rate: float = settings.slippage_rate # 滑点(价格比例近似)
DEFAULT = CostSchedule()
def buy_cost(price: float, qty: float, sch: CostSchedule = DEFAULT) -> tuple[float, float, float]:
"""买入成本。返回 (成交价, 佣金, 过户费)。买入无印花税。"""
fill_price = price * (1 + sch.slippage_rate)
gross = fill_price * qty
commission = max(gross * sch.commission_rate, sch.commission_min)
transfer_fee = gross * sch.transfer_fee_rate
return fill_price, commission, transfer_fee
def sell_cost(price: float, qty: float, sch: CostSchedule = DEFAULT) -> tuple[float, float, float, float]:
"""卖出成本。返回 (成交价, 佣金, 过户费, 印花税)。"""
fill_price = price * (1 - sch.slippage_rate)
gross = fill_price * qty
commission = max(gross * sch.commission_rate, sch.commission_min)
transfer_fee = gross * sch.transfer_fee_rate
stamp_duty = gross * sch.stamp_duty_rate
return fill_price, commission, transfer_fee, stamp_duty