保持敬畏之心
交易是一场持久战

Pine Script(157):编写直方图、十字图与圆圈图

#Pine Script入门教学

编写直方图(plot.style_histogram)

直方图通过独立的条形来高亮显示数值,通常显示在主图表下方的独立图表面板中。像成交量和MACD这样的标准指标就使用了这种绘图。当然,我们也可以编写自己的TradingView直方图。让我们来看看如何实现。

使用TradingView的 plot() 函数编写直方图

指标或策略脚本可以通过TradingView的 plot() 函数在图表上绘制数值。通过这种方式,我们的代码,例如,可以用RSI值绘制一条常规的线图。但 plot() 也可以创建面积图和实心圆图。

一个常见的绘图类型是直方图。要让 plot() 函数创建一个直方图,我们需要做两件事:首先,将其第一个参数设为我们想要绘制的数值;然后,将其 style 参数设为 plot.style_histogram

所以,创建一个直方图的基本方式是:

plot(volume, style=plot.style_histogram)

这行代码创建的直方图看起来如下:

一个典型的直方图能告诉我们两件事。当我们比较不同的直方图柱子时,我们可以看到数值随时间的变化。并且,直方图还能告诉我们数值的量级,因为直方图的柱子是从价格坐标轴的零点开始绘制的。后者也可能是一个缺点。当我们绘制本身数值很大但随时间变化很小的值时,直方图会变得难以阅读:此时的价格坐标轴会使得微小的变化难以被察觉。

注意

直方图与TradingView的柱状图非常相似。它们的区别在于,直方图的条是独立的,而柱状图的条则很宽,彼此相邻(甚至相互接触)。

在TradingView中编写一个基础的直方图

要创建一个直方图,我们将 plot() 函数的 style 参数设为 plot.style_histogram。下面是一个快速的示例:

//@version=5
indicator(title="Histogram example", overlay=false)

plot(volume, style=plot.style_histogram, linewidth=4,
     color=color.orange)

这里,我们首先使用 indicator() 函数定义指标的设置。然后,我们调用 plot() 函数来创建一个直方图。为了实现这一点,我们将其 style 参数设为 plot.style_histogram

我们将 plot() 的第一个参数设为 volume 来显示交易品种的成交量。通过将 linewidth 参数设为4,直方图的柱子会比其默认尺寸大几级。通过 color 参数,我们让它们以橙色(color.orange)显示。

这个示例指标看起来是这样的:

使用 plot() 参数配置直方图

正如上面的小示例所示,plot() 函数有几个用于配置直方图外观的参数。通过它们,我们可以,例如,改变绘图的颜色或粗细。

以下是 plot() 函数用于创建直方图的所有参数:

参数 描述
series 必需参数,指定要绘制的数据。当我们创建直方图时,该参数不要求在每根K线上都有值。我们也可以在有条件地将此参数设为 na 时关闭绘图。
title 可选的常量字符串参数,用于为绘图命名。一个描述性的名称有助于将该绘图与其他绘图区分开。绘图的标题会显示在图表的数据窗口、警报设置窗口以及指标叠加指标功能中。
color 可选参数,用于指定直方图的颜色。可接受的值包括标准的TradingView颜色、十六进制颜色值或透明色。绘图颜色可以在每根K线上相同,也可以根据条件而变化。
linewidth 可选的整数参数,用于设置直方图条的宽度,默认值为1。此参数的值越大,直方图条就越粗。如果值足够大,直方图条会连接在一起。
style 可选参数,用于指定绘图类型。要创建一个直方图,我们将 style 设为 plot.style_histogram
trackprice 可选的布尔参数,当设为 true 时,会显示一条横跨整个图表的、带有最后一个绘图值的水平线。这使得我们可以方便地将当前值与历史值进行比较。该参数默认为 false,此时不显示水平线。
histbase 可选的浮点数参数,用于指定直方图条的起始点。未设置时默认为0.0。
offset 可选的整数参数,用于指定直方图向左(负值)或向右(正值)的偏移。此参数默认为0,即不产生偏移。
editable 可选的布尔常量参数,用于指定直方图是否可以手动编辑(true)或不可以(false)。默认值为 true,此时我们可以在脚本的设置窗口中更改直方图的外观。
show_last 可选的常量整数参数,用于指定应该显示最近多少根直方图条。该值是从最后一根K线向历史K线测量的。因此,通过 show_last=20,直方图将只为最近的20根价格K线显示。当未设置此参数时,直方图会对所有价格K线都显示。

注意

plot() 绘制其数据之后,它会返回一个所谓的绘图对象。如果我们将该对象存储在一个变量中,稍后就可以使用TradingView的 fill() 函数来为TradingView绘图之间的背景着色。除此之外,plot() 返回的值目前没有其他用处。

示例:使用多个 plot() 参数的详尽直方图

通过 plot() 函数的参数,我们可以随心所欲地详细编写我们的直方图。这里是一个使用了一系列参数的例子:

//@version=5
indicator(title="Elaborate histogram plot", overlay=false)

plot(ta.mom(volume, 10), title="Volume momentum",
     color=ta.mom(volume, 10) > 0 ? color.new(color.teal, 10) : 
     color.new(color.maroon, 10), linewidth=4, 
     style=plot.style_histogram, trackprice=true, 
     show_last=50)

这里,我们将 plot() 的第一个参数设为10周期的成交量动量(ta.mom(volume, 10))。通过 title,我们将其命名为“Volume momentum”。我们为 color 参数赋予一个条件值:当动量大于0时,直方图条被着色为青色(color.teal);否则,我们使用褐红色(color.maroon)。这两种颜色都通过 color.new() 函数被设为10%的透明度。

linewidth 参数设为4使得绘图的尺寸比默认的大几级。通过 style=plot.style_histogram,我们创建一个直方图。通过 trackprice=true,我们在整个图表上显示一条带有最后一个绘图值的水平线。而 show_last=50 则使直方图只在最近的50根价格K线上出现。

下图是这个详尽的 plot() 函数调用看起来的样子:

注意

如果我们提前设置所有与我们期望的绘图显示效果相关的 plot() 参数,一个TradingView指标或策略会变得更容易使用。

一旦我们在代码中定义了绘图设置,我们就不必每次将脚本添加到图表时都手动配置它。此外,还有一些 plot() 参数没有对应的人工设置选项,因此我们只能通过代码来设置它们。

影响TradingView直方图的其他设置

上面显示的 plot() 函数的参数配置了大部分,但并非全部的绘图设置。还有三个通用的脚本设置会影响我们的直方图,它们是:

  • indicator()strategy() 函数的 overlay 参数用于指定脚本的显示位置。当 overlay=true 时,指标或策略创建的所有绘图都会显示在主图表的交易品种上。而当 overlay=false 时,绘图则会显示在一个单独的图表面板中(这通常是我们用于直方图的设置)。
  • indicator()strategy() 函数的 scale 参数定义了脚本的绘图是否应该使用左侧价格坐标轴、右侧坐标轴,或不使用任何价格坐标轴。
  • indicator()strategy() 函数的 precision 参数用于指定脚本绘图所使用的小数点后的位数。当我们的直方图绘制大数值时(例如成交量),我们可能希望使用 precision=0。这还会将千位数值以k来缩写显示,例如20,043的成交量会显示为20k。

示例指标:使用plot()绘制移动平均线差值的直方图

让我们来看看如何在完整的示例指标中创建一个直方图。下方的脚本使用直方图来显示6周期简单移动平均线(SMA)与24周期SMA之间的差值。

当这个差值连续几根K线增加时,我们让直方图变绿。对于数值连续下降的K线,我们则将直方图涂成红色。其他情况下,我们使用银色作为默认颜色。

下图是该示例指标的样子:

该脚本的完整代码是:

//@version=5
indicator(title="Plotting: histogram example", overlay=false)

// 输入选项
fastLen = input.int(6, title="Fast SMA Length")
slowLen = input.int(24, title="Slow SMA Length")

// 计算数值
fastMA = ta.sma(close, fastLen)
slowMA = ta.sma(close, slowLen)
maDiff = fastMA - slowMA

// 确定绘图颜色
fourRising = maDiff > maDiff[1] and 
     maDiff[1] > maDiff[2] and
     maDiff[2] > maDiff[3] and 
     maDiff[3] > maDiff[4]
fourFalling = maDiff < maDiff[1] and 
     maDiff[1] < maDiff[2] and
     maDiff[2] < maDiff[3] and 
     maDiff[3] < maDiff[4]
plotColour = fourRising ? color.green :
     fourFalling ? color.red :
     color.silver

// 绘制plot.style_histogram
plot(maDiff, color=plotColour, style=plot.style_histogram, linewidth=4)

// 为背景着色
crossOverSignal  = ta.crossover(maDiff, 0)
crossUnderSignal = ta.crossunder(maDiff, 0)
bgColour = crossOverSignal ? color.green :
     crossUnderSignal ? color.red :
     na
bgcolor(color.new(bgColour, 90))

让我们来逐一解析代码。首先,我们定义指标的设置:

indicator(title="Plotting: histogram example", overlay=false)

// 输入选项
fastLen = input.int(6, title="Fast SMA Length")
slowLen = input.int(24, title="Slow SMA Length")

我们使用 indicator() 函数定义指标的通用设置。然后,我们通过 input.int() 函数创建两个整数输入选项,分别名为“Fast SMA Length”(默认值为6)和“Slow SMA Length”(默认值为24)。我们将这两个输入的当前值存储在变量中,以便后续使用。

接下来,我们计算脚本所使用的数值:

// 计算数值
fastMA = ta.sma(close, fastLen)
slowMA = ta.sma(close, slowLen)
maDiff = fastMA - slowMA

我们使用TradingView的 ta.sma() 函数来计算简单移动平均线。我们首先计算快线SMA,然后计算慢线SMA。接着,我们从快线SMA中减去慢线SMA来计算它们之间的差值,并将结果存储在 maDiff 变量中。

然后,就该进行一些绘图操作了:

// 确定绘图颜色
fourRising = maDiff > maDiff[1] and 
     maDiff[1] > maDiff[2] and
     maDiff[2] > maDiff[3] and 
     maDiff[3] > maDiff[4]
fourFalling = maDiff < maDiff[1] and 
     maDiff[1] < maDiff[2] and
     maDiff[2] < maDiff[3] and 
     maDiff[3] < maDiff[4]
plotColour = fourRising ? color.green :
     fourFalling ? color.red :
     color.silver

// 绘制plot.style_histogram
plot(maDiff, color=plotColour, style=plot.style_histogram, linewidth=4)

在绘图之前,我们首先确定绘图的颜色。但在此之前,我们先定义了着色的条件,并将它们存储在两个布尔变量中。

我们创建的 fourRising 布尔变量在移动平均线差值连续4根K线增加时为 true,否则为 falsefourFalling 布尔变量的逻辑则与之相反,判断差值是否连续四根K线减少。

在定义了条件之后,我们来确定绘图的颜色。我们为此创建了 plotColour 变量,并通过两个条件运算符(?:)将其设为三种颜色之一。当 fourRisingtrue 时,我们将 plotColour 设为绿色。否则,我们检查 fourFalling 是否为 true,如果是,则使用红色。当两者都为 false 时,我们使用银色作为默认颜色。

然后,我们绘制实际的直方图。为此,我们调用 plot() 函数,并将其 style 参数设为 plot.style_histogram。我们绘制的值是移动平均线的差值(maDiff),使用的颜色则是我们之前创建的 plotColour 变量。通过将 linewidth 参数设为4,这些直方图柱会比其默认尺寸大得多。

在指标代码的最后一部分,我们高亮显示一些特殊情况:

// 为背景着色
crossOverSignal  = ta.crossover(maDiff, 0)
crossUnderSignal = ta.crossunder(maDiff, 0)
bgColour = crossOverSignal ? color.green :
     crossUnderSignal ? color.red :
     na
bgcolor(color.new(bgColour, 90))

首先,我们判断移动平均线的差值是否穿越了零轴。我们使用 ta.crossover() 函数来测试 maDiff 变量的值是否上穿了零,并将布尔结果存储在 crossOverSignal 变量中。接着,我们使用 ta.crossunder() 函数来判断 maDiff 是否下穿了零,并将结果存入 crossUnderSignal 变量。

我们接下来创建的 bgColour 变量被有条件地设为三个值之一。当移动平均线差值上穿0时,我们将该变量设为绿色。如果差值跌破0,则设为红色。当没有发生任何交叉时,bgColour 变量持有 na 值来关闭着色。

接下来,我们使用 bgcolor() 函数从上到下为图表的背景着色。我们使用的颜色是我们刚刚创建的 bgColour 变量。通过 color.new() 函数,我们为该颜色设置了90%的透明度。

总结

我们使用 plot() 函数在图表上绘制数值。该函数有一个必需的参数:其第一个参数(series),用于定义要绘制的值。如果我们的值要显示为直方图,我们还需要将 style 参数设为 plot.style_histogram,否则 plot() 会默认创建一个常规的线图。

plot() 函数有几个参数用于配置我们的直方图。通过 title,我们为绘图命名,以帮助将其与其他绘图区分开。color 则为绘图在每根K线上赋予相同或不同的颜色。

直方图条的粗细由 linewidth 参数设置。直方图条在价格坐标轴上的起始点受 histbase 的影响。通过 trackprice 参数,我们可以在整个图表上显示一条带有最后一个绘图值的水平线。

要将我们的直方图条向左或向右移动,我们使用 offset 参数。另一方面,show_last 定义了绘制的数值在最近多少根价格K线上显示。最后也是最不常用的 editable 参数,则可以阻止用户在指标或策略的设置窗口中手动更改直方图的视觉设置。

编写十字图(plot.style_cross)

TradingView的十字图会在图表上显示一系列小的 + 号。它们通常显示在主图表的交易品种上,用于高亮显示高低点,或者例如显示追踪止损价格。当然,十字图也可以为多种情况进行编码。让我们来一探究竟。

使用Pine Script的 plot() 函数编写十字图(+)

指标和策略脚本可以通过TradingView的 plot() 函数在图表上绘制数值。通过这种方式,我们的代码,例如,可以为移动平均线绘制常规的线图。但 plot() 也可以创建实心圆图和柱状图。

另一种绘图类型是十字图,它在图表上显示为一系列小的 + 号。要让 plot() 函数显示十字,需要满足两个要求:首先,将其第一个参数设为我们想要绘制的数据;然后,将其 style 参数设为 plot.style_cross

所以,创建一个基础十字图的方式如下:

plot(ta.ema(close, 10), style=plot.style_cross)

这行代码创建的十字看起来如下。(在本文后面,我们将学习如何让十字比它们的标准尺寸更大。)

我们通常使用十字图来显示数据的趋势。它们最适合那些每根K线变化不大的数值,否则我们得到的十字会到处都是,使得绘图难以阅读。与线图,特别是面积图相比,十字图是一种更微妙地绘制数据的方式。十字图与TradingView的圆圈图非常相似。

由于十字图由独立的 + 号组成,它们能很好地处理缺失的数据。所以,当某一根价格K线上没有数值时,十字图会直接停止绘制。这与常规线图和基础面积图的做法相反,因为后两者确实会画线穿过没有数据的K线。

在TradingView中编写一个基础的十字图

要创建一个十字图,我们将 plot() 函数的 style 参数设为 plot.style_cross。下面是一个快速的示例指标:

//@version=5
indicator(title="Cross plot example", overlay=true)

plot(ta.highest(high, 20), style=plot.style_cross, color=color.green, linewidth=2)
plot(ta.lowest(low, 20), style=plot.style_cross, color=color.red, linewidth=2)

这里,我们首先通过 indicator() 函数定义指标属性。然后,我们两次调用 plot() 函数来创建两个十字图。

第一个 plot() 语句创建了一个20周期的最高价的最高点绘图(ta.highest(high, 20))。我们把该数据显示为绿色(color.green)的十字(style=plot.style_cross)。通过将 linewidth 参数设为2,这些十字会比标准尺寸1稍大一些。

第二个 plot() 语句非常相似,只是这次我们将第一个参数设为20周期的最低价的最低点(ta.lowest(low, 20)),并以红色(color.red)绘制十字(plot.style_cross)。

这个示例指标看起来是这样的:

plot() 函数的十字图参数

正如前面的示例所示,plot() 函数有几个影响我们十字图外观的参数。通过它们,我们可以改变绘图的大小、颜色,甚至关闭绘图。

以下是我们可以与十字图一起使用的所有 plot() 参数:

参数 描述
series 必需参数,指定要绘制的数据。对于十字图来说,数据中是否存在缺口并不重要。我们也可以通过有条件地将 series 设为 na 值来关闭十字图的显示。
title 可选的常量字符串参数,用于为绘图命名。一个描述性的名称有助于将该绘图与其他绘图区分开。该标题会显示在图表的数据窗口、警报设置窗口以及指标叠加指标功能中。
color 可选参数,用于设置十字的颜色。可接受的值包括标准颜色、十六进制颜色值和透明色。绘图颜色可以在每根K线上相同,也可以根据条件而变化。
linewidth 可选的整数参数,用于设置十字的大小,默认值为1。该参数的值越大,十字在图表上显示的就越大。
style 可选参数,用于定义绘图类型。要创建一个十字图,我们将 style 设为 plot.style_cross
trackprice 可选的布尔参数,当设为 true 时,会显示一条横跨整个图表的、带有最后一个绘图值的水平线。这样我们可以方便地将当前的绘图值与历史值进行比较。该参数默认为 false,此时不显示水平线。
offset 可选的整数参数,用于指定十字图向左(负值)或向右(正值)的偏移。该参数默认为0,即不产生偏移。
join 可选的布尔参数,当为 true 时,会用一条细线将单个的十字连接起来。当未设置此参数时,其默认值为 false,此时连续的十字之间不显示连接线。
editable 可选的布尔常量参数,用于指定我们是否可以手动编辑十字图(true)或不可以(false)。默认值为 true,这使得在脚本的选项窗口中手动更改十字图的设置成为可能。
show_last 可选的常量整数参数,用于指定十字图应该在最近的多少根K线上显示。该值是从最后一根K线向历史K线测量的。因此,通过 show_last=50,我们的十字图将只在最近的50根价格K线上出现。当未设置此参数时,十字图会对所有价格K线都显示。

注意

plot() 函数绘制数据之后,它会返回一个所谓的绘图对象。如果我们将该对象存储在一个变量中,稍后就可以使用TradingView的 fill() 函数来为TradingView绘图之间的背景着色。除此之外,plot() 返回的绘图对象目前没有其他用处。

示例:使用各种 plot() 参数的详尽十字图

plot() 函数的不同参数使得我们可以随心所欲地详细编写一个十字图。这里是一个创建十字图并使用 plot() 的多个参数来设置选项的例子:

//@version=5
indicator(title="Elaborate cross plot", overlay=true)

plot(ta.sma(close, 10), title="SMA",
     color=ta.rising(ta.sma(close, 10), 1) ? color.new(color.green, 10) :
     color.new(color.red, 10), linewidth=2, style=plot.style_cross, 
     show_last=50, editable=false)

这里,我们将 plot() 函数的第一个参数设为10周期的收盘价SMA(ta.sma(close, 10))。我们将其命名为“SMA”。我们有条件地设置 color 参数:当SMA上升时,绘图以绿色(color.green)显示;否则,我们使用红色(color.red)作为绘图颜色。我们通过 color.new() 函数使这两种颜色都具有10%的透明度。

linewidth 参数设为2使得绘图比正常的稍大一些。style 参数设为 plot.style_cross 则为我们创建了一个十字图。(如果我们没有设置该参数,plot() 会默认创建一个常规的线图。)

通过 show_last 参数,十字只在最近的50根价格K线上出现。而将 editable 设为 false 则可以防止用户在指标的设置窗口中随意修改该绘图的样式。

下图是这个详尽的十字图看起来的样子:

注意

如果所有相关的绘图设置都通过 plot() 参数提前设置好,一个指标或策略会变得更容易使用。

一旦我们在代码中定义了绘图设置,我们就不必每次将脚本添加到图表时都手动配置它的绘图设置了。此外,还有一些 plot() 参数没有对应的人工设置选项,因此通常最好尽可能地通过代码来配置你的绘图。

下面再看一个完整的示例指标:它以十字图绘制前一日的高低点,并在当日行情突破昨日范围时绘制日内极值、同时填充两者之间的背景。完整代码如下:

//@version=5
indicator(title="Plotting: cross plot example", overlay=true)

// 获取前一日高点和低点
prevDayHigh = request.security(syminfo.tickerid, "D", high)[1]
prevDayLow  = request.security(syminfo.tickerid, "D", low)[1]

// 绘制前一日高点和低点
prvHiDay = plot(prevDayHigh, style=plot.style_cross, color=color.red, linewidth=2)
prvLoDay = plot(prevDayLow, style=plot.style_cross, color=color.green, linewidth=2)

// 计算当日高点和低点
dayHigh = 0.0
dayLow  = 0.0
newDay  = dayofmonth != dayofmonth[1]
dayHigh := newDay ? high : math.max(dayHigh[1], high)
dayLow := newDay ? low : math.min(dayLow[1], low)

// 当日内极值超过昨日范围时进行绘制
hiDay = plot(dayHigh > prevDayHigh ? dayHigh : na,
     style=plot.style_cross, color=color.red, linewidth=2)
loDay = plot(dayLow < prevDayLow ? dayLow : na,
     style=plot.style_cross, color=color.red, linewidth=2)

// 高亮突破昨日范围的区域
fill(plot1=prvHiDay, plot2=hiDay, color=color.new(color.red, 90))
fill(plot1=prvLoDay, plot2=loDay, color=color.new(color.green, 90))

这里的内容很多,但让我们一步步来分析。首先,我们使用 indicator() 函数定义指标设置:

indicator(title="Plotting: cross plot example", overlay=true)

然后,我们获取前一日的高点和低点:

// 获取前一日高点和低点
prevDayHigh = request.security(syminfo.tickerid, "D", high)[1]
prevDayLow  = request.security(syminfo.tickerid, "D", low)[1]

为了检索这些数据,我们使用 request.security()。该函数可以从任何交易品种和/或时间周期加载数据,并使其可用于当前脚本。这两个 request.security() 函数调用都使用 syminfo.tickerid 来加载当前图表品种的数据,并使用 "D" 来加载日线数据。我们都使用了值为1的历史引用运算符 [],以获取前一日的数据,而非当日的数值。

接下来,我们在图表上以十字形式绘制这些值:

// 绘制前一日高点和低点
prvHiDay = plot(prevDayHigh, style=plot.style_cross, color=color.red, linewidth=2)
prvLoDay = plot(prevDayLow, style=plot.style_cross, color=color.green, linewidth=2)

第一个 plot() 调用以红色显示昨天的高点(prevDayHigh)。第二个则以绿色显示昨天的低点(prevDayLow)。两次调用都创建了一个比默认尺寸稍大的十字图(style=plot.style_cross, linewidth=2)。我们将 plot() 返回的值存储在变量中,以便稍后可以为这些绘图之间的背景着色。

然后,我们计算当日的高点和低点:

// 计算当日高点和低点
dayHigh = 0.0
dayLow  = 0.0
newDay  = dayofmonth != dayofmonth[1]
dayHigh := newDay ? high : math.max(dayHigh[1], high)
dayLow := newDay ? low : math.min(dayLow[1], low)

我们首先创建了两个变量 dayHighdayLow,并创建了 newDay 变量来判断当前K线是否为新一天的第一根K线。接着,我们更新 dayHigh 变量:当 newDaytrue 时,日内高点就是该K线的最高价;否则,我们取前一根K线的 dayHigh 值和当前K线最高价中的较大者。dayLow 变量的计算逻辑类似,只是它追踪的是最低价。

接下来,我们绘制日内高点和低点:

// 当日内极值超过昨日范围时进行绘制
hiDay = plot(dayHigh > prevDayHigh ? dayHigh : na, style=plot.style_cross, color=color.red, linewidth=2)
loDay = plot(dayLow < prevDayLow ? dayLow : na, style=plot.style_cross, color=color.red, linewidth=2)

为了不让图表过于混乱,我们只在当日高低点超过昨日高低点时才显示它们。第一个 plot() 调用绘制 dayHigh 值,但只有在 dayHigh > prevDayHigh 这个条件为 true 时才绘制。第二个 plot() 调用则绘制 dayLow 值,但只有在 dayLow < prevDayLow 时才绘制。注意我们在这里将 plot() 返回的值存储在变量中,这是为了下一步填充背景:

// 高亮突破昨日范围的区域
fill(plot1=prvHiDay, plot2=hiDay, color=color.new(color.red, 90))
fill(plot1=prvLoDay, plot2=loDay, color=color.new(color.green, 90))

我们使用 fill() 函数为背景着色。第一个语句为昨日和今日的高点(分别是 prvHiDayhiDay 绘图变量)之间的背景着上90%透明度的红色。第二个 fill() 调用则为昨日和今日的低点(prvLoDayloDay)之间的背景着上90%透明度的绿色。

总结

在TradingView图表上绘制数值是通过 plot() 函数完成的。该函数有一个必需的参数:其第一个参数(series),用于指定要显示的值。如果我们想让我们的数据显示为小十字(+),我们将该函数的 style 参数设为 plot.style_cross,否则 plot() 会默认创建一个常规的线图。

plot() 函数有几个影响我们十字图的参数。通过 title,我们可以为绘图命名;通过 color 参数,我们为绘图指定颜色;linewidth 则影响我们的十字看起来有多大。

通过 trackprice 参数,我们可以用最后一个绘图值在整个图表上显示一条水平线。show_last 则让十字只在一定数量的最近K线上显示。通过 plot()offset 参数,我们可以向左或向右移动十字图。join 会用一条细线连接单个的十字。最后,editable 参数可以阻止用户在指标或策略的设置中手动更改十字图的外观。

编写圆圈图(plot.style_circles)

我们的TradingView指标和策略脚本可以创建多种绘图类型,其中之一就是圆圈图,它在图表上显示为实心点(•)。让我们来看看如何在TradingView中编写这种绘图。

使用 plot() 编写一个圆圈图(•)

指标和策略脚本通过TradingView的 plot() 函数在图表上绘制数值。通过这种方式,我们的代码,例如,可以为MACD指标绘制常规的线图,或者绘制一个直方图来显示成交量。

另一种绘图类型是圆圈图,它在图表上显示为一系列实心点(•)。要让 plot() 函数显示这些小圆圈,需要满足两个要求:首先,将其第一个参数设为我们想要绘制的数据;然后,将其 style 参数设为 plot.style_circles

所以,创建一个基础圆圈图的方式如下:

plot(ta.sma(close, 10), style=plot.style_circles)

这行代码创建的圆圈看起来如下。(在本文后面,我们将学习如何让圆圈变得更大。)

我们通常使用圆圈图来显示数据的趋势。由于每个圆圈都是一个独立的点,它们最适合那些每根K线变化不大的数值(例如移动平均线和盈利目标)。对于每根K线变化很大的值(例如成交量),这些点看起来会显得很随机,难以阅读。这类数值使用柱状图、直方图或面积图来显示效果会更好。

与线图,特别是面积图相比,圆圈图是一种更微妙地显示数据的方式。圆圈图看起来与十字图非常相似,并且实际上有很多相同的特性。

圆圈图的一个强大特性是它们能很好地处理缺失的数据。当一个绘图在某一根K线上没有数值时,圆圈图会直接停止绘制。这与基础线图和标准面积图的做法不同,因为后两者确实会画线穿过没有数据的K线,这一特性有时可能具有误导性。

在TradingView中编写一个基础的圆圈图

要创建一个圆圈图,我们将 plot() 函数的 style 参数设为 plot.style_circles。下面是一个示例指标:

//@version=5
indicator(title="Circles plot example", overlay=true)

plot(ta.ema(ta.sma(close, 10), 20), style=plot.style_circles,
     linewidth=3)

这个迷你指标只有两条语句。第一条调用 indicator() 函数来定义指标的名称和叠加设置。

第二条语句执行 plot() 函数。我们在这里绘制的值是一个10周期SMA的20周期EMA。我们将这个平滑后的移动平均线显示为一个圆圈图。为此,我们将该函数的 style 参数设为 plot.style_circles。并且通过将 linewidth 参数设为3,使绘图比正常的更粗一些(任何绘图的默认大小都是1)。

这个圆圈图看起来是这样的:

plot() 函数的圆圈图参数

正如上面的快速示例所示,plot() 函数有几个用于指定我们圆圈图外观的参数。通过它们,我们可以,例如,改变绘图的粗细或使用条件性颜色。

以下是我们可以与圆圈图一起使用的所有 plot() 参数:

参数 描述
series 必需参数,指定要绘制的数据。如果此数据中存在缺口,圆圈图仍能很好地绘制数据。我们也可以通过有条件地将 series 设为 na 来关闭圆圈图的显示。
title 可选的常量字符串参数,用于为绘图命名。一个描述性的名称有助于将该绘图与其他绘图区分开。该标题会显示在图表的数据窗口、警报设置窗口以及指标叠加指标功能中。
color 可选参数,用于设置圆圈的颜色。可接受的值包括标准颜色、十六进制颜色值和透明色。绘图颜色可以在每根K线上相同,也可以根据条件而变化。
linewidth 可选的整数参数,用于指定圆圈的大小。未设置时默认为1。我们为该参数设定的值越大,圆圈在图表上显示的就越大。
style 可选参数,用于定义绘图类型。对于圆圈图(•),我们将此参数设为 plot.style_circles
trackprice 可选的布尔参数,当设为 true 时,会显示一条横跨整个图表的、带有最后一个绘图值的水平线。这样我们可以方便地将最后一个绘图值与历史值进行比较。该参数默认为 false,此时不显示水平线。
offset 可选的整数参数,用于指定圆圈向左(负值)或向右(正值)的偏移。该参数的默认值为0,即不产生偏移。
join 可选的布尔参数,当为 true 时,会用一条细线将独立的圆圈连接起来。当未设置此参数时,其默认值为 false,此时连续的圆圈之间不显示连接线。
editable 可选的布尔常量参数,用于指定我们是否可以手动编辑圆圈图(true)或不可以(false)。默认值为 true,这使得在脚本的选项窗口中手动更改圆圈图的设置成为可能。
show_last 可选的常量整数参数,用于指定圆圈图应该在最近的多少根K线上显示。该值是从最后一根K线向历史K线测量的。因此,通过 show_last=30,我们的圆圈图将只在最近的30根价格K线上出现。当未设置 show_last 时,圆圈图会对所有价格K线都显示。

注意

plot() 函数创建绘图后,它会返回一个所谓的绘图对象。如果我们将该对象存储在一个变量中,稍后就可以使用TradingView的 fill() 函数来为TradingView绘图之间的背景着色。除此之外,plot() 返回的绘图对象目前没有其他用处。

示例:使用各种 plot() 参数的详尽圆圈图

plot() 函数的不同参数使得我们可以随心所欲地详细编写一个圆圈图。这里是一个创建圆圈图并使用多个 plot() 参数来设置选项的例子:

//@version=5
indicator(title="Elaborate circles plot", overlay=true)

plot(ta.ema(close, 12), title="EMA",
     color=ta.rising(ta.ema(close, 12), 1) ? color.new(color.green, 50) : 
     color.new(color.red, 50), linewidth=3, style=plot.style_circles,
     show_last=50, editable=false, join=true)

我们在这里将 plot() 的第一个参数设为12周期的EMA (ta.ema(close, 12))。通过 title,我们将其命名为“EMA”。我们为 color 参数赋予了一个条件性颜色。

ta.rising() 函数指示EMA正在上升时,条件运算符会使绘图使用绿色(color.green);否则,我们使用红色(color.red)作为绘图颜色。我们通过 color.new() 函数使这两种颜色都具有50%的透明度。

linewidth 参数设为3使得绘图比标准尺寸大几级。style 设为 plot.style_circles 则让我们将移动平均线显示为小的实心点。show_last 设为50则只在最近的五十根价格K线上显示该绘图。由于我们将 editable 参数设为 false,用户将无法在指标设置的样式标签页中手动编辑此绘图。最后,通过 join=true,我们在独立的圆圈之间创建了一条细线。

下图是这个详尽的圆圈图看起来的样子:

注意

如果所有相关的绘图设置都预先通过 plot() 参数定义好,那么指标或策略会变得更容易使用。这样做前期需要一些工作,但之后每次我们将脚本添加到图表时,它就已经被正确配置好了。

另一种选择是每次都手动配置绘图的选项。不依赖手动绘图设置的另一个原因是,一些绘图特性只能通过代码来设置。

影响TradingView圆圈图的其他设置

我们上面讨论的 plot() 参数配置了大部分,但并非全部的圆圈图设置。还有三个通用的脚本设置会影响圆圈图的显示方式。这些选项是:

  • indicator()strategy() 函数的 scale 参数用于指定脚本的绘图是应该使用图表的右侧价格坐标轴、左侧坐标轴,还是不使用任何价格坐标轴。
  • 通过 indicator()strategy() 函数的 precision 参数,我们指定小数点后应该显示多少位数值。该设置会影响脚本创建的所有绘图。
  • 通过 indicator()strategy() 函数的 overlay 参数,我们指定脚本的绘图是应该显示在主图表的交易品种上,还是在一个单独的图表面板中。

示例:使用 plot() 以圆圈显示追踪止损水平

让我们通过一个完整的示例脚本来看看圆圈图是如何工作的。下方的示例策略使用圆圈图来显示追踪止损水平,这样当有持仓时,我们就可以追踪止损的变化情况。鉴于圆圈图只在有数值时才进行绘制(而不会在数据缺失时绘制实心圆),这些圆圈只会在有市场持仓时才显示。

至于策略本身,当8周期EMA上穿22周期EMA时,它会做多;如果快线均线下穿慢线均线,我们则做空。追踪止损则基于50周期的EMA。下图是该脚本在图表上的样子:

该脚本的完整代码如下:

//@version=5
strategy(title="Plotting: circles example", overlay=true)

// 计算数值
quickMA = ta.ema(close, 8)
medMA   = ta.ema(close, 22)
slowMA  = ta.ema(close, 50)

// 绘制数值
plot(quickMA, style=plot.style_line, color=color.orange)
plot(medMA, style=plot.style_line, color=color.teal)

// 确定条件
goLong = ta.crossover(quickMA, medMA) and
     slowMA > slowMA[1] and 
     slowMA[1] > slowMA[2]
goShort = ta.crossunder(quickMA, medMA) and
     slowMA < slowMA[1] and 
     slowMA[1] < slowMA[2]

// 提交入场订单
if goLong
    strategy.entry("EL", strategy.long)
if goShort
    strategy.entry("ES", strategy.short)

// 确定追踪止损
trailLong  = 0.0
trailShort = 0.0
trailLong := strategy.position_size > 0 ?
     math.max(slowMA, nz(trailLong[1], 0)) : na
trailShort := strategy.position_size < 0 ?
     math.min(slowMA, nz(trailShort[1], 99999)) : na

// 提交止损订单
strategy.exit("XL", from_entry="EL", stop=trailLong)
strategy.exit("XS", from_entry="ES", stop=trailShort)

// 绘制追踪止损
plot(trailLong, style=plot.style_circles, linewidth=3, color=color.green)
plot(trailShort, style=plot.style_circles, linewidth=3, color=color.red)

我们来一起分析一下代码。首先,我们使用 strategy() 函数定义策略的属性:

strategy(title="Plotting: circles example", overlay=true)

然后,我们计算移动平均线:

// 计算数值
quickMA = ta.ema(close, 8)
medMA   = ta.ema(close, 22)
slowMA  = ta.ema(close, 50)

我们使用 ta.ema() 函数来获取指数移动平均线。该函数需要两个参数:一个用于计算的数据序列和以K线数量为单位的周期。我们分别计算了8周期、22周期和50周期的EMA,并将它们的值存储在 quickMAmedMAslowMA 变量中。

接下来,我们使用 plot() 函数在图表上绘制两条移动平均线:

// 绘制数值
plot(quickMA, style=plot.style_line, color=color.orange)
plot(medMA, style=plot.style_line, color=color.teal)

这段代码创建了两个常规的线图(style=plot.style_line),分别以橙色和青色显示8周期和22周期的EMA。

然后,我们确定策略的交易条件:

// 确定条件
goLong = ta.crossover(quickMA, medMA) and
     slowMA > slowMA[1] and 
     slowMA[1] > slowMA[2]
goShort = ta.crossunder(quickMA, medMA) and
     slowMA < slowMA[1] and 
     slowMA[1] < slowMA[2]

我们寻找两种模式来建立多头头寸:8周期EMA上穿22周期EMA,并且50周期EMA连续两根K线上升。我们使用 ta.crossover() 函数和 and 运算符来组合这些逻辑检查。goShort 变量的逻辑则完全相反,它使用 ta.crossunder() 并检查50周期EMA是否连续两根K线下跌。

我们接下来提交策略的入场订单:

// 提交入场订单
if goLong
    strategy.entry("EL", strategy.long)
if goShort
    strategy.entry("ES", strategy.short)

goLong 变量为 true 时,我们使用 strategy.entry() 函数提交一个名为“EL”的多头订单(strategy.long)。当 goShorttrue 时,则提交一个名为“ES”的空头订单(strategy.short)。

接下来,我们计算策略的追踪止损价格:

// 确定追踪止损
trailLong  = 0.0
trailShort = 0.0
trailLong := strategy.position_size > 0 ?
     math.max(slowMA, nz(trailLong[1], 0)) : na
trailShort := strategy.position_size < 0 ?
     math.min(slowMA, nz(trailShort[1], 99999)) : na

我们在这里创建了两个变量:trailLongtrailShort。我们使用条件运算符(?:)来设定 trailLong 变量的值。该运算符首先评估策略当前的持仓规模(strategy.position_size)。当策略持有多头时,我们使用 math.max() 函数来计算追踪止损价格。

nz(trailLong[1], 0) 这个写法的目的是:获取 trailLong 在前一根K线上的值,但如果该值不存在(即为 na),则返回0作为替代。这样可以确保 math.max() 总能进行有效的数值比较。通过这种方式,我们实现了追踪止损的效果:止损位从50周期EMA开始,然后只向上移动。当策略没有持仓时,我们返回 na 来重置trailLong 变量。

trailShort 变量的更新方式非常相似,只是它要求策略持有空头,并使用 math.min() 来实现只向下移动的追踪止损。这里使用的 99999 是一个很大的初始值,以确保止损位总是从50周期EMA的值开始。

既然我们知道了追踪止损的价格,我们就让策略提交它们:

// 提交止损订单
strategy.exit("XL", from_entry="EL", stop=trailLong)
strategy.exit("XS", from_entry="ES", stop=trailShort)

我们通过两次 strategy.exit() 函数调用来提交追踪止损。第一个创建了一个ID为“XL”的平仓订单,它只平掉由“EL”订单建立的仓位,其止损价格由我们刚计算的 trailLong 决定。第二个则为“ES”空头订单设置了止损。

最后,代码的最后一部分在图表上绘制了追踪止损:

// 绘制追踪止损
plot(trailLong, style=plot.style_circles, linewidth=3, color=color.green)
plot(trailShort, style=plot.style_circles, linewidth=3, color=color.red)

我们使用TradingView的 plot() 函数在图表上绘制数值。第一个 plot() 语句在图表上显示多头的追踪止损(trailLong),并将其显示为实心圆(style=plot.style_circles)。第二个语句则以红色的圆圈绘制空头的追踪止损价格。

之前,当没有多头或空头持仓时,我们将 trailLongtrailShort 设为了 na 值。这个 na 值在这里还有一个好处:它可以关闭绘图。这是因为当 trailLong 的值在某次脚本计算中为 na 时,plot() 将不会在图表上显示任何东西。trailShort 也是如此。通过这种方式,我们最终只在有实际的多头或空头持仓时,才绘制追踪止损的价格。

总结

我们使用 plot() 函数在TradingView图表上绘制数值。该函数有一个必需的参数:其第一个参数(series),用于指定要显示的值。如果我们想让数据显示为一系列实心点(•),我们还必须将 plot()style 参数设为 plot.style_circles,否则我们会得到一个常规的线图。

plot() 函数有几个影响我们圆圈图的参数。通过 title,我们可以为绘图命名;通过 color 参数,我们为绘图指定颜色;linewidth 则指定实心圆的大小。

trackprice 参数会在整个图表上显示一条带有最后一个绘图值的水平线。通过 offset,我们指定绘图是否应该向左或向右移动。show_last 则将绘图限制在最近的 n 根K线上。通过 join 参数,我们让TradingView在连续的圆圈之间画一条细线。最后,editable 参数可以阻止用户在指标或策略的设置中手动更改圆圈图的外观。

赞(0)
未经允许不得转载:图道交易 » Pine Script(157):编写直方图、十字图与圆圈图
分享到

评论 抢沙发

登录

找回密码

注册