问题描述
各位大神好,
在代码里明明定义了close_position这个函数
为什么运行的时候还是报错说:
NameError: name 'close_position' is not defined
if curr_price < newnet[p-1]:
open_position(context, stock)
log.info('买入[%s]', val)
if curr_price > newnet[p+1]:
close_position(stock, '死叉清仓')
log.info('卖出[%s]', -val)
def open_position(context, stock):
val = context.portfolio.available_cash / grid_num
o_ord = order_target_value(stock, val)
def close_position(stock, action):
val = context.portfolio.available_cash / grid_num
o_ord = order_target(stock, -val)
code
解决方案
在 JoinQuant(聚宽)平台编写策略时,遇到 NameError: name 'close_position' is not defined 报错,通常是因为 Python 解释器在执行到函数调用时,还没有读取到该函数的定义,或者代码的缩进/结构不符合规范。
结合您提供的代码,以下是几种最可能的原因及解决方法:
1. 交易逻辑未放入聚宽的回调函数中(最常见原因)
在 Python 中,代码是从上到下顺序执行的。如果您将 if curr_price > newnet[p+1]: 这段判断逻辑直接写在了全局作用域(即没有缩进,不在任何函数内部),当程序启动时,解释器会立即执行这段代码。此时,由于 def close_position 写在下方,解释器还不知道它的存在,就会报错。
解决方法:
在 JoinQuant 中,所有的交易逻辑(买卖判断)都必须放在特定的回调函数中,例如 handle_data 或者通过 run_daily 调用的自定义函数中。当这些回调函数被触发时,整个代码文件已经被解析完毕,就不会出现找不到函数的问题。
正确的结构示例:
# 1. 初始化函数
def initialize(context):
g.stock = '000001.XSHE'
# 每天运行一次交易逻辑
run_daily(trade_logic, time='every_bar')
# 2. 交易逻辑函数
def trade_logic(context):
# 获取价格等数据...
curr_price = 10.0
# 判断逻辑必须在函数内部
if curr_price < newnet[p-1]:
open_position(context, g.stock)
log.info('买入')
if curr_price > newnet[p+1]:
close_position(g.stock, '死叉清仓')
log.info('卖出')
# 3. 自定义操作函数(放在外层全局作用域即可)
def open_position(context, stock):
val = context.portfolio.available_cash / grid_num
order_target_value(stock, val)
def close_position(stock, action):
val = context.portfolio.available_cash / grid_num
# 注意:A股不支持做空,order_target 的目标股数不能为负数
order_target(stock, 0)
2. 缩进错误导致作用域问题
Python 严格依赖缩进。如果您的 def close_position 不小心多加了缩进,导致它变成了另一个函数的内部函数,那么在全局或其他函数中调用它时,就会提示 not defined。
解决方法:
检查 def open_position 和 def close_position 的缩进,确保它们顶格写(前面没有空格),属于全局函数。
3. 额外提示:下单函数的参数问题
在您的 close_position 函数中,有一行代码:
o_ord = order_target(stock, -val)
order_target(security, amount)的作用是将标的的最终持仓股数调整为amount。- 在 A 股市场中,持仓股数不能为负数(不支持直接做空)。如果您想清仓,应该使用
order_target(stock, 0)。 - 如果您想按价值卖出,应该使用
order_value(stock, -val)(负数表示卖出价值)。
总结:请检查您的 if 判断语句是否正确地包含在了 handle_data 或其他定时运行的函数内部,并确保自定义函数顶格定义在代码文件中。