如何获取前一个交易日的持仓价值
请教各位大侠,我想通过持仓价值(context.portfolio.positions_value)来进行风控。如何才能获得前一个交易日的持仓价值?
问题描述
解决方案
在 JoinQuant(聚宽)平台中,context.portfolio.positions_value 记录的是当前时刻的持仓价值。由于 context 对象只维护账户的当前状态,并没有直接提供获取历史某一天总持仓价值的内置属性。
为了获取前一个交易日的持仓价值来进行风控,最简单且最可靠的方法是:利用全局变量 g 结合收盘后运行函数 after_trading_end 来记录每天收盘时的持仓价值。
实现思路
- 在
initialize函数中初始化一个全局变量(例如g.last_positions_value),用于存储前一天的持仓价值。 - 在每天收盘后执行的
after_trading_end函数中,将当天的context.portfolio.positions_value赋值给该全局变量。 - 在第二天的盘中交易逻辑(如
handle_data或market_open)中,直接调用g.last_positions_value即可用于风控判断。
代码示例
下面是一个完整的策略框架示例:
# 导入聚宽函数库
import jqdata
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 1. 初始化全局变量,记录前一交易日持仓价值
# 策略刚启动时没有前一日数据,可以设为0或初始资金
g.last_positions_value = 0
# 每天开盘时运行交易逻辑
run_daily(market_open, time='09:30')
# 每天收盘后运行,用于记录当天的最终状态
run_daily(after_trading_end, time='15:30')
def market_open(context):
# 3. 在盘中获取前一交易日的持仓价值,进行风控逻辑判断
previous_value = g.last_positions_value
current_value = context.portfolio.positions_value
log.info(f"前一交易日收盘持仓价值: {previous_value}")
log.info(f"当前持仓价值: {current_value}")
# --- 这里可以编写您的风控逻辑 ---
# 例如:如果当前持仓价值比昨天下跌超过5%,则清仓止损
if previous_value > 0 and (current_value - previous_value) / previous_value < -0.05:
log.warn("触发风控:持仓价值较昨日下跌超过5%,执行清仓!")
for security in context.portfolio.positions:
order_target(security, 0)
return # 触发风控后跳过后续买入逻辑
# --- 正常的买卖逻辑 ---
# order('000001.XSHE', 100)
def after_trading_end(context):
# 2. 每天收盘后,记录当天的持仓价值,作为明天的“前一交易日持仓价值”
g.last_positions_value = context.portfolio.positions_value
log.info(f"收盘记录:保存今日持仓价值 {g.last_positions_value} 供明日使用。")
注意事项
- 策略启动的第一天:在策略运行的第一个交易日,
after_trading_end还未执行过,此时g.last_positions_value的值是您在initialize中赋予的初始值(如0)。在编写风控逻辑时(如计算跌幅除以该值),需要做好防错处理(如if previous_value > 0:),避免除以零的报错。 - 出入金的影响:如果您在模拟盘中进行了手动出入金(
inout_cash),这会影响总资产(total_value),但不会直接影响持仓价值(positions_value)。如果您是用总资产做风控,请注意出入金带来的数值突变。 - 全局变量的持久化:在聚宽模拟盘中,
g对象会被自动序列化保存,因此即使模拟盘休眠重启,g.last_positions_value的数据也不会丢失,可以放心使用。