3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在JoinQuant(聚宽)平台中,要在回测图表下方添加自定义的曲线,可以使用 record() 函数。
关于你提到的**“绿线有除权,不准确”**的问题,这是因为在开启了真实价格模式(use_real_price=True)后,直接使用收盘价计算收益率会受到分红派息(除权除息)的影响,导致曲线出现向下的跳空缺口。
为了画出准确的复权收益率曲线,最巧妙且高效的方法是:利用每天的真实涨跌幅进行累乘。在聚宽的 data 对象中,data[stock].returns 直接提供了该股票当天的相对收益比例 (close - pre_close) / pre_close,这个值平台底层已经做好了复权处理,不会受到除权除息的影响。
以下是完整的策略代码示例,实现了买入持有,并在附图中绘制多只股票的同期复权收益率曲线:
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格),实盘和回测强烈建议开启
set_option('use_real_price', True)
# 定义策略要买入持有的目标股票(例如:平安银行)
g.target_stock = '000001.XSHE'
# 定义你想在附图中对比收益率的其他股票列表
# 例如:万科A, 贵州茅台
g.compare_stocks = ['000002.XSHE', '600519.XSHG']
# 初始化一个字典,用于记录对比股票的累计净值(初始为1.0)
g.cum_returns = {stock: 1.0 for stock in g.compare_stocks}
def handle_data(context, data):
# 1. 简单的买入持有策略逻辑
if context.portfolio.positions[g.target_stock].total_amount == 0:
# 如果没有持仓,则全仓买入
order_value(g.target_stock, context.portfolio.available_cash)
log.info("买入持有: %s" % g.target_stock)
# 2. 计算并绘制对比股票的同期复权收益率曲线
record_dict = {}
for stock in g.compare_stocks:
# 确保股票当天没有退市或未上市
if not data[stock].isnan():
# data[stock].returns 是当天的涨跌幅,平台已处理好复权
daily_return = data[stock].returns
# 累乘计算累计净值
g.cum_returns[stock] *= (1 + daily_return)
# 转换为百分比收益率,例如 1.05 -> 5.0
pct_return = (g.cum_returns[stock] - 1) * 100
# 将股票名称作为曲线的图例名称
# 为了图例好看,可以获取股票的中文名
stock_name = get_security_info(stock).display_name
record_dict[stock_name] = pct_return
# 使用 record 函数将数据画到图表上
# record 函数接受 key=value 形式的参数,这里使用 ** 解包字典
if record_dict:
record(**record_dict)
g.cum_returns 字典:在 initialize 中初始化为 1.0,代表本金净值。data[stock].returns:这是聚宽 API 提供的一个非常方便的属性,它等于 (close - pre_close) / pre_close。即使当天发生了分红送股,pre_close 也是调整后的前收盘价,因此算出来的 returns 是完全真实的单日涨跌幅。g.cum_returns[stock] *= (1 + daily_return),每天将当天的涨跌幅乘到累计净值上,完美避开了跨期复权因子计算的复杂性。record(**record_dict):将计算好的百分比收益率动态传入 record 函数,回测完成后,图表下方就会自动生成这几只股票平滑、准确的复权收益率曲线。