问题描述
market_open(context) 和handle_data(context, data)函数括号里默认都是这么写的,但是不知道具体起的作用是什么,函数里怎么引用’context‘和’data‘?
解决方案
在 JoinQuant(聚宽)量化平台编写策略时,context 和 data 是两个最核心的变量。它们分别代表了账户的上下文状态和标的的行情切片数据。下面为您详细解析它们的作用以及如何在函数中引用。
一、 context 变量详解
1. 作用是什么?
context 是一个全局的上下文对象(Context 对象),它贯穿于策略运行的整个生命周期。无论是在 handle_data 还是通过 run_daily 注册的自定义函数(如 market_open)中,它都包含了当前的账户资金、持仓信息、运行时间等核心状态。
2. 常用的属性有哪些?
context.portfolio:总账户信息。包含可用资金、总资产、持仓字典等。context.portfolio.available_cash:当前账户的可用资金。context.portfolio.positions:当前持仓字典,key 是标的代码,value 是Position对象(包含持仓量、成本等)。context.current_dt:当前策略运行的逻辑时间(datetime.datetime对象)。context.previous_date:前一个交易日(datetime.date对象)。
3. 如何在函数中引用?
def market_open(context):
# 1. 获取当前可用资金
cash = context.portfolio.available_cash
print("当前可用资金:", cash)
# 2. 获取当前时间
current_time = context.current_dt
print("当前运行时间:", current_time)
# 3. 检查某只股票是否在持仓中,并获取可卖出的数量
security = '000001.XSHE'
if security in context.portfolio.positions:
amount = context.portfolio.positions[security].closeable_amount
print(f"{security} 的可卖数量为:{amount}")
二、 data 变量详解
1. 作用是什么?
data 变量仅存在于 handle_data(context, data) 函数中。它是一个字典(dict),key 是标的代码,value 是当时的 SecurityUnitData 对象。它存放了前一个单位时间(按天回测是前一天,按分钟回测是前一分钟)的行情数据切片。
注意:为了加速,data 里面的数据是按需获取的,只有当你使用 data[security] 时,该标的的数据才会被加载。
2. 常用的属性和方法有哪些?
假设 d = data['000001.XSHE']:
d.close:前一个单位时间的收盘价。d.open/d.high/d.low/d.volume/d.money:开盘价、最高价、最低价、成交量、成交额。d.mavg(days):获取过去days天的每天收盘价的平均值(自带的计算均线方法)。d.isnan():判断数据是否有效(如停牌或未上市返回 True)。
3. 如何在函数中引用?
def handle_data(context, data):
security = '000001.XSHE'
# 1. 获取该股票前一单位时间的收盘价
current_price = data[security].close
# 2. 获取该股票过去5天的平均价
ma5 = data[security].mavg(5)
# 3. 判断是否停牌,如果没有停牌且价格高于5日均线,则买入
if not data[security].isnan():
if current_price > ma5:
order(security, 100)
三、 market_open 与 handle_data 的区别
handle_data(context, data):是系统默认的按频率(天/分钟)调用的函数。它自带data参数,可以直接快速获取当前切片的行情。market_open(context):通常是你自己定义的函数,通过run_daily(market_open, time='09:30')注册为定时任务。它只有context参数,没有data参数。如果你在这个函数里需要获取行情数据,不能用data,而必须使用 JoinQuant 提供的数据 API,例如attribute_history或get_price。
在 market_open 中获取数据的替代方法:
def market_open(context):
security = '000001.XSHE'
# 因为没有 data 变量,所以使用 attribute_history 获取过去1天的收盘价
hist = attribute_history(security, 1, '1d', ['close'])
current_price = hist['close'][-1]
print("当前价格:", current_price)
总结:context 帮你管钱、管仓位、看时间;data 帮你快速看盘(仅限 handle_data)。在自定义定时函数中,用数据 API 替代 data 即可。