问题描述
# 导入函数库
from jqdata import *
# 初始化函数,设定基准等等
def initialize(context):
run_daily(market_open, time='open', reference_security='000300.XSHG')
## 开盘时运行函数
def market_open(context):
print(1)
return 2
上面是一个简单的回测,期望的结果是返回1,2,1,2...的序列,但是打印的日志只有1没有2. 看起来return方法被忽略了。
请教一下聚宽工作人员,如果return被忽略,那么我如何设置函数的返回值呢?或者设置函数的终止点呢?
比如说:满足某个条件,那么该函数在当天终止不再执行,在之后的时间,继续执行。因为根据我的理解,聚宽的run_daily函数就是把某个函数每天执行一次,然而实际上return被忽略了。
def market_open(context):
if sth
return
解决方案
您好!关于您在聚宽(JoinQuant)回测环境中遇到的 return 方法的问题,这里为您做详细的解答:
1. 为什么 return 2 没有被打印出来?
在聚宽的框架中,像 market_open(context) 这样的函数被称为回调函数。当您使用 run_daily 注册了这个函数后,是聚宽的底层回测引擎在每天的指定时间去调用它。
因为调用方是底层引擎,引擎在执行完您的函数后,并不会接收、处理或打印您的返回值。所以 return 2 中的 2 直接被引擎丢弃了。而 print(1) 是您显式调用的打印命令,所以会在日志中显示。
2. 如何设置函数的返回值?
由于回调函数是由引擎调用的,设置返回值没有实际意义(因为您无法在策略代码中接收这个返回值)。
如果您希望在 market_open 函数中计算出某个结果,并在策略的其他地方(比如另一个定时函数或第二天的执行中)使用,您应该使用全局变量对象 g 来保存状态。例如:
def initialize(context):
g.my_signal = 0
run_daily(market_open, time='open')
run_daily(check_signal, time='14:00')
def market_open(context):
print(1)
# 用 g 变量代替 return 来传递数据
g.my_signal = 2
def check_signal(context):
print("获取到的信号是:", g.my_signal)
3. 如何设置函数的终止点(提前退出)?
您的理解非常正确!如果您希望在满足某个条件时,当天该函数立即终止不再往下执行,但第二天继续正常触发,直接使用 return 是完全正确且标准的 Python 语法。
return 并没有被忽略,它确实结束了当前函数的执行,只是它的“返回值”被引擎忽略了。
正确的提前终止示例:
def market_open(context):
# 假设获取当前可用资金
cash = context.portfolio.available_cash
# 如果资金不足,当天直接结束,不再执行后续的买入逻辑
if cash < 1000:
print("资金不足,今日操作结束")
return # 函数在此终止,当天的 market_open 执行完毕
# 如果上面的 return 没有被触发,才会执行到这里
print("资金充足,开始下单...")
order('000001.XSHE', 100)
总结
- 返回值:引擎不接收回调函数的返回值,请使用全局变量
g来传递数据和状态。 - 提前终止:直接使用
return即可完美实现“满足条件则跳过当天剩余逻辑,等待下一次触发”的需求。