现在,我们在收盘价之外再画出开盘价。为此,要扩展上一章的程序:从库中引入一项新数据,并添加一次绘图调用。

修改前,先逐行看看程序,弄清楚各行的作用。

代码是一份精确描述

在程序里,你向电脑发出指令。例如:“使用 K 线的收盘价,以蓝线显示。”电脑需要精确的名称和符号才能执行。

在 Pyne code 中,我们用 Python 语法书写这些指令。函数调用的括号、冒号和行缩进都属于这套规则。接下来会逐一介绍它们的作用。

打开第二章创建的 first_chart.py。即使你已经修改了指标名称,也不影响下面的解释。

文件开头的 Pyne 标记

文件的前三行:

"""
@pyne edge
"""

三个引号标记文本块的开始与结束。放在文件开头时,这个块也能容纳程序说明。Python 称它为 docstring(文档字符串)。

PyneCore 从中读取 @pyne 标记,得知文件包含 Pyne code,需要采用不同于普通 Python 的规则。运行前,PyneCore 会转换代码,让我们能够访问之前 K 线的值,或让变量把数值保留到下一根 K 线。这些功能会在各自章节介绍。

单独使用 @pyne 也是有效标记。Pyne code 文件也可以这样开头:

"""
@pyne
"""

后面的 edge 是什么意思?

edge 表示程序使用 Pyne code 中规定的受限语言子集。@pyne 启用逐根 K 线的执行方式;edge 决定可以使用哪些语言元素和函数。超出范围时,PyneIDE 会给出提示。

只有 @pyne 标记的程序还可以使用 Python 的其他能力和库。@pyne edge 程序使用 Pyne 允许的工具,不会导入任意 Python 库。因此,没有通用 Python 环境的执行器也能够处理它们。

本书所有完整程序都保留 @pyne edge,并在这一语言范围内编写。

选择所需工具

下一行是:

from pynecore.lib import close, color, plot, script

from … import … 结构让列出的名称可以在程序中使用。本例从 pynecore.lib 库引入四项工具:

  • close:当前 K 线的收盘价;
  • color:可用的颜色;
  • plot:在图表上显示数值;
  • script:指定程序类型和基本设置。

名称之间用逗号分隔。大小写有区别:close 和 Close 不是同一个名称。

空行用于划分代码结构,让你更容易看出工具列表在哪里结束、程序从哪里开始。

程序的名称和显示方式

@script.indicator("My First Chart", overlay=True)

这一行表示我们要创建一个指标。指标根据数据计算并显示内容。本例绘制的是收盘价。

括号内指定指标设置:

  • 引号中的 "My First Chart" 是指标名称。
  • overlay=True 要求图形与 K 线显示在同一张图表上。

True 表示真,反面是 False。将 overlay 改为 False,指标就会显示在单独面板中。自定义计算章节也会使用这一设置。

计算发生在哪里

def main():
    plot(close, "Close", color=color.blue, linewidth=2)

def 表示函数定义的开始。函数是一组有名称的操作,这里的名字是 main。

PyneCore 会针对数据中的每根 K 线执行 main() 的函数体。它是本程序的入口。括号后面是冒号,下方缩进的行属于函数体。

缩进说明哪些行属于同一代码块。每一级缩进使用四个空格。在行首按 Tab,按 PyneIDE 默认设置就能一次缩进四个空格;Shift + Tab 则向外退一级。在以冒号结尾的行后按 Enter,Visual Studio Code 通常也会自动缩进新行。

我们要求 plot 做什么?

plot(...) 是一次函数调用。括号中提供运行所需的值和设置:

  • close:显示这个值;
  • "Close":图形使用这个名称;
  • color=color.blue:使用蓝色;
  • linewidth=2:线宽设置为 2。

前两个值的作用由位置决定。color= 和 linewidth= 则明确写出传递的是哪一项设置。这些设置称为参数。

color.blue 中的点表示使用 color 下的 blue 颜色。它属于名称访问语法,不要替换为逗号。

绘制两条线

收盘价使用 close,开盘价则通过 open 访问。

在 scripts 文件夹中复制该文件,命名为 two_lines.py,这样第二章的示例也会保留。在副本中:

  1. 将 open 加入导入的工具。
  2. 将指标名称改为 "Open and Close"。
  3. 在 main() 函数体内添加第二个 plot 调用。

完整程序:

"""
@pyne edge
"""
from pynecore.lib import close, color, open, plot, script


@script.indicator("Open and Close", overlay=True)
def main():
    plot(close, "Close", color=color.blue, linewidth=2)
    plot(open, "Open", color=color.orange, linewidth=2)

运行前,先预测两条线会在 K 线的什么位置相交。保存文件,点击 Run Pyne code,使用与此前相同的示例数据。

two_lines.py 代码旁的 DEMO 价格图表显示分别名为 Close 和 Open 的线条。
两次 plot 调用生成两条线:Close 显示收盘价,Open 显示开盘价,位于同一张图表。

应当观察什么?

蓝线连接收盘价,橙线连接开盘价。图中的线条也有名称:Close 和 Open。以后改变颜色时,名称仍能帮助辨认。

两个 plot 调用都缩进四个空格,因为它们属于同一个 main() 函数。

如果 open 下方出现错误提示,检查是否已在导入行添加它。使用新工具之前,必须让其名称在程序中可用。

代码中的注释

以单个 # 开头的一行是注释:

    # Show the opening price of each candle.
    plot(open, "Open", color=color.orange, linewidth=2)

注释不执行操作。你可以用它说明某一步的目的,方便自己或后来阅读代码的人理解。示例注释使用英文,书中的解释使用中文。

也可以把注释放在语句末尾:

    plot(open, "Open", color=color.orange, linewidth=2)  # Show the opening price.

此时 plot(...) 调用照常执行。其后从 # 到行尾的文字是注释,执行器会忽略。代码与 # 之间留两个空格,便于阅读。

自己试一试

添加第三条线,显示各根 K 线的最高价,数据名称是 high。图形名称设为 "High",颜色使用 color.green。

想想需要在哪两处扩展程序。运行前预测一下:High 的值可能低于同一根 K 线的开盘价或收盘价吗?

参考答案

导入行也必须添加 high:

from pynecore.lib import close, color, high, open, plot, script

在 main() 函数体内添加下面一行,缩进与另两个调用相同:

    plot(high, "High", color=color.green, linewidth=2)

K 线的最高价至少与开盘价和收盘价一样高。因此,同一根 K 线的 High 点不可能低于其中任何一个值。理解连接各点的线段时,要在对应 K 线的位置判断。

检查自己的修改

通读三条线的程序。能找到导入的数据、指标名称和绘图调用吗?检查每项新数据的名称是否出现在导入行,三个调用的缩进是否一致。

开始对价格进行自定义计算前,先看看 PyneIDE 如何帮助你使用函数。