在 PyneIDE 中调试
在断点处暂停程序,逐根 K 线检查变量。
代码语法正确,仍可能算出与你预期不同的结果。调试器可以暂停运行、查看变量,并逐条跟踪指令。
本章检查收盘价与五期移动平均的距离。先预测结果,再查看程序实际算出了什么。
三类错误
语法错误违反代码书写规则,例如缺少冒号或缩进错误。编辑器通常在输入时就会提示。
运行时错误发生在程序执行过程中。例如,读取数组中不存在元素的索引,运行就可能报错停止。
逻辑错误则不一定阻止程序运行。如果把 close - average 写成 average - close,结果符号就会反过来。语言规则并不禁止,需要你把结果与任务对照。
Visual Studio Code 的 View → Problems 视图列出编辑器发现的问题。点击一行即可跳转到出错位置。开始大幅改代码前,先读清具体错误信息。
一个可供检查的程序
创建 debug_average.py:
"""
@pyne edge
"""
from pynecore import Series
from pynecore.lib import bar_index, close, color, log, plot, script, ta
@script.indicator("Average Distance", overlay=False)
def main():
average: Series[float] = ta.sma(close, 5)
gap = close - average
if bar_index == 10:
log.info("close={0}, average={1}, gap={2}", close, average, gap)
plot(gap, "Distance", color=color.blue)bar_index 是当前处理 K 线的序号,从零开始。索引 10 对应第十一根,所以这次历史运行只记录一次日志。
log.info 创建格式化消息。{0}、{1}、{2} 按顺序替换成后面三个值。带编号占位符的文本由日志工具处理。
先通过 Run Pyne code 运行一次。收盘价高于均线时,线条应为正。最前四根的平均值和距离都缺失。
在某一行之前暂停
- 点击
plot(gap, ...)所在行行号左侧,出现断点标记。 - 点击代码上方的 Debug。
- 若出现数据选择,选择
demo。 - 程序会在断点处暂停。打开 Run and Debug 视图。
断点是调试器让程序暂停的位置。高亮行尚未执行,之前赋值的结果已经可以查看。
第一次暂停可能在第一根 K 线。此时尚无完整五根窗口,gap 为缺失值。调试器展示的是这个状态,缺值本身不是程序错误。
到达预热后的 K 线
调试时出现的浮动工具栏上,PyneIDE 的 Next Bar 会前进到下一根 K 线。将鼠标停在图标上可查看名称。找到 Run to Bar… 并点击,在输入框填入 10,按 Enter。
第十一根已有完整五期窗口。在 Variables 中找到 average 和 gap。Pyne 分组显示当前 K 线数据,包括 bar_index 与 close。

average 是 Series 变量,所以程序里也能用 average[1] 访问其上一值。上一根平均值未必等于当前,因为窗口已向前移动一根。
监视表达式
在 Watch 中可以添加每次暂停都想查看的表达式。试试:
close
close[1]
average
close - averageclose[1] 是相对于暂停 K 线的前一收盘价。average 是自定义变量。close - average 的结果应等于已算出的 gap。
监视变量和简单算术即可。不要在 Watch 中放 ta.sma、发订单的操作或修改数组的调用。调试检查不应改变程序状态。
逐行与逐根 K 线
Step Over 执行到下一条语句,不深入被调用函数。Step Into 可以进入自己的函数。Continue 继续到下次暂停,Disconnect 断开调试连接并结束调试。
Next Bar 使用另一种步长,直接前进到下一根 K 线。逐行操作展示单根内部的计算细节,逐根操作展示结果如何随时间变化。
当前暂停 K 线尚未处理完成,所以图表可能仍显示先前完成的状态。请在 Pyne 分组检查当前索引和数据。
读取变量前,先看高亮行。如果赋值还没执行,变量就还不包含你此刻期待的结果。
找出符号错误
停止调试器,将这一行改成:
gap = average - close重新启动调试,前进到同一根 K 线。若价格在均线上方,gap 会为负,但任务要求的是正距离。
Watch 中的 close - average 仍是原本需要的方向。比较二者就能直接看到差异。恢复正确减法,在同一根再检查一次。
自己试一试
添加 previous_close = close[1],在调试器中检查。K 线索引为 10 时,它应该包含哪根的收盘价?第一根时是什么值?
参考答案
previous_close = close[1]在索引 10 上,它返回索引 9 的收盘价。在第一根、索引 0 上缺失,因为数据文件没有更早 K 线。
把这行放到断点前,确保暂停时已经执行。检查完后,可以删去辅助变量和只用于验证的日志行。
如何清楚描述错误
求助时,提供文件、所用数据、实际输入和被检查 K 线的时间。同时说明预期值与实际值。不要只说“线不对”,而可以说:“这根收盘价是 101,平均值是 100,但距离结果为 −1。”这样别人才能核查计算。