3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在量化投资中,高换手率策略(如日内高频、多因子多空轮动)往往伴随着高昂的交易成本。如果回测中未加入真实的交易成本(佣金、印花税、滑点),回测结果(毛收益)通常会严重失真。通过在聚宽(JoinQuant)平台中合理设置 set_order_cost 和 set_slippage,我们可以精确模拟真实交易,并对比分析毛收益与扣除成本后的净收益、夏普比率(Sharpe)及换手率的变化。
在聚宽中,交易成本主要由两部分组成:
set_order_cost 设置。set_slippage 设置,模拟真实市场中因流动性不足产生的价差。聚宽默认的股票手续费为:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税,每笔交易最低扣5元。可以使用 OrderCost 对象进行自定义设置:
# 股票类交易费率设置示例
set_order_cost(OrderCost(
open_tax=0, # 买入印花税(A股买入免税)
close_tax=0.001, # 卖出印花税(千分之一)
open_commission=0.0003, # 买入佣金(万分之三)
close_commission=0.0003,# 卖出佣金(万分之三)
close_today_commission=0,
min_commission=5 # 最低佣金5元
), type='stock')
滑点是高换手率策略的“利润杀手”。聚宽支持固定值滑点和百分比滑点:
# 方式 A:百分比滑点(例如双边 0.2%,即买入加 0.1%,卖出减 0.1%)
set_slippage(PriceRelatedSlippage(0.002), type='stock')
# 方式 B:固定值滑点(例如每股固定滑点 0.02 元)
set_slippage(FixedSlippage(0.02), type='stock')
为了直观评估交易成本对不同换手率策略的敏感性影响,我们可以通过以下公式进行理论测算,并在回测中进行实证:
$$\text{净年化收益} \approx \text{毛年化收益} - (\text{单边交易成本} + \text{单边滑点}) \times \text{年化单边换手率} \times 2$$
以下提供一个多股票追涨/动量调仓策略。我们通过开启和关闭交易成本,来对比策略的毛收益与净收益表现。
import jqdata
import pandas as pd
import numpy as np
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 强烈建议开启真实价格(动态复权)模式
set_option('use_real_price', True)
# ==================== 交易成本敏感性设置 ====================
# 1. 启用真实佣金与印花税
set_order_cost(OrderCost(
open_tax=0,
close_tax=0.001,
open_commission=0.0003,
close_commission=0.0003,
min_commission=5
), type='stock')
# 2. 启用滑点(此处设置双边 0.2% 的百分比滑点进行敏感性测试)
set_slippage(PriceRelatedSlippage(0.002), type='stock')
# ==========================================================
# 策略参数
g.stocks = ['000001.XSHE', '000002.XSHE', '000004.XSHE', '000005.XSHE']
g.hold_days = 3 # 调仓周期短,换手率高
# 定时运行
run_daily(market_open, time='09:30')
def market_open(context):
# 简单的均线突破逻辑,产生高频调仓
for security in g.stocks:
close_data = attribute_history(security, 5, '1d', ['close'])
if close_data.empty:
continue
MA5 = close_data['close'].mean()
current_price = close_data['close'][-1]
cash = context.portfolio.available_cash
# 突破MA5 1.005倍买入
if current_price > 1.005 * MA5 and cash > 0:
# 目标价值下单,自动计算换手
order_value(security, cash / len(g.stocks))
log.info("买入标的: %s" % security)
# 低于MA5 0.995倍卖出
elif current_price < 0.995 * MA5 and context.portfolio.positions[security].closeable_amount > 0:
order_target(security, 0)
log.info("卖出平仓: %s" % security)
# 记录当前持仓价值,用于归因分析
record(positions_value=context.portfolio.positions_value)
运行上述回测后,您可以在聚宽回测结果页面的**“归因分析”和“风险指标”**中查看以下关键数据:
g.hold_days 或突破阈值,可以明显改变换手率。