🇨🇳 简体中文
🇺🇸 English
🇯🇵 日本語
Skip to the content.

交易费用架构设计

概述

交易费用模块负责管理券商的交易费用配置,并在订单成交时自动计算和扣除相应的交易费用。系统支持美股和港股的不同费用标准,费用配置与券商绑定,在交易会话启动时传递给相关模块使用。

费用处理模式

系统根据不同的交易模式采用不同的费用处理策略:

1. 模拟资产交易(实时交易 + 回测)

2. 真实资产交易(实时交易)

关键设计原则

  1. 订单费用字段:所有订单都有 trading_fee 字段,存储费用明细
  2. 买卖差异:买入和卖出的费用计算规则不同(交易活动费仅在卖出时收取)
  3. 模式隔离:模拟资产和真实资产的费用处理逻辑完全隔离
  4. 真实数据优先:真实资产模式下,账户数据以券商API为准,不做本地修改

架构图

1. 费用配置数据流

graph TB
    subgraph "前端层"
        FE1[券商设置页面]
        FE2[费用配置表单]
    end
    
    subgraph "API层"
        API1[Broker API<br/>券商管理]
        API2[Fee Config API<br/>费用配置]
    end
    
    subgraph "服务层"
        SVC1[BrokerService<br/>券商服务]
        SVC2[TradingService<br/>交易服务]
    end
    
    subgraph "仓储层"
        REPO1[BrokerRepository<br/>券商仓储]
        REPO2[Redis缓存]
    end
    
    subgraph "交易引擎层"
        TSE[TradingSessionEngine<br/>交易会话引擎]
        SE[StrategyEngine<br/>策略引擎]
        TE[TradingEngine<br/>交易引擎]
        SIM[SimulationEngine<br/>模拟交易引擎]
        FEE[FeeCalculator<br/>费用计算器]
    end
    
    subgraph "数据存储"
        DB[(PostgreSQL<br/>持久化存储)]
        REDIS[(Redis<br/>缓存)]
    end
    
    %% 配置流程
    FE2 --> |更新费用配置|API2
    API2 --> SVC1
    SVC1 --> REPO1
    REPO1 --> DB
    REPO1 --> REDIS
    
    %% 启动流程
    TSE --> |获取券商配置|SVC1
    SVC1 --> REPO1
    REPO1 --> |返回费用配置|SVC1
    SVC1 --> |传递费用配置|TSE
    TSE --> |初始化|SE
    TSE --> |初始化|TE
    TSE --> |初始化|SIM
    
    %% 交易流程
    SIM --> |计算费用|FEE
    FEE --> |扣除现金|SIM

2. 费用计算时序图

sequenceDiagram
    participant Strategy as StrategyEngine
    participant Trading as TradingEngine
    participant Simulation as SimulationEngine
    participant FeeCalc as FeeCalculator
    participant Account as AccountManager
    
    Strategy->>Trading: 发送订单信号
    Trading->>Simulation: 执行订单
    
    Note over Simulation: 订单成交
    
    Simulation->>FeeCalc: 计算费用(quantity, price, side, market)
    
    alt 美股市场
        FeeCalc->>FeeCalc: 使用US费用配置
        FeeCalc->>FeeCalc: 计算平台费
        FeeCalc->>FeeCalc: 计算交易活动费(仅卖出)
        FeeCalc->>FeeCalc: 计算交收费
        FeeCalc->>FeeCalc: 计算综合审计费
    else 港股市场
        FeeCalc->>FeeCalc: 使用HK费用配置
        FeeCalc->>FeeCalc: 计算平台费
        FeeCalc->>FeeCalc: 计算交易活动费(仅卖出)
        FeeCalc->>FeeCalc: 计算交收费
        FeeCalc->>FeeCalc: 计算综合审计费
    end
    
    FeeCalc-->>Simulation: 返回总费用
    
    Simulation->>Account: 扣除交易费用
    Account->>Account: 更新现金余额
    Account-->>Simulation: 扣除成功
    
    Simulation->>Simulation: 记录交易费用到订单
    Simulation-->>Trading: 订单完成
    Trading-->>Strategy: 交易完成通知

核心组件设计

1. 费用配置模型

FeeConfig(费用配置)

class FeeConfig(BaseModel):
    """交易费用配置"""
    us_fees: USFeeConfig      # 美股费用配置
    hk_fees: HKFeeConfig      # 港股费用配置

USFeeConfig(美股费用配置)

class USFeeConfig(BaseModel):
    """美股交易费用配置"""
    # 平台费用
    platform_fee_per_share: Decimal = Decimal('0.005')    # 平台费 0.005美元/股
    platform_fee_minimum: Decimal = Decimal('1.0')        # 最低收取1美元
    
    # 交易活动费用 (仅在卖出时收取)
    activity_fee_per_share: Decimal = Decimal('0.000166') # 0.000166美元/股
    activity_fee_maximum: Decimal = Decimal('8.3')        # 最高8.3美元
    
    # 交收费
    clearing_fee_per_share: Decimal = Decimal('0.003')    # 0.003美元/股
    clearing_fee_max_pct: Decimal = Decimal('0.07')       # 最高7%
    
    # 综合审计费
    audit_fee_per_share: Decimal = Decimal('0.000046')    # 0.000046美元/股
    audit_fee_minimum: Decimal = Decimal('0.01')          # 最低0.01美元

HKFeeConfig(港股费用配置)

class HKFeeConfig(BaseModel):
    """港股交易费用配置(结构与美股相同)"""
    # 平台费用
    platform_fee_per_share: Decimal = Decimal('0.005')
    platform_fee_minimum: Decimal = Decimal('1.0')
    
    # 交易活动费用 (仅在卖出时收取)
    activity_fee_per_share: Decimal = Decimal('0.000166')
    activity_fee_maximum: Decimal = Decimal('8.3')
    
    # 交收费
    clearing_fee_per_share: Decimal = Decimal('0.003')
    clearing_fee_max_pct: Decimal = Decimal('0.07')
    
    # 综合审计费
    audit_fee_per_share: Decimal = Decimal('0.000046')
    audit_fee_minimum: Decimal = Decimal('0.01')

2. 费用计算器

FeeCalculator(费用计算器)

class FeeCalculator:
    """交易费用计算器"""

    def __init__(self, fee_config: Optional[FeeConfig] = None):
        """
        初始化费用计算器

        Args:
            fee_config: 费用配置(包含美股和港股配置),如果为None则使用默认配置
        """
        if fee_config is None:
            fee_config = FeeConfig()

        self.us_fees = fee_config.us_fees
        self.hk_fees = fee_config.hk_fees
    
    def calculate_fee(
        self,
        quantity: Decimal,
        price: Decimal,
        side: str,
        market: str
    ) -> TradingFee:
        """
        计算交易费用
        
        Args:
            quantity: 成交数量
            price: 成交价格
            side: 买卖方向 ('buy' | 'sell')
            market: 市场类型 ('US' | 'HK')
        
        Returns:
            TradingFee: 费用明细对象
        """
        if market == 'US':
            return self._calculate_us_fee(quantity, price, side)
        elif market == 'HK':
            return self._calculate_hk_fee(quantity, price, side)
        else:
            raise ValueError(f"Unsupported market: {market}")
    
    def _calculate_us_fee(
        self,
        quantity: Decimal,
        price: Decimal,
        side: str
    ) -> TradingFee:
        """计算美股费用"""
        trade_amount = quantity * price
        fees = TradingFee()
        
        # 1. 平台费(买入和卖出都收取)
        fees.platform_fee = max(
            quantity * self.us_fees.platform_fee_per_share,
            self.us_fees.platform_fee_minimum
        )
        
        # 2. 交易活动费(仅卖出收取)
        if side == 'sell':
            fees.activity_fee = min(
                quantity * self.us_fees.activity_fee_per_share,
                self.us_fees.activity_fee_maximum
            )
        
        # 3. 交收费(买入和卖出都收取)
        fees.clearing_fee = min(
            quantity * self.us_fees.clearing_fee_per_share,
            trade_amount * self.us_fees.clearing_fee_max_pct
        )
        
        # 4. 综合审计费(买入和卖出都收取)
        fees.audit_fee = max(
            quantity * self.us_fees.audit_fee_per_share,
            self.us_fees.audit_fee_minimum
        )
        
        # 计算总费用
        fees.total_fee = (
            fees.platform_fee +
            fees.activity_fee +
            fees.clearing_fee +
            fees.audit_fee
        )

        # ⭐ 精度控制:将所有费用四舍五入到2位小数
        fees.platform_fee = fees.platform_fee.quantize(Decimal('0.01'))
        fees.activity_fee = fees.activity_fee.quantize(Decimal('0.01'))
        fees.clearing_fee = fees.clearing_fee.quantize(Decimal('0.01'))
        fees.audit_fee = fees.audit_fee.quantize(Decimal('0.01'))
        fees.total_fee = fees.total_fee.quantize(Decimal('0.01'))

        # ⭐ 记录计算详情(用于调试和审计)
        fees.calculation_details = {
            'quantity': str(quantity),
            'price': str(price),
            'trade_amount': str(trade_amount),
            'side': side,
            'market': 'US',
            'fee_breakdown': {
                'platform_fee': {'applied': str(fees.platform_fee)},
                'activity_fee': {'applied': str(fees.activity_fee)},
                'clearing_fee': {'applied': str(fees.clearing_fee)},
                'audit_fee': {'applied': str(fees.audit_fee)}
            }
        }

        return fees
    
    def _calculate_hk_fee(
        self,
        quantity: Decimal,
        price: Decimal,
        side: str
    ) -> TradingFee:
        """计算港股费用(逻辑与美股相同)"""
        # 实现逻辑与 _calculate_us_fee 相同,使用 hk_fees 配置
        pass

TradingFee(费用明细)

class TradingFee(BaseModel):
    """交易费用明细"""
    platform_fee: Decimal = Decimal('0')      # 平台费
    activity_fee: Decimal = Decimal('0')      # 交易活动费
    clearing_fee: Decimal = Decimal('0')      # 交收费
    audit_fee: Decimal = Decimal('0')         # 综合审计费
    total_fee: Decimal = Decimal('0')         # 总费用
    
    currency: str = 'USD'                     # 币种
    calculation_details: Dict[str, Any] = {}  # 计算详情

3. 模拟交易引擎集成

class SimulationEngine:
    """模拟交易引擎"""
    
    def __init__(
        self,
        user_id: str,
        session_id: str,
        fee_config: Optional[FeeConfig] = None
    ):
        """
        初始化模拟交易引擎
        
        Args:
            user_id: 用户ID
            session_id: 会话ID
            fee_config: 费用配置(可选,默认使用长桥标准费率)
        """
        self.user_id = user_id
        self.session_id = session_id
        
        # 初始化费用计算器
        if fee_config is None:
            fee_config = self._get_default_fee_config()
        self.fee_calculator = FeeCalculator(fee_config)
    
    async def execute_order(
        self,
        symbol: str,
        side: str,
        quantity: Decimal,
        price: Decimal
    ) -> Order:
        """
        执行订单
        
        Args:
            symbol: 股票代码 (格式: CODE.MARKET, 如 AAPL.US)
            side: 买卖方向 ('buy' | 'sell')
            quantity: 数量
            price: 价格
        
        Returns:
            Order: 订单对象
        """
        # 1. 解析市场类型
        market = symbol.split('.')[-1]  # US 或 HK
        
        # 2. 计算交易费用
        trading_fee = self.fee_calculator.calculate_fee(
            quantity=quantity,
            price=price,
            side=side,
            market=market
        )
        
        # 3. 检查账户余额
        if side == 'buy':
            required_cash = (quantity * price) + trading_fee.total_fee
            if not self._has_sufficient_cash(required_cash, market):
                raise InsufficientFundsError("现金余额不足")
        
        # 4. 执行订单
        order = self._execute_order_internal(
            symbol=symbol,
            side=side,
            quantity=quantity,
            price=price
        )
        
        # 5. 扣除交易费用
        self._deduct_trading_fee(trading_fee, market)
        
        # 6. 记录费用到订单
        order.trading_fee = trading_fee
        
        # 7. 持久化订单
        await self._persist_order(order)
        
        return order
    
    def _deduct_trading_fee(self, trading_fee: TradingFee, market: str):
        """
        扣除交易费用
        
        Args:
            trading_fee: 费用明细
            market: 市场类型 (US | HK)
        """
        currency = 'USD' if market == 'US' else 'HKD'
        
        # 从账户现金中扣除费用
        current_cash = self.account.get_cash(currency)
        new_cash = current_cash - trading_fee.total_fee
        self.account.set_cash(currency, new_cash)
        
        # 记录费用日志
        self._log_fee_deduction(trading_fee, currency)
    
    @staticmethod
    def _get_default_fee_config() -> FeeConfig:
        """获取默认费用配置(长桥标准费率)"""
        return FeeConfig(
            us_fees=USFeeConfig(),
            hk_fees=HKFeeConfig()
        )

数据存储设计

1. PostgreSQL存储

Broker表扩展

-- 券商表中的config字段存储费用配置
-- config JSONB字段结构:
{
  "api_config": {
    "app_key": "...",
    "app_secret": "...",
    "access_token": "..."
  },
  "fee_config": {
    "us_fees": {
      "platform_fee_per_share": "0.005",
      "platform_fee_minimum": "1.0",
      "activity_fee_per_share": "0.000166",
      "activity_fee_maximum": "8.3",
      "clearing_fee_per_share": "0.003",
      "clearing_fee_max_pct": "0.07",
      "audit_fee_per_share": "0.000046",
      "audit_fee_minimum": "0.01"
    },
    "hk_fees": {
      "platform_fee_per_share": "0.005",
      "platform_fee_minimum": "1.0",
      "activity_fee_per_share": "0.000166",
      "activity_fee_maximum": "8.3",
      "clearing_fee_per_share": "0.003",
      "clearing_fee_max_pct": "0.07",
      "audit_fee_per_share": "0.000046",
      "audit_fee_minimum": "0.01"
    }
  }
}

Order表扩展

-- 订单表增加费用字段
ALTER TABLE orders ADD COLUMN trading_fee JSONB;

-- trading_fee JSONB字段结构:
{
  "platform_fee": "1.50",
  "activity_fee": "0.50",
  "clearing_fee": "0.90",
  "audit_fee": "0.14",
  "total_fee": "3.04",
  "currency": "USD",
  "calculation_details": {
    "quantity": 300,
    "price": "150.25",
    "side": "buy",
    "market": "US"
  }
}

2. Redis缓存

# 券商费用配置缓存
key: f"broker:fee_config:{broker_id}"
value: {
    "us_fees": {...},
    "hk_fees": {...}
}
ttl: 3600  # 1小时

# 交易会话费用配置缓存
key: f"trading:session:fee_config:{session_id}"
value: {
    "us_fees": {...},
    "hk_fees": {...}
}
ttl: 86400  # 24小时

前端配置界面

1. 费用配置表单

interface FeeConfigFormData {
  us_fees: USFeeConfig;
  hk_fees: HKFeeConfig;
}

interface USFeeConfig {
  // 平台费用
  platform_fee_per_share: number;     // 平台费(美元/股)
  platform_fee_minimum: number;       // 最低收费(美元)
  
  // 交易活动费用
  activity_fee_per_share: number;     // 交易活动费(美元/股)
  activity_fee_maximum: number;       // 最高收费(美元)
  
  // 交收费
  clearing_fee_per_share: number;     // 交收费(美元/股)
  clearing_fee_max_pct: number;       // 最高收费百分比
  
  // 综合审计费
  audit_fee_per_share: number;        // 综合审计费(美元/股)
  audit_fee_minimum: number;          // 最低收费(美元)
}

// HKFeeConfig 结构相同

2. 表单字段说明

字段 说明 默认值 Tooltip
平台费(每股) 每股交易平台费用,买入和卖出都收取 0.005 按成交股数计算,例如100股收取0.5美元
平台费(最低) 每笔订单最低收取的平台费 1.0 即使按股计算不足1美元,也收取1美元
交易活动费(每股) 每股交易活动费,仅卖出时收取 0.000166 按成交股数计算,仅适用于卖出订单
交易活动费(最高) 每笔订单最高收取的交易活动费 8.3 即使按股计算超过8.3美元,也只收取8.3美元
交收费(每股) 每股交收费用,买入和卖出都收取 0.003 按成交股数计算
交收费(最高百分比) 交收费最高收取交易额的百分比 0.07 例如交易额1000美元,最高收取70美元
综合审计费(每股) 每股综合审计费,买入和卖出都收取 0.000046 按成交股数计算
综合审计费(最低) 每笔订单最低收取的综合审计费 0.01 即使按股计算不足0.01美元,也收取0.01美元

关键特性

1. 费用配置灵活性

2. 费用计算准确性

3. 费用扣除可靠性

4. 费用透明度

安全与性能

1. 数据安全

2. 性能优化

3. 容错处理

扩展性

1. 新市场支持

2. 新费用类型

3. 费用策略