48 lines
2.1 KiB
Python
48 lines
2.1 KiB
Python
"""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
|