3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在聚宽(JoinQuant)平台进行 ETF 轮动策略实盘或模拟交易时,随着资金规模的增长,策略拥挤度、流动性不足和信号反转时的滑点会成为蚕食收益的主要因素。本文将指导您如何利用聚宽 API 建立一套完整的监控与控制机制。
策略拥挤通常表现为大量资金在同一时间段买入相同的 ETF。在聚宽中,我们可以通过监控目标 ETF 的**成交量占比(Volume Ratio)**来评估自身交易对市场的冲击:
set_option('order_volume_ratio', value) 限制单笔订单占当日总成交量的比例。例如,设置 set_option('order_volume_ratio', 0.1),确保下单量不超过全市场成交量的 10%。get_money_flow 获取资金流向数据,评估是否有大单资金异常流入或流出目标 ETF。在实盘或高频模拟中,仅看日线成交量是不够的,必须实时评估盘口深度。聚宽提供了获取实时 Tick 数据的接口:
get_current_tick(security) 获取最新的 Tick 对象。通过 Tick 对象中的 a1_v ~ a5_v(卖一到卖五量)和 b1_v ~ b5_v(买一到买五量)来评估盘口深度。set_option('match_with_order_book', True)
当轮动信号发生反转(例如从 A ETF 切换到 B ETF)时,大额的买卖单会直接推高买入价并压低卖出价。控制滑点风险的方法如下:
set_slippage 设置符合 ETF 真实交易摩擦的滑点。例如,设置百分比滑点:# 设置 ETF 交易滑点为万分之二
set_slippage(PriceRelatedSlippage(0.0002), type='fund')
MarketOrderStyle(limit_price) 设置保护价,防止极端滑点:# 以市价单买入,但成交价不得高于 2.50 元
order('510300.XSHG', 10000, style=MarketOrderStyle(2.50))
以下代码展示了如何在每日开盘及盘中,动态评估 ETF 池的流动性,并根据盘口深度计算安全下单量:
import jqdata
from jqlib.alpha101 import *
def initialize(context):
# 开启真实价格模式
set_option('use_real_price', True)
# 设置基准
set_benchmark('000300.XSHG')
# 设定 ETF 轮动池
g.etf_pool = ['510300.XSHG', '510500.XSHG', '159915.XSHE']
# 运行监控函数
run_daily(market_open, time='every_bar')
def market_open(context):
for etf in g.etf_pool:
# 1. 获取当前盘口 Tick 数据
tick = get_current_tick(etf)
if tick is None:
continue
# 计算买一到买三的总深度,卖一到卖三的总深度
bid_depth = tick.b1_v + tick.b2_v + tick.b3_v
ask_depth = tick.a1_v + tick.a2_v + tick.a3_v
# 2. 获取当前单位时间的成交量(分钟 Bar)
current_data = get_current_data()
last_price = current_data[etf].last_price
# 3. 评估滑点风险:若盘口深度小于预期交易量的 3 倍,则判定为高滑点风险
target_amount = 20000 # 假设我们计划交易 20000 股
if ask_depth < target_amount * 3:
log.warn("警告: %s 卖盘深度不足 (%d < %d),信号反转时可能存在高滑点风险!" % (etf, ask_depth, target_amount * 3))
# 采用限价单分批挂单,或缩小本次调仓规模
limit_price = tick.current * 1.001 # 限制买入溢价在 0.1% 以内
order(etf, target_amount, style=LimitOrderStyle(limit_price))
else:
# 深度充足,直接下单
order(etf, target_amount)