问题描述
/
解决方案
首先,需要纠正一个常见的误区:根据 ptrade 官方 API 文档的规定,如果在非交易日调用 get_trading_day(0),它返回的不是上一交易日,而是下一交易日的日期。
get_trading_day(day) 返回值逻辑详解
get_trading_day(day) 函数用于获取当前时间数天前或数天后的交易日期。其核心逻辑如下:
-
参数
day的含义:day > 0:获取数天后的交易日。day < 0:获取数天前的交易日。day = 0(默认值):获取当前交易日。
-
非交易日的特殊处理:
- 当
day = 0时,如果当前日期本身就是一个交易日,则直接返回当天。 - 如果当前日期为非交易日(例如周末或法定节假日),则返回下一交易日的日期。
- 当
举个例子:
假设今天是 2023年10月21日(周六,非交易日)。
- 调用
get_trading_day(0),系统会判断今天不是交易日,因此向后寻找,返回 2023年10月23日(周一)。 - 如果你想获取上一个交易日(即周五),你应该明确传入负数参数:
get_trading_day(-1),这会返回 2023年10月20日(周五)。
环境差异(回测 vs 研究 vs 交易)
理解该函数还需要注意“当前时间”在不同模块下的定义:
- 回测模块:当前时间指的是策略运行到的虚拟回测日期(即
context.blotter.current_dt)。 - 研究模块:当前时间指的是你实际调用代码的当天真实日期。
- 交易模块:当前时间指的是实际运行的当天真实日期。
代码示例
如果你希望在任何情况下(无论当天是否为交易日)都获取最近的一个已过去的交易日(包含今天),你可以结合当前日期进行判断,或者直接使用 get_trade_days 获取历史列表取最后一个:
def initialize(context):
g.security = '000001.SZ'
set_universe(g.security)
def handle_data(context, data):
# 获取当前交易日(如果今天是周末,会返回下周一)
current_or_next_trade_day = get_trading_day(0)
log.info(f"get_trading_day(0) 返回: {current_or_next_trade_day}")
# 明确获取前一个交易日
prev_trade_day = get_trading_day(-1)
log.info(f"前一个交易日: {prev_trade_day}")
# 明确获取后一个交易日
next_trade_day = get_trading_day(1)
log.info(f"后一个交易日: {next_trade_day}")
总结:如果你发现返回了不符合预期的日期,请检查你所处的环境(尤其是研究环境下周末调用的情况),并牢记 day=0 在非交易日是向后寻找下一交易日的规则。如果需要获取上一个交易日,请务必使用 get_trading_day(-1)。