在传统的计算机语言类的图书中,数据类型(Data Type)与数据结构(Data Structure)通常在不同的章节介绍。本书参考了 Pine Script User Manual ,并结合Pine Script的特色,将这两部分内容合并在一章讲解。
数据形式(Form)是Pine Script特有的术语。Pine Script中的数据形式是指基础数据类型的具体应用形式。
本章将要介绍Pine Script V5语言中的数据类型,包括5种基础数据类型(Fundamental Data Types)、6种特殊数据类型(Special Data Types)、5种数据形式(Data Form)和6种数据结构(Data Structure)。这些数据类型是编写脚本所必需的基础知识,需要熟练掌握。
Pine Script V5共有5种基础数据类型:int、float、bool、string和color,下面进行详细介绍。
例如:
例如:
布尔型变量只有两个值:
字符串型数据需要用单引号或双引号括起来,例如:
上面句子使用单引号或双引号的功能是等效的。
双引号内的字符串可以包含单引号,同样,单引号内的字符串也可以包含双引号,如下所示:
若单引号内的字符串包含单引号,则需要在字符串中的单引号前加反斜线(\)标识。双引号同理,如下面两句:
颜色类型是Pine Script语言的特色之一。Pine Script V5提供了4种颜色类型的常数/常量/变量的表示方法,包括具名常量表示法、十六进制常数表示法、十进制函数表示法和通用的函数表示法。本节将介绍十六进制常数表示法和具名常量表示法。
颜色常数(Color Literal)的表示格式为:“#”后面跟着6个或8个十六进制数字,表示RGB值或RGBA值。前6位表示颜色通道(Channel):第1位与第2位数字确定红色通道的值,第3位与第4位数字确定绿色通道的值,第5位与第6位数字确定蓝色通道的值。每个通道值必须是从00到FF的十六进制数字(十进制则是从0到255)。最后两位,即第7位和第8位数字是可选的,可以指定Alpha(透明度)通道,其值也是从00(完全透明)到FF(完全不透明)。
如图5-1所示为10个颜色类型的常量在Pine Editor编辑器中的显示。
图5-1 10个颜色类型的常量在Pine Editor编辑器中的显示
十六进制常数表示法不区分字母大写和小写。
Pine Script V5提供了17种预定义的具名常量,可以用于替代十六进制颜色常数,这样更便于记忆和使用,如表5-1所示。
表5-1 17种预定义的具名常量
TradingView平台提供了功能强大、灵活友好的绘图模块,同时Pine Script对于色彩的支持也颇具匠心与创新。在本书第18章图表的配色设计中,我们将对此进行详细讲解。
Pine Script V5共有6种特殊数据类型,即line、label、box、table、plot和hline。其中数据类型line、label、box和table的属性和用法类似,plot和hline的属性和用法类似。
line、label、box和table数据类型是Pine Script特有的数据类型,它们的属性和用法类似。
Pine Script从V4版本开始,引入了此项新功能,使用户可以通过脚本创建图形/图表对象。Pine Script从V5版本又丰富了此项功能。用户可以分别使用函数line.new()、label.new()、box.new()和table.new()创建line、label、box和table对象,这些对象的数据形式分别为series line、series label、series box和series table。
基础数据类型line、label、box和table仅有series一种数据形式。
用户通过脚本创建line对象的用途。如前所述,函数line.new()的返回值在图表上创建line类型的对象,由该函数创建的对象还可以再传递给函数linefill.new(),用于在指定区域内填充颜色。函数linefill.new()可以在两个line对象之间的区域填充颜色。
关键字plot和hline既可以指数据类型也可以指函数,具体含义根据语法格式与上下文鉴别,但在本节中我们讨论的是数据类型。
plot和hline数据类型也是Pine Script特有的数据类型,两者的属性和用法类似。
如前所述,函数plot()和hline()的返回值在图表上创建类型为plot和hline的对象。由这些函数创建的对象还可以再传递给函数fill(),用于在指定区域内填充颜色。函数fill()可以在两个plot对象或两个hline对象之间的区域填充颜色。
数据形式是Pine Script语言中特有的术语,Pine Script中的每种基础数据类型在具体使用的时候都可以被分为5种不同的数据形式,分别是literal、const、input、symbol和series,这些不同的数据形式在实际编程中有着重要的作用。
常数是指固定不变的数值。常数的值,在编译时就确定了。常数的类型如表5-2所示。
表5-2 常数的类型
常量是指数值不变的量。在程序/脚本运行时,常量的值不变。
常数与常量的区别:
● 常数的值:编译时就是确定的。
● 常量的值:在程序运行初始化后是确定的。
常量的类型如表5-3所示。
表5-3 常量的类型
在下面的例子中,c1是int常量,c2也是int常量,而c3是series int变量,c3的值在脚本运行时会发生变化。
input类型的变量的特点:
● 在脚本运行期间,此种变量的值不变。
● 在编译时此种变量的值未知。
● 此种变量的值从函数input的返回值得到。
如下所示,变量p是input类型。
商品代码可以是任意金融产品(包括股票、债券、大宗商品、货币、ETF等)的代码。打开TradingView图表,商品代码信息就显示在图表界面的左上方。
symbol类型变量的特点:
● 在脚本运行期间此种变量的值不变。
● 在编译时此种变量的值未知。
例如内置变量syminfo.mintick是symbol float类型。
在使用这种数据形式时,通常只使用关键字float,而不使用symbol float。
1.时间序列的定义
Pine Script中的series就是时间序列,是一组按照时间发生的先后顺序进行排列的数据序列。通常一组时间序列的时间间隔值为恒定值(如1秒、5分钟、12小时、7天、1个月和1年等)。
时间序列是Pine Script中的主要数据类型,是一组连续的序列值,从当前时间的K线数据向过去时间的K线数据延伸,每根K线存储的都是市场行情数据。
虽然时间序列很类似数组,但两者却有很大不同,最显著的区别是时间序列带有动态索引。
2.时间序列变量的特性
时间序列变量有如下特性:
● 时间序列变量的值可以在脚本运行时修改。
● 可以存储市场行情数据。
● 可以使用“[]”操作符访问。
历史行情数据仅可以读取,实时行情中的当前时点(图表上最右侧的K线)的行情数据可以同时进行读取和写入。
3.常用的内置时间序列变量
常用的内置时间序列变量包括:open、high、low、close、hl2、hlc3、ohlc4、hlcc4、volume和time。在Pine Script中,它们也都是保留字。
这里:
▫ hl2=(high+low)/2
▫ hlc3=(high+low+close)/3
▫ ohlc4=(open+high+low+close)/4
▫ hlcc4=(high+low+close+close)/4
值得一提的是,时间序列变量还可以存储数字或特殊值na。有关na的更多内容可参考第5.4.1节。
例如:
Pine Script中的数据结构可以分为:特殊的内置变量na、特殊类型void、多元组、数组、用户自定义类型和矩阵。
在Pine Script中有一个特殊的内置变量na,它是“not available”的缩写,意思是表达式或变量不可用。na类似Java中的null或者Python中的None。
有关内置变量na的3个要点如下:
(1)内置变量na可以用于任何数据类型,换句话说,任何数据类型都可以有na值。
(2)在某些情况下,Pine Script编译器无法自动转换na的数据类型,需要定义数据类型。
(3)若测试某变量的值是否为na,则需要使用特殊的函数na()。需要注意的是,不可以使用运算符“==”来测试na值。
示例1:下面的脚本是na的错误用法示例。
单击“Add to chart”选项,编译系统会提示错误,如图5-2所示。
图5-2 编译系统提示的错误
这段错误提示信息的含义在第4行代码运行中体现(发生错误),“na类型不能赋值给没有类型关键字定义的变量”,这是因为编译器不能确定myVar的数据类型。
上述问题可以用以下两种方法解决。
示例2:下面的脚本是改正示例1错误的方法1。
示例3:下面的脚本是改正示例1错误的方法2。
在Pine Editor页面中,单击“Add to chart”选项,把脚本添加到图表中。以微软股票(MSFT)为例,会发现图表背景发生变化,即当K线为阳线时,主图上的背景为浅绿色,如图5-3所示。
图5-3 内置变量na的示例
示例4:下面一条语句使用了特殊函数na(),来测试某变量的值是否为na。
void类型是Pine Script中一个特殊的数据结构。很多有副作用(Side effects)的函数返回void结果,例如函数strategy.entry和plotshape等。
函数返回的void结果不能应用于任何数学表达式,也不能赋值给变量。
多元组(或 n 元组)泛指有限个元素所组成的序列。在数学上,多元组是指对象个数有限的序列。
多元组由3部分组成,即边界符、分隔符和元素。通常采用的边界符是括号“()”或“[]”,以逗号为分隔符。多元组在数学及计算机科学中都有特殊的意义。
Pine Script中的多元组由一系列按特定顺序排列的元素组成,且为次序不可变序列。在形式上,多元组的所有元素都放在一对括号“[]”中,两个相邻元素间使用逗号“,”分隔。
多元组的元素可以是任何类型,也可以将整数、浮点数和字符串等任何类型的内容放入多元组中,并且在同一个多元组中,元素的类型可以不同,因为它们之间没有任何关系。
在Pine Script中,对多元组的应用仅限于函数调用且函数返回结果包含多个特定序列变量时。
在下面所示语句中,calcSumAndMul函数的最后一行语句就是一个二元组,即该函数的返回变量。
函数调用的返回值也必须是特定的元组表达式,例如在下面语句中是对函数calcSumAndMul的调用。
数组的定义:数组又称数组数据结构(Array data structure),是由相同类型元素的集合所组成的数据结构,分配一块连续的内存来存储。
数组的特点:Pine Script中的数组是一维的,其数据类型可以是int、float、bool、color、string、line、label、box或table,且Pine Script中的数组一定是时间序列的数据形式。
数组的引用:可以使用数组下标(ID)引用数组,类似引用line或label。数组的下标从0开始,最大长度是100000。
Pine Script中的大部分数据是以时间序列的方式存储的,这与使用数组的方式存储有很大区别。
● 在Pine Script中,数组是一维的。一个数组中的所有元素都是相同类型的,可以是int、float、bool或color等类型,且数据形式总是时间序列数据形式。
● 可以使用数组下标引用数组,类似通过ID引用label和line数据。
● 在Pine Script中,不能使用索引操作符来引用单个数组元素,而是使用array.get()函数和array.set()函数等来读取和写入数组元素的值。
● 数组的值可应用于所有允许时间序列数据形式的表达式和函数中。
用户自定义类型是Pine Script V5的新增功能,需要使用关键字type来定义该类型。用户自定义类型的变量可用于存储对象数据。
以下语句定义了用户自定义类型pivotPoint。
用户自定义类型的使用方法可以参考下面的脚本示例。下面的脚本定义了一个对象pivotPoint,该对象包含了高点的坐标和时间等信息,并使用该对象来存储ta.pivothigh函数的返回值。最后在图表上使用标签表示指定周期内出现的高点。脚本如下。
把该脚本添加到图表中,如图5-4所示。
图5-4 使用用户自定义类型,提示指定周期内的价格高点
用户自定义类型通常用于创建新的数据类型,以便更好地组织和管理程序中的数据。但用户自定义类型对于初学者来说可能会比较困难和复杂,因此,初学者可以先忽略这个概念,在熟练掌握基础知识后再深入研究它。
在Pine Script V5中,新增了矩阵作为一种数据类型/数据结构。相对于数组,矩阵是多维的,通常用于处理更复杂的数据结构和算法。在之前的版本中,Pine Script只有一维数组,矩阵的引入为开发者提供了更多的数据处理选项。
举个例子来说明矩阵的用法。下面的脚本通过使用matrix.new函数和matrix.get函数来实现绘制当前K线收盘价与前面第10根K线收盘价之间的对比图。
把该脚本添加到图表中,如图5-5所示。
图5-5 矩阵应用的例子
Pine Script具备数据类型的自动转换(Type Casting)功能,在图5-6中,箭头表示数据类型的自动转换方向和关系。
图5-6 数据类型的自动转换
在下面的脚本中,函数plotshape的参数series是series bool类型,而内置变量close是series float类型。表达式“series=close”等号左右两侧的变量类型不同,但是系统在此处自动进行了类型转换,即series float转换为series bool。
在有些情况下,系统不能进行数据类型的自动转换,这时需要使用函数进行数据类型转换。Pine Script V5版本中的数据类型的转换函数有int()、float()、string()、bool()、color()、line()和label()。
示例1:数据类型转换失败的脚本。
在Pine Editor页面中,单击“Add to chart”选项,编译器会有错误提示,如图5-7所示。
图5-7 编译器提示有错误
出现这个错误的原因是变量len是const float类型,而函数ta.sma(source,length)的参数变量length必须是整型。因此,系统不会自动进行从const float到int的数据类型转换。为了解决这个问题,我们需要使用数据类型转换函数int()。下面是正确的脚本代码。
本章详细讲解了Pine Script语言中的数据类型,包括5种基础数据类型、6种特殊数据类型、5种数据形式和6种数据结构。需要注意的是:
● 特殊数据类型和数据形式是Pine Script的特色,需要特别注意。
● 不同数据类型之间的转换也是写脚本的重要技巧之一,需要不断实践和练习。
● 数据结构中的用户自定义类型和矩阵有助于编写更高效的脚本,但是因其比较复杂,初学者可以先重点掌握基础知识,在熟练掌握后再深入研究它。
在编写Pine Script代码时,选择合适的数据类型可以帮助我们更好地管理各类数据,提高编程的效率,并使脚本更加易于维护和扩展。因此,学习Pine Script必须熟练掌握数据类型的概念和用法。