🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

深入理解JoinQuant聚宽API中的context对象及参数传递原理

joinquant | 发布时间: 2026/6/1
以下内容由 EasyQuant 生成。

问题描述

函数传入context对象的问题

请问聚宽框架显示的initialize(context)初始化函数、handle_data(context, data)、before_trading_start(context)等函数,为什么定义的时候都需要传入一个context参数呢,百度了下说context是策略运行上下文环境对象,该对象将会在你的算法策略的任何方法之间做传递,但看了有些策略里定义了止损函数如下,这个函数确没有传入context对象。
def dp_stoploss(kernel=2, n=10, zs=0.03):
'''
方法1:当大盘N日均线(默认60日)与昨日收盘价构成“死叉”,则发出True信号
方法2:当大盘N日内跌幅超过zs,则发出True信号
'''

# 止损方法1:根据大盘指数N日均线进行止损
if kernel == 1:
t = n+2
hist = attribute_history('000300.XSHG', t, '1d', 'close', df=False)
temp1 = sum(hist['close'][1:-1])/float(n)
temp2 = sum(hist['close'][0:-2])/float(n)
close1 = hist['close'][-1]
close2 = hist['close'][-2]
if (close2 > temp2) and (close1 < temp1):
return True
else:
return False
# 止损方法2:根据大盘指数跌幅进行止损
elif kernel == 2:
hist1 = attribute_history('000300.XSHG', n, '1d', 'close',df=False)
if ((1-float(hist1['close'][-1]/hist1['close'][0])) >= zs):
return True
else:
return False
想请问以下传入context参数的原理是什么?以及什么时候可以不传入context对象,谢谢!

解决方案

什么是 context 对象?\n\n在 JoinQuant(聚宽)量化平台中,context 是一个策略运行上下文环境对象。它就像是策略的“大管家”,实时记录并保存着策略在运行过程中的所有核心状态信息。根据聚宽 API 文档,context 对象包含了以下重要信息:\n\n- 账户与资金信息:如 context.portfolio.available_cash(可用资金)、context.portfolio.total_value(总资产)。\n- 持仓信息:如 context.portfolio.positions(当前持仓的标的及数量)。\n- 时间信息:如 context.current_dt(当前策略运行到的逻辑时间)。\n\n## 为什么系统函数必须传入 context?\n\n聚宽的策略框架是基于事件驱动(回调机制)的。像 initializehandle_databefore_trading_start 等函数,都是系统保留的回调函数。\n\n原理:在回测或模拟交易运行时,聚宽的底层引擎会在特定的时间点(如每天开盘前、每分钟/每天的交易时刻)自动调用这些函数。为了让你的策略代码能够知道“现在账户里还有多少钱”、“现在是几月几号”、“现在持有哪些股票”,底层引擎在调用这些函数时,会主动把包含最新状态的 context 对象作为参数传递进去。因此,你在定义这些系统函数时,必须预留一个 context 参数来接收引擎传过来的状态。\n\n## 为什么自定义函数可以不传入 context?\n\n在你提供的 dp_stoploss 示例中,这是一个用户自定义的函数,它是由你自己在代码中主动调用的,而不是由底层引擎自动调用的。\n\n在这个函数内部,你只使用了 attribute_history 这个全局 API 来获取大盘的历史数据,并进行了简单的数学计算。该函数内部并没有用到任何与当前账户资金、持仓状态或当前精确时间相关的信息。因此,你完全不需要把 context 传给它。\n\n## 什么时候需要传入 context,什么时候不需要?\n\n1. 必须传入 context 的情况:\n- 系统回调函数:如 initialize, handle_data, before_trading_start, after_trading_end 等,必须按照 API 规范定义 context 参数。\n- 需要使用账户/时间状态的自定义函数:如果你写了一个自定义函数,且该函数内部需要判断当前可用资金(context.portfolio.available_cash)、检查当前持仓(context.portfolio.positions)或获取当前逻辑时间(context.current_dt),那么你在调用这个自定义函数时,就必须把 context 作为参数传给它。\n\n2. 可以不传入 context 的情况:\n- 纯数据处理或逻辑判断的自定义函数:如果你的自定义函数仅仅是调用全局 API(如 get_price, attribute_history, history)获取行情数据,或者只是读取全局变量 g(如 g.security),进行纯粹的数学计算或指标判断(如你示例中的大盘止损判断),那么就不需要传入 context。\n\n总结context 是用来传递账户和时间状态的。系统函数必须带它是为了接收引擎的状态;自定义函数带不带它,完全取决于你函数内部是否需要用到这些状态信息。