跳到主要内容

Pine Script 学习笔记——基础语法篇(一)

简介

量化交易平台 TrendingView 是一个支持多种资产的投资平台,很多人在上面分享对于股票,外汇,数据货币等资产的投资观点,难得的是在上面能找到很多人的交易策略。

TrendingView 使用的是自己开发的Pine 语言作为脚本,这一点和MT4 开发的mql4 很像。用户可以自己编写脚本和策略,并与其他人分享。Pine 直观给我的印象比Mql4 更加简单,更加关注于策略本身,而不是编程技巧。

此外,Pine语言编辑器没有那么强大的debug 功能,这对于一开始上手练习来说,不是那么方便。不过它一直在更新,发展的很快。

TrendingView 对接了很多经纪商,使得它支持的交易品种很丰富,而且它的图表功能很强大。

下面记录一下自己学习Pine 脚本的一些基础的笔记,权当备忘。主要内容都参考自Pine 的脚本文档

脚本结构

指明用的Pine 脚本版本

//@version=4  

Pine 可以分为study脚本 和 strategy 脚本(指标&策略) study 脚本必须包含 plot,plotshape,barcolor,line.new 等输出 strategy 脚本包含 strategy.* 即交易函数

换行 Line wrapping

//例子1 换行需要空格
a = open+
high+
low
// 例子2 换行中不能有注释
a = open+
high // 此处加注释会出问题
// 例子3 函数内换行,空行必须要超过一个Tab(或者4个空格)
label.new(bar_index, na, yloc=yloc.abovebar, text=t,
color=hist ? color.green : color.red)
// 这里空格必须超过4个

运算符

  • 算术: + - * / %

    1/2 = 0 1/2.0 = 0.5

  • 比较: == !=

  • 逻辑: not and or

  • 三元运算符:

    • condition ? result1 : result2
    • iff(condition, result1, result2)
    有房?嫁:有车?: 嫁:帅?嫁: 不嫁
  • [] 运算符(History reference operator) close 代表最新的价格,close[1]代表了历史价格。

    close = close[0] //显示的是最新的收盘价

    除此之外,Pine脚本里面还有一个变量 bar_index,记录着bar的数目,编号自左向右,从0开始。bar_index = (bar数量)N-1。

    • 为什么运行close[bar_index-1] ≠ close[0] ? 而close[bar_index-1] 会出错

函数

Pine 脚本中包含了大量的自建函数,用户还可以自定义函数、

  • 单行函数

    f(x,y) => x+y

    Pine Script 的函数不支持**递归**

    即,不允许在函数中再次调用自己本身

  • 多行函数

    geom_average(x, y) =>
    a = x*x
    b = y*y
    sqrt(a + b)
    • Pine Script 需要(一个Tab 或者4空格,TrendingView 会自动用4个空格来替换掉Tab)来划定函数的范围
    • 最后一行的表达式或 变量作为函数的输出结果
  • 输出>=2

    fun(x,y) =>
    a = x+y
    b = x-y
    retrun [a,b]
    // 调用函数
    [a,b] =fun(3,2)

函数的注意事项

当在函数块中使用函数或者历史数据信息的时候要注意。因为所使用的历史信息是每一次连续调用生成的。

如果函数并不是在每一根柱线上都调用,那么数据生成就会出现错误。

  • 例1

    // 定义两个函数f1,f2
    f1(a) => a[1]
    f2() => close[1]
    // 说明下列用法的实际意义
    f1(close) 等价于 close[2]
    f2() 等价于 close[1]

f1 传入的close 序列,需要在第一次调用后才能生成,所以f1 的 价格信息实际上比f2 晚一天

变量声明&语句statement

var

  • Pine 语言中变量定义的方式有两种: = 和 var

    a = 1 // a为整形
    float a = 1 // a为浮点型
    var a = 0
    var int a = 0
    b = na //出错

    变量定义的时候,需要指明变量的类型(或者 等式右侧表达式能指明类型亦可)

    na 没有特定的类型,所以赋值时会出错

  • var 关键词

    var 是用于分配和一次性初始化变量的关键词。

    不含var 关键词的变量在每次数据更新的时候都会覆盖变量的值。使用了var 关键词的变量,在数据更新中,可以“保持状态”。 举例

    //@version=4
    study("Var keyword example")
    var a = close
    var b = 0.0
    var c = 0.0
    var green_bars_count = 0
    if close > open
    var x = close
    b := x
    green_bars_count := green_bars_count + 1
    if green_bars_count >= 10
    var y = close
    c := y
    plot(a)
    plot(b)
    plot(c)

    变量 'a' 保持系列中每个柱线的第一根柱线的收盘价。

    变量 'b'保持系列中第一个“绿色”价格棒的收盘价。

    变量 'c'保持系列中第十个“绿色”条的收盘价。

    即a,b,c 都是一个常数。

    去除var 的话,a,b,c 会随着价格变化而变化

if 语句

// This code compiles
x = if close > open
close
else
open
// This code doesn't compile
x = if close > open
close
else
"open"

需要注意的是,与python不同,Pine要求,then 和 else语句返回的值的类型是相同的。在上面的第二个例子中,close 和 "open" 一个是float Series,另一个是string,不同类型的话,编译会出错。

  x = if close > open
close
// If current close > current open, then x = close.
// Otherwise the x = na.

if 语句中可以忽略else,但是系统会默认赋值(na,false,"")

for 语句

for i = 1 to length-1
sum := sum + price[i]

执行模型

Pine代码是根据价格信息计算的。但是价格信息并不是完整加载的,用户可以一直向左滑动图表,直到最早的一根柱子(Pro 用户可以在图表上加载10000左右,免费用户可以加载5000根柱子)

实时数据的计算

Pine指标计算实时数据的时候和计算历史数据略有不同,因为实时数据会有addtional commit(?)和rollback action(?)

在实时数据的处理过程中,柱线的每一次变动都会引起Pine 指标的计算

  • rollback : 在每一根柱线更新时发生
  • commit : 在每一根柱线关闭时发生

对于判断柱线的状态,Pine中有一系列的自建函数 barstate.* 来显示当前柱线的状态。