3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
LOF(Listed Open-Ended Fund)上市开放式基金既可以在二级市场像股票一样交易,也可以在一级市场进行申购和赎回。由于二级市场交易价格由市场供求决定,而一级市场申购赎回价格基于基金单位净值(Unit Net Value),两者之间经常会出现价差,从而产生折价套利和溢价套利的机会。
在聚宽(JoinQuant)平台上,我们可以通过获取 LOF 基金的二级市场行情和一级市场净值数据,构建高效率的套利策略。
要识别折溢价机会,需要同时获取以下两类数据:
get_price 或 attribute_history 获取最新收盘价或分钟 Bar 价格。get_extras 获取 unit_net_value(基金单位净值)。from jqdata import *
def get_lof_arbitrage_data(context, lof_code):
# 获取二级市场最新价格
current_data = get_current_data()
market_price = current_data[lof_code].last_price
# 获取前一交易日的基金单位净值
net_value_df = get_extras('unit_net_value', [lof_code],
end_date=context.previous_date, count=1)
net_value = net_value_df[lof_code][0]
return market_price, net_value
(二级市场价格 - 基金单位净值) / 基金单位净值在聚宽中,LOF 基金的二级市场买卖可以直接使用 order 或 order_target 函数。需要注意的是,场内申购和赎回在回测中需要通过资金和持仓的调整来模拟,或者通过二级市场反向操作进行模拟(由于 A 股 T+2 申购份额到账限制,实盘中需注意时间差风险)。
def handle_data(context, data):
lof_code = '161219.XSHE' # 示例 LOF 基金
market_price, net_value = get_lof_arbitrage_data(context, lof_code)
if not market_price or not net_value:
return
premium_rate = (market_price - net_value) / net_value
cash = context.portfolio.available_cash
# 设定套利阈值
arbitrage_threshold = 0.015
# 1. 溢价套利:二级市场价格远高于净值 -> 场内申购,二级市场卖出(需有底仓)
if premium_rate > arbitrage_threshold:
if context.portfolio.positions[lof_code].closeable_amount > 0:
# 卖出场内持仓
order_target(lof_code, 0)
log.info(f"触发溢价套利,卖出场内 LOF: {lof_code}")
# 2. 折价套利:二级市场价格远低于净值 -> 二级市场买入,场外赎回
elif premium_rate < -arbitrage_threshold:
if cash > 10000:
# 二级市场买入 LOF 基金
order_value(lof_code, cash)
log.info(f"触发折价套利,二级市场买入 LOF: {lof_code}")
套利策略是典型的“高频、低利润率”策略,交易成本是决定套利能否成功的关键。在聚宽回测中,必须严格设置手续费并开启真实价格模式。
在 initialize 中必须开启真实价格,以确保获取的二级市场价格和账户资金处理符合历史真实情况:
def initialize(context):
# 开启真实价格模式
set_option('use_real_price', True)
LOF 基金在二级市场交易不征收印花税,佣金通常比股票更低。使用 set_order_cost 进行单独设置:
# 设置场内基金交易费用:买入佣金万分之三,卖出佣金万分之三,无印花税,最低 5 元
set_order_cost(OrderCost(open_tax=0, close_tax=0,
open_commission=0.0003, close_commission=0.0003,
min_commission=5), type='fund')
回测结束后,应重点观察以下指标: