🚀 AI 一键生成 joinquant 策略代码
立即体验
👉 AI 生成代码 👈

为什么在 JoinQuant 中定义了函数,调用时仍提示 NameError: not defined?

joinquant | 发布时间: 2026/6/1
以下内容由 EasyQuant 生成。

问题描述

为什么已经定义了函数,但引用时还提示not defined?

各位大神好,

在代码里明明定义了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_positiondef 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 或其他定时运行的函数内部,并确保自定义函数顶格定义在代码文件中。