"""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