第三章 交易成本分析:量化每一分钱的代价
做量化交易,说白了就是在跟成本赛跑。
我刚开始做算法交易那会儿,总觉得策略赚钱就行,成本那点小钱无所谓。结果呢?年终一算账,利润被吃掉了一大块。嗯,从那以后,我再也不敢忽视交易成本了。
3.1 显性成本:看得见的“手续费”
显性成本,就是交易所和券商明明白白告诉你要交的钱。这部分最直观,也最好量化。
3.1.1 佣金
佣金是券商收的服务费。国内A股市场,佣金一般在万分之一到万分之三之间。我习惯把佣金分成两部分:
- 固定佣金:每笔交易收一个固定金额,比如5元起步
- 比例佣金:按成交金额的百分比收取
举个例子,你买10万元的股票,佣金是万分之二点五:
佣金 = 100,000 × 0.00025 = 25元
如果佣金有最低5元限制,那这笔交易实际收25元。但如果你只买1万元,按比例算只有2.5元,券商就会收你5元。这就是为什么小单交易成本占比特别高。
3.1.2 印花税与过户费
印花税是交给国家的,目前A股是卖出时收千分之一。过户费是交给登记结算公司的,万分之零点二左右。
| 费用类型 | 费率 | 收取方向 |
|---|---|---|
| 佣金 | 万1-万3 | 买卖双向 |
| 印花税 | 千1 | 仅卖出 |
| 过户费 | 万0.2 | 买卖双向 |
我在项目中遇到过最坑的情况:有人做高频交易,一天来回几十次,结果印花税和佣金加起来比利润还高。所以,做高频策略前,一定要先把显性成本算清楚。
3.2 隐性成本:看不见的“吸血鬼”
隐性成本才是真正考验功力的地方。它们看不见摸不着,但每一笔都在吞噬你的收益。
3.2.1 市场冲击成本
市场冲击,说白了就是你的大单子把价格打偏了。你买的时候把价格推高了,卖的时候把价格砸低了。
为什么会这样?因为市场深度有限。你想想看,买一档只有1000股,你突然砸进去1万股,那后面的9000股就得用更高的价格成交。
量化市场冲击,我常用这个公式:
冲击成本 = (成交均价 - 订单簿中间价) / 订单簿中间价 × 100%
举个例子:
订单簿中间价 = 10.00元
你买入1万股,成交均价 = 10.05元
冲击成本 = (10.05 - 10.00) / 10.00 × 100% = 0.5%
0.5%什么概念?如果你一年做100次这样的交易,光冲击成本就吃掉50%的收益。恐怖吧?
核心观点:市场冲击与订单规模成正比,与市场流动性成反比。流动性越差的股票,冲击成本越大。
3.2.2 延迟成本
延迟成本,就是“等”出来的代价。你的订单从发出到成交,中间有网络延迟、交易所处理延迟、撮合延迟。
我记得有一次做期货套利,策略信号出来时价格是100.00,等我的订单到达交易所,价格已经变成100.02了。这0.02的差价,就是延迟成本。
量化延迟成本,我一般用这个思路:
延迟成本 = (实际成交价 - 信号发出时的价格) × 交易数量
延迟成本受几个因素影响:
- 网络延迟:从你的服务器到交易所机房的距离
- 系统处理延迟:策略计算、风控检查的时间
- 交易所撮合延迟:订单进入撮合队列的等待时间
避坑指南:我曾经以为延迟成本只影响高频交易。后来发现,即使是分钟级别的策略,如果市场波动剧烈,几秒钟的延迟也能造成不小的损失。
3.2.3 机会成本
机会成本,就是你因为没成交而错过的利润。这个最隐蔽,也最容易被忽视。
举个例子:你想在10.00元买入某股票,结果只成交了一半。后来股价涨到10.50元,那没成交的那一半,就产生了机会成本。
量化机会成本,我习惯这样算:
机会成本 = (目标成交量 - 实际成交量) × (最终价格 - 目标价格)
如果最终价格高于目标价格,机会成本就是正的(你亏了)。如果最终价格低于目标价格,机会成本是负的(你反而赚了)。
3.3 如何量化这些成本?
量化交易成本,不能靠感觉。我有一套自己的量化框架,分享给你。
3.3.1 建立成本模型
一个完整的交易成本模型,应该包含:
总成本 = 显性成本 + 隐性成本
显性成本 = 佣金 + 印花税 + 过户费
隐性成本 = 市场冲击 + 延迟成本 + 机会成本
3.3.2 实战量化代码
下面是我常用的一个成本量化函数:
def calculate_trading_cost(order_size, price, commission_rate,
stamp_tax_rate, transfer_fee_rate,
market_impact_factor):
"""
计算交易总成本
"""
# 显性成本
commission = order_size * price * commission_rate
stamp_tax = order_size * price * stamp_tax_rate # 仅卖出时
transfer_fee = order_size * price * transfer_fee_rate
explicit_cost = commission + stamp_tax + transfer_fee
# 隐性成本 - 市场冲击
# 使用平方根模型:冲击成本与订单规模的平方根成正比
market_impact = market_impact_factor * (order_size ** 0.5) * price
# 延迟成本(简化版)
latency_cost = 0.0001 * price * order_size # 假设0.01%的延迟影响
# 机会成本(简化版)
opportunity_cost = 0.0005 * price * order_size # 假设0.05%的未成交概率
implicit_cost = market_impact + latency_cost + opportunity_cost
total_cost = explicit_cost + implicit_cost
return {
'explicit_cost': explicit_cost,
'implicit_cost': implicit_cost,
'total_cost': total_cost,
'cost_per_share': total_cost / order_size
}
# 使用示例
result = calculate_trading_cost(
order_size=10000, # 1万股
price=10.0, # 10元/股
commission_rate=0.00025, # 万2.5
stamp_tax_rate=0.001, # 千1
transfer_fee_rate=0.00002, # 万0.2
market_impact_factor=0.001 # 市场冲击系数
)
print(f"总成本: {result['total_cost']:.2f}元")
print(f"每股成本: {result['cost_per_share']:.4f}元")
注意:市场冲击系数需要根据具体股票的历史数据回测得到。不同股票、不同时间段,这个系数差异很大。我建议至少用3个月的数据来校准这个参数。
3.4 成本分析框架图
下面这张图,是我自己总结的交易成本分析框架。它把显性成本和隐性成本的关系,以及如何量化它们,都串起来了。
3.5 实战中的成本优化建议
说了这么多理论,最后分享几个我在实战中总结的优化技巧:
- 拆单策略:大单拆成小单,降低市场冲击。我习惯用TWAP或VWAP算法来拆单。
- 选择流动性好的时段:开盘和收盘前半小时流动性最好,冲击成本最低。
- 使用限价单:市价单虽然成交快,但冲击成本高。限价单可以控制成交价格。
- 监控延迟:定期检查你的网络延迟和系统处理时间,确保在合理范围内。
- 回测时加入成本模型:很多人在回测时忽略成本,结果实盘时发现策略根本不赚钱。
我的经验:做回测时,我习惯把成本设定为实际成本的1.5倍。这样即使实盘时成本超预期,策略也能扛得住。这叫“压力测试”,说白了就是给自己留点安全垫。
交易成本分析,说到底就是搞清楚每一分钱花在哪了。显性成本好算,隐性成本需要经验。但只要你把量化框架搭好了,这些成本都能算得明明白白。
记住一句话:控制成本,就是增加利润。
公众号:蓝海资料掘金营,微信deep3321