佣金与滑点¶
QTrade 内置四种 Commission 实现,覆盖大多数策略需要的模式。全部位于 qtrade.core.commission,共享抽象基类 Commission。
from qtrade.core import (
NoCommission, # default: 0
PercentageCommission, # X% of order value
FixedCommission, # flat fee per order
SlippageCommission, # X% slippage on order value
)
把实例传给 Backtest(..., commission=...) 或 TradingEnv(..., commission=...)。commission=None 等价于 NoCommission()。
接口¶
Commission.calculate_commission(order_size: int, fill_price: float) -> float
返回一笔成交的佣金(账户币种)。Broker 在成交时从 cash 扣除。order_size 的符号保留 —— 如果想买卖对称收费,在内部用 abs(order_size)。
自定义实现:
from qtrade.core.commission import Commission
class TieredCommission(Commission):
"""0.1% under $10k, 0.05% above (per fill)."""
def calculate_commission(self, order_size, fill_price):
notional = abs(order_size) * fill_price
rate = 0.001 if notional < 10_000 else 0.0005
return notional * rate
内置实现¶
NoCommission¶
NoCommission()
始终返回 0.0。不传任何参数时的默认值。用于和 Buy & Hold 做干净对比,或者建模零佣金券商。
PercentageCommission¶
PercentageCommission(percentage=0.001) # 0.1%
按 abs(order_size) * fill_price * percentage 收费。
股票(佣金按名义本金的 bps 报价)和加密现货(taker 费率通常 0.05–0.1%)的标准模型。
FixedCommission¶
FixedCommission(fixed_fee=1.0) # $1 per fill
无论 size 和价格如何,返回固定费用。适合 期货(交易所按合约计费)和按笔收单一费用的折扣券商。
对于含多个佣金组件(交易所 + 清算 + 券商)的期货,加总后传入:FixedCommission(fixed_fee=2.50)。
SlippageCommission¶
SlippageCommission(slippage_percentage=0.0005) # 5 bps
数学上与 PercentageCommission 相同,但意图不同 —— 这个建模的是穿越买卖价差的价格冲击,不是交易所费用。适用场景:
想在显式佣金之上额外加上滑点。
想让成本按名义本金缩放,但在报表中和「佣金」分开统计。
# Crypto spot: 0.1% taker fee + 0.05% slippage
class CryptoCost(Commission):
def __init__(self):
self.fee = PercentageCommission(0.001)
self.slip = SlippageCommission(0.0005)
def calculate_commission(self, order_size, fill_price):
return self.fee.calculate_commission(order_size, fill_price) \
+ self.slip.calculate_commission(order_size, fill_price)
如何选择合适的模型¶
资产类别 |
典型设置 |
|---|---|
美股(零售) |
|
美股(机构) |
|
期货 |
|
外汇 |
|
加密现货 |
|
加密永续合约 |
|
不确定的话,回测时分别带和不带佣金跑一遍。差距告诉你策略的成本敏感度 —— 高换手率策略经常成本前看起来很美,扣掉成本就亏钱。
A note on the built-in Contract specs¶
The qtrade.contracts module ships specs for common futures (GC_COMEX,
ES_CME, CL_NYMEX, etc.) that bundle a multiplier and a default
margin_ratio. The multiplier values are part of the contract design
and rarely change. The margin_ratio values are conventional starting
points only — actual margin is set by the exchange (SPAN) and your
broker, and floats over time. Verify against your account before
trusting backtest leverage numbers.
To override, either tweak with dataclasses.replace:
from dataclasses import replace
from qtrade.contracts import GC_COMEX
MY_GC = replace(GC_COMEX, margin_ratio=0.07)
…or define your own:
from qtrade.contracts import Contract
SHFE_AU = Contract(multiplier=1000, margin_ratio=0.08, name="SHFE Gold")
未建模的部分¶
Maker / taker 不对称。所有成交按单一费率收费。如需对限价单按 maker 费率收费,写一个自定义
Commission并根据订单是否有limit价格分支。买卖价差。Broker 用
Close(或下一根Open)成交市价单。买卖价差未建模 ——SlippageCommission是最接近的近似。资金费率 / 借券成本。未建模。对于长期空仓或永续合约资金费率,需要在策略的
on_bar_close里手动扣cash。按资产收费。多资产回测中单个
Commission实例应用到所有资产。如需按资产差异化费率,写一个根据订单_fill_price分支的自定义Commission,或在策略逻辑里包装。