叠加多个fill()着色的背景区域
在TradingView中,我们可以为背景的某个区域着色,并利用该功能高亮显示支撑和阻力区,我们还通过一种变通方法,实现了为曲线和水平线之间的背景着色。但当我们在同一个脚本里多次调用fill()时,这些着色区域会如何相互叠加呢?
在TradingView Pine中重复为背景区域着色
我们可以使用标准的TradingView颜色和十六进制颜色值,并与像 fill() 这样的TradingView函数结合使用。该函数可以为图表上两条曲线或两条水平线之间的背景区域着色。
为了知道该为哪个区域填充颜色,fill() 要么需要两个绘图对象(由 plot() 函数返回),要么需要两条水平线对象(由 hline() 函数返回)。这些对象代表了一个绘图或水平线的实例,就像一个字符串变量代表一段特定的文本,一个数值变量代表一个值一样。
fill() 函数可以为支撑和阻力区域的背景着色,也可以为曲线和水平线之间的背景着色,我们甚至可以用它来为不可见绘图之间的背景着色。fill() 的另一个应用是将着色的背景区域相互叠加,我们通过在同一个脚本中多次使用此函数来实现这一点。为了看看这是如何工作的,让我们来看一个示例指标。
组合TradingView的着色背景区域
在下方的示例指标中,我们使用 fill() 为两个背景区域着色。第一个区域是30周期内的最高价和最低价之间。在该背景区域内部,我们再为最近10根价格K线的最高价和最低价之间的区域着色。这样,我们着色的背景就提供了一种粗略的趋势指示:一个初期的趋势,其K线会移动到10周期高低点之外;而强劲的趋势,其价格则会移动到30周期极值之外。
在讨论完代码之后,我们将看看该指标在图表上的显示效果,以及 fill() 函数的调用顺序如何影响指标。但首先,是代码:
//@version=5
indicator(title="Colouring background areas repeatedly", overlay=true)
// 输入选项
shortLookback = input.int(10, title="Short lookback", minval=3)
longLookback = input.int(30, title="Long lookback", minval=10)
smoothLength = input.int(7, title="Double-smooth length", minval=1)
plotOffset = input.int(1, title="Plot offset", minval=0)
// 计算数值
highestValue = ta.highest(high, shortLookback)
highestSmooth1 = ta.sma(highestValue, smoothLength)
highestSmooth2 = ta.sma(highestSmooth1, smoothLength)
highestHi = highestSmooth2
lowestLo = ta.sma(ta.sma(ta.lowest(low, shortLookback), smoothLength), smoothLength)
// 绘制数值
highPlot = plot(highestHi, color=color.orange, linewidth=2)
lowPlot = plot(lowestLo, color=color.orange, linewidth=2)
highestPlot = plot(ta.highest(high, longLookback)[plotOffset], color=#1E90FF)
lowestPlot = plot(ta.lowest(low, longLookback)[plotOffset], color=#1E90FF)
// 填充背景区域
fill(plot1=highestPlot, plot2=lowestPlot, color=color.new(#1E90FF, 80))
fill(plot1=highPlot, plot2=lowPlot, color=color.new(#FFD700, 80))
我们以 indicator() 函数开始,设置指标的属性。通过将其 overlay 参数设为 true,脚本会显示在主数据系列上,而不是在单独的图表面板中。
然后,我们向脚本添加几个输入选项:
// 输入选项
shortLookback = input.int(10, title="Short lookback", minval=3)
longLookback = input.int(30, title="Long lookback", minval=10)
smoothLength = input.int(7, title="Double-smooth length", minval=1)
plotOffset = input.int(1, title="Plot offset", minval=0)
这些输入都是整数输入,我们通过Pine Script的 input.int() 函数来创建它们。该函数不仅创建了输入项本身,还会返回该设置的当前值。我们在这里使用赋值运算符(=)将这些值存储在变量中,这样稍后就可以在脚本中通过变量来引用输入的当前值。
第一个输入名为“Short lookback”,默认值为10,最小值为3。我们将它的当前值存储在 shortLookback 变量中。
接下来的几个输入分别名为“Long lookback”、“Double-smooth length”和“Plot offset”,它们的值分别存储在 longLookback、smoothLength 和 plotOffset 变量中,供后续使用。plotOffset 的最小值为0,确保它总是一个正数。
创建完输入后,我们对最短周期内的最高价和最低价进行平均:
// 计算数值
highestValue = ta.highest(high, shortLookback)
highestSmooth1 = ta.sma(highestValue, smoothLength)
highestSmooth2 = ta.sma(highestSmooth1, smoothLength)
highestHi = highestSmooth2
lowestLo = ta.sma(ta.sma(ta.lowest(low, shortLookback), smoothLength), smoothLength)
我们在这里使用两种方法来平滑最高价和最低价:一种使用中间变量使步骤清晰,另一种则使用单个语句。
为了平均最高价,我们首先使用 ta.highest() 获取该值。然后,我们通过两次调用 ta.sma() 函数来对其进行双重平滑处理,并将最终结果存储在 highestHi 变量中。
然而,这些不同的步骤可以被简化为一行代码。我们在设置 lowestLo 变量的值时就是这么做的,我们将 ta.lowest() 和两个 ta.sma() 函数嵌套在了一行代码中。当函数被放在其他函数的括号内时,TradingView Pine会首先评估最内层的函数,然后由内向外地工作。
接下来是绘制一些数值:
// 绘制数值
highPlot = plot(highestHi, color=color.orange, linewidth=2)
lowPlot = plot(lowestLo, color=color.orange, linewidth=2)
highestPlot = plot(ta.highest(high, longLookback)[plotOffset], color=#1E90FF)
lowestPlot = plot(ta.lowest(low, longLookback)[plotOffset], color=#1E90FF)
我们使用 plot() 在图表上绘制数值,该函数默认将数据绘制成一条连续的线。plot() 函数还会返回一个绘图对象。这里我们通过赋值运算符(=)将这些对象存储在变量中,以便稍后在为背景区域着色时引用它们。
前两个 plot() 调用显示了双重平滑后的最高价和最低价,为橙色。
接下来的两个语句绘制了30周期的最高价和最低价(假设“Long lookback”输入仍为其默认值30)。这些 plot() 函数调用的第一个参数被设为 ta.highest() 函数。这里有个小麻烦:如果我们绘制一个包含当前K线值的最高价线,那么价格K线将永远无法突破该范围。
我们通过在 ta.highest() 函数后面紧跟着加上历史引用运算符 [] 并传入 plotOffset 输入变量来解决这个问题。该运算符会返回指定数量的K线之前的值。例如,当 plotOffset 设为1时,我们在当前K线上绘制的是前一根K线的最高价。这样,当前K线的最高价仍然可以突破这个最高价线。
使用 plotOffset 输入变量的好处是,我们可以在脚本的设置中手动指定绘图应该向历史K线偏移多少。这条最高价线的颜色被设为 #1E90FF,即道奇蓝的十六进制颜色值。我们将其绘图对象存储在 highestPlot 变量中。
较长回看周期的最低价也以类似的方式绘制,并将其绘图对象存储在 lowestPlot 变量中。
然后,我们填充这些曲线之间的背景:
fill(plot1=highestPlot, plot2=lowestPlot, color=color.new(#1E90FF, 80))
fill(plot1=highPlot, plot2=lowPlot, color=color.new(#FFD700, 80))
fill() 函数可以为背景的某个区域着色,其 plot1 和 plot2 参数用于指定该区域的边界。在第一个 fill() 语句中,我们将这两个参数设为30周期的最高价(highestPlot)和最低价(lowestPlot)线。该函数的 color 参数被设为 #1E90FF,一个我们通过 color.new() 函数设为80%透明度的十六进制颜色。
我们用第二个 fill() 语句结束本例,它为双重平滑后的10周期最高价(highPlot)和最低价(lowPlot)之间的背景着色。这个背景区域被着以 #FFD700,即金色的十六进制颜色值,并通过 color.new() 将其设为80%透明。
在TradingView中叠加着色的背景区域
当我们将上述示例指标添加到S&P 500指数差价合约图表上时,它看起来是这样的:
应用到英镑/美元图表上时,该示例如下显示:
该脚本的输入选项如下:
现在,让我们更改这些设置,将“Plot Offset”设为3,“Double-smooth Length”设为10,“Short Lookback”周期设为25。前一张英镑/美元图表现在变为:
不同方式的背景着色:语句顺序的影响
当 fill() 在一个脚本中被重复使用时,我们放置这些 fill() 语句的顺序很重要。这是因为第一个 fill() 函数调用创建了最底层的着色背景区域,而任何后续的 fill() 函数调用都会创建一个叠加在前一个之上的填充背景。因此,最后一个 fill() 函数调用会创建最顶层的着色背景。这种视觉效果的明显程度取决于背景的透明度。
为了看看这个效果如何,让我们回顾一下上面的编程示例。在其中,我们首先为30周期高低点之间的背景填充蓝色,然后为10周期高低点之间的背景填充黄色:
fill(plot1=highestPlot, plot2=lowestPlot,
color=color.new(#1E90FF, 80)) // 蓝色背景
fill(plot1=highPlot, plot2=lowPlot,
color=color.new(#FFD700, 80)) // 黄色背景
这看起来是这样的:
现在,让我们改变 fill() 语句的顺序,以便首先创建黄色的背景。为此,我们将它们的顺序更改为如下:
fill(plot1=highPlot, plot2=lowPlot,
color=color.new(#FFD700, 80)) // 黄色背景
fill(plot1=highestPlot, plot2=lowestPlot,
color=color.new(#1E90FF, 80)) // 蓝色背景
现在保存脚本会将图表变为:
现在,黄色的背景区域变得不那么明显了,因为它被放置在了蓝色的后面。但由于两个背景的高透明度,我们仍然可以清楚地看到黄色的背景,这是因为它透过了蓝色的背景。
然而,当我们把透明度降低到40%时,这个效果就改变了:
fill(plot1=highPlot, plot2=lowPlot,
color=color.new(#FFD700, 40)) // 黄色背景
fill(plot1=highestPlot, plot2=lowestPlot,
color=color.new(#1E90FF, 40)) // 蓝色背景
这会产生如下效果:
现在,黄色的背景几乎看不见了(如果透明度更低,将完全被隐藏)。如果我们再次交换两个 fill() 语句,蓝色的背景区域会再次被首先创建,黄色的则被放置在它之上:
fill(plot1=highestPlot, plot2=lowestPlot,
color=color.new(#1E90FF, 40)) // 蓝色背景
fill(plot1=highPlot, plot2=lowPlot,
color=color.new(#FFD700, 40)) // 黄色背景
虽然这两个 fill() 语句现在与上面讨论的编程示例中的顺序相同,但由于较低的透明度,我们现在可以清楚地看到背景是如何相互叠加的:
总结
fill() 函数可以为图表背景的某个区域着色。它填充的是两条曲线对象(由 plot() 函数返回)之间或两条水平线对象(由 hline() 函数返回)之间的区域。通过在同一个脚本中重复使用 fill() 函数,多个背景区域会被着色并相互叠加。此时,我们调用 fill() 函数的顺序就很重要:第一个 fill() 函数创建了最底层的着色背景区域,其后的任何 fill() 函数调用都会创建一个叠加在之前背景之上的着色区域,而最后一个 fill() 语句则会创建最顶层的着色背景部分。
结合bgcolor()和fill()为价格带与K线背景着色
在TradingView中,我们可以为整个图表背景(从上到下)着色,也可以为背景的某个区域着色。但这两种功能有何不同,我们又该如何将它们结合起来呢?
在TradingView中为图表区域和完整背景着色
TradingView的背景可以使用标准的TradingView基础颜色或十六进制颜色值进行着色。这些背景可以显示在图表主交易品种的区域,也可以显示在脚本的子图中,具体取决于 indicator() 或 strategy() 函数的 overlay 参数分别被设为 true 还是 false。
TradingView中有两种类型的背景着色。第一种由 bgcolor() 函数创建,它会从上到下为K线的完整背景赋予指定的颜色。
fill() 函数也为背景着色,但它不是为整个背景,而是为两条曲线或两条水平线之间的背景区域着色。为了知道该为哪个区域填充颜色,该函数要么需要两个绘图对象(由 plot() 函数返回),要么需要两条水平线对象(由 hline() 函数返回)。虽然对象听起来很抽象,但它们代表了一个绘图或线条的实例,就像一个数值变量代表一个特定的数字一样。
bgcolor() 和 fill() 函数有相似之处也有不同之处。它们的相同之处包括都拥有一个 color 参数来设置背景颜色。一个显著的区别是 bgcolor() 可以有条件地为背景着色,而 fill() 则不能。这意味着由 fill() 创建的背景在每一根K线上都是相同的,而 bgcolor() 则可以使用不同的颜色,甚至可以关闭背景着色。
为了更好地理解 bgcolor() 和 fill() 之间的差异与协同作用,让我们来看一个结合了两者的示例指标。
在TradingView中以编程方式为背景或图表区域着色
在下方的例子中,我们绘制了一条EMA(指数移动平均线)以及四条价格通道。这些价格通道是根据一定数量的标准差计算的,其中两条位于EMA之上,另外两条位于该均线之下。
这就像布林带,一个每当价格超过其通道时就产生趋势跟踪信号的指标。在我们的示例指标中,当价格移动到通道之外时,我们会为K线的完整背景着色,同时使用 fill() 为通道之间的区域着色。之后,我们将看看该指标在图表上的样子,但首先来讨论代码:
//@version=5
indicator(title="Overlaying coloured background areas", overlay=true)
// 输入选项
priceData = input.source(hl2, title="Price data")
maLength = input.int(20, title="MA length")
sdLength = input.int(12, title="StDev length")
offset1 = input.float(1.25, title="1st StDev offset", minval=0.1)
offset2 = input.float(2.25, title="2nd StDev offset", minval=0.1)
colourBg = input.bool(true, title="Colour background?")
highLowLen = input.int(20, title="High/low lookback")
// 计算数值
maValue = ta.ema(priceData, maLength)
sdValue = ta.stdev(priceData, sdLength)
maPlus2 = maValue + (offset2 * sdValue)
maPlus1 = maValue + (offset1 * sdValue)
maMin1 = maValue - (offset1 * sdValue)
maMin2 = maValue - (offset2 * sdValue)
// 绘制数值
plotPlus2 = plot(maPlus2, color=color.green, linewidth=2)
plotPlus1 = plot(maPlus1, color=color.green, linewidth=2)
maPlot = plot(maValue, color=color.gray, style=plot.style_circles, linewidth=2)
plotMin1 = plot(maMin1, color=color.red, linewidth=2)
plotMin2 = plot(maMin2, color=color.red, linewidth=2)
// 填充曲线之间的背景区域
fill(plot1=plotPlus2, plot2=plotPlus1, color=color.new(color.green, 87))
fill(plot1=plotPlus1, plot2=maPlot, color=color.new(color.green, 92))
fill(plot1=maPlot, plot2=plotMin1, color=color.new(color.red, 92))
fill(plot1=plotMin1, plot2=plotMin2, color=color.new(color.red, 87))
// 从上到下为完整背景着色
backgroundColour = if colourBg and priceData > maPlus2
color.new(color.green, 90)
else if colourBg and priceData < maMin2
color.new(color.red, 90)
bgcolor(backgroundColour)
// 为新高/新低创建着色背景
newHigh = high == ta.highest(high, highLowLen)
newLow = low == ta.lowest(low, highLowLen)
highsLowsBackground = if colourBg and newHigh and priceData > maPlus2
color.new(color.lime, 85)
else if colourBg and newLow and priceData < maMin2
color.new(color.fuchsia, 85)
bgcolor(highsLowsBackground)
我们以 indicator() 函数开始该指标。通过将其 overlay 参数设为 true,脚本会显示在主价格图表区域,而不是在一个单独的子图中。这也意味着我们着色的背景将被应用到图表的交易品种上。
接下来,我们向脚本添加几个输入项:
// 输入选项
priceData = input.source(hl2, title="Price data")
maLength = input.int(20, title="MA length")
sdLength = input.int(12, title="StDev length")
offset1 = input.float(1.25, title="1st StDev offset", minval=0.1)
offset2 = input.float(2.25, title="2nd StDev offset", minval=0.1)
colourBg = input.bool(true, title="Colour background?")
highLowLen = input.int(20, title="High/low lookback")
输入项使得我们可以方便地手动更改脚本代码中使用的值。我们将输入函数的结果存储在变量中,以便后续在代码中通过该变量来引用输入的当前值。
我们创建了多种类型的输入。第一个是 input.source() 创建的数据源输入,它允许我们选择不同的价格数据(如高、低、收盘价),默认值为 hl2(K线的中点价格)。接下来的几个是 input.int() 创建的整数输入和 input.float() 创建的浮点数输入,用于设置均线周期、标准差周期以及通道偏移量。最后,我们还创建了两个布尔型输入,用于切换背景着色和高低点回看周期的设置。
在创建完输入选项后,我们计算几个数值:
maValue = ta.ema(priceData, maLength)
sdValue = ta.stdev(priceData, sdLength)
maPlus2 = maValue + (offset2 * sdValue)
maPlus1 = maValue + (offset1 * sdValue)
maMin1 = maValue - (offset1 * sdValue)
maMin2 = maValue - (offset2 * sdValue)
我们首先使用 ta.ema() 计算移动平均线,并使用 ta.stdev() 计算标准差。然后,我们通过将EMA的值加上或减去偏移量乘以标准差,来确定价格通道的边界。
接下来,这些值被绘制在图表上:
plotPlus2 = plot(maPlus2, color=color.green, linewidth=2)
plotPlus1 = plot(maPlus1, color=color.green, linewidth=2)
maPlot = plot(maValue, color=color.gray, style=plot.style_circles, linewidth=2)
plotMin1 = plot(maMin1, color=color.red, linewidth=2)
plotMin2 = plot(maMin2, color=color.red, linewidth=2)
我们使用 plot() 在图表上绘制数值。plot() 函数总是返回一个绘图对象,我们通常不需要用到它。但在我们当前的示例中,情况并非如此:由于我们将要填充两条曲线之间的背景区域,我们需要将每个绘图对象存储在一个变量中供后续使用。我们绘制了上下共四条通道线,以及用圆圈样式绘制的EMA中线。
现在,让我们使用这些绘图对象来为几个图表区域着色:
fill(plot1=plotPlus2, plot2=plotPlus1, color=color.new(color.green, 87))
fill(plot1=plotPlus1, plot2=maPlot, color=color.new(color.green, 92))
fill(plot1=maPlot, plot2=plotMin1, color=color.new(color.red, 92))
fill(plot1=plotMin1, plot2=plotMin2, color=color.new(color.red, 87))
我们在这里四次使用 fill() 函数,每次都为两条曲线之间的背景区域着色。例如,第一个 fill() 调用填充了 plotPlus2 和 plotPlus1(即EMA上方的两条价格通道线)之间的区域。我们为不同的区域赋予了不同透明度的绿色和红色。
在为曲线之间的区域着色后,我们通过着色背景来高亮显示移动到价格通道之外的价格K线:
// 从上到下为完整背景着色
backgroundColour = if colourBg and priceData > maPlus2
color.new(color.green, 90)
else if colourBg and priceData < maMin2
color.new(color.red, 90)
bgcolor(backgroundColour)
我们通过一个级联 if 语句来为 backgroundColour 变量赋值。第一个 if 条件测试“Colour background?”输入是否被启用 并且 价格是否大于最上方的价格通道。如果都满足,我们返回一个90%透明的绿色。如果条件不满足,第二个 if 条件会运行,它检查背景着色是否被启用 并且 价格是否低于最下方的价格通道,如果是,则返回一个90%透明的红色。如果两个 if 条件都不满足,Pine Script会隐式地返回 na 值,这会关闭背景着色。最后,我们调用 bgcolor() 函数并传入 backgroundColour 变量。
示例的最后一部分是另一个有条件地为背景着色的代码段:
// 为新高/新低创建着色背景
newHigh = high == ta.highest(high, highLowLen)
newLow = low == ta.lowest(low, highLowLen)
highsLowsBackground = if colourBg and newHigh and priceData > maPlus2
color.new(color.lime, 85)
else if colourBg and newLow and priceData < maMin2
color.new(color.fuchsia, 85)
bgcolor(highsLowsBackground)
我们首先创建了两个布尔变量:newHigh 和 newLow,用于判断当前K线是否创下了指定周期内的新高或新低。然后,我们通过另一个级联 if 语句来为 highsLowsBackground 变量赋值。
第一个 if 条件判断背景着色是否被启用、是否创下了新高 并且 价格是否位于最上方的通道之上。如果这三个条件都满足,函数返回一个85%透明度的酸橙绿。否则,第二个 if 条件会运行,它判断背景着色是否被启用、是否创下了新低 并且 价格是否低于最下方的通道。如果满足,则返回85%透明度的紫红色。最后,我们再次调用 bgcolor() 函数,传入 highsLowsBackground 变量,这会在之前的背景色之上再叠加一层颜色。
以编程方式为图表及其不同的图表区域着色
当我们将上述示例指标添加到EuroStoxx 50 CFD图表上时,它看起来是这样的:
应用到S&P 500指数差价合约图表上时,我们的示例指标显示如下:
该脚本创建的输入选项如下:
如果我们,例如,把“Price Data”输入改为close,设置移动平均线和标准差周期为35和20,并禁用“Colour Background?”选项;那么前一个S&P 500指数差价合约图表变为:
总结
图表的背景可以通过 bgcolor() 和 fill() 函数来着色。前者从上到下为K线的背景着色,而后者则填充两条曲线或两条水平线之间的背景区域。为此,fill() 函数需要两个绘图对象(由 plot() 返回)或两个水平线对象(由 hline() 返回)。bgcolor() 函数可以有条件地为背景着色,而 fill() 则无法做到这一点。
为价格区间内的K线背景着色
有时,我们很难用肉眼判断一根价格K线是否正好落在一个特定的价格区间内。幸运的是,我们不必为此费力地锻炼眼力。通过一小段代码,TradingView就可以为我们识别出来。让我们看看如何通过填充图表区域来高亮显示那些位于高低价区间内的K线。
用彩色背景高亮价格区间内的K线
当我们追踪市场时,有时希望观察一根K线是否在某个特定区间内。我们可以在图表上画线然后自己进行监控,或者从TradingView的数据窗口读取数值。但是对于有很多小数位的交易品种(例如货币对有5位小数),这种视觉检查既慢又烦人。
幸运的是,Pine Script可以为我们监控价格K线,但我们还需要一种方式来高亮显示这些K线。我们可以改变它们在区间内的颜色,或者直接为高低价区间的背景涂上一种独特的颜色。
要实现后者,我们需要做两件事。首先,我们通过绘图来显示区间的上限和下限,这可以通过 plot() 函数完成。然后,我们填充这些绘图之间的背景,这正是 fill() 函数的功能。让我们来看看具体如何操作。
概述:为区间内K线的背景着色的步骤
要让一个TradingView指标或策略为那些落在特定价格区间内的K线背景着色,我们可以遵循以下步骤:
- (可选) 通过输入选项配置价格区间的范围。
- 判断当前K线是否落在该区间内。
- 如果K线在区间内,则绘制该区间的上限和下限。
- 使用
fill()为这些绘图之间的背景着色。
让我们一起逐步了解这些步骤所需的代码。
步骤一:通过输入项设置价格区间(可选)
要判断一根K线是否在一个区间内,我们首先需要知道这个区间的范围。我们可以让脚本来计算这些边界,例如使用近期的最高价和最低价,也可以依赖于手动设定的值。
在本文中,我们使用手动值。最方便的方法是使用输入选项,这样我们就可以快速地调整脚本的参数而无需修改代码。
所以,在第一步中,我们创建一些用户可配置的设置:
// 通过输入项配置价格区间
rangeUp = input.float(8500, title="Price Range Upper Bound", minval=0)
rangeDown = input.float(7500, title="Price Range Lower Bound", minval=0)
fullBarInRange = input.bool(false, title="Full Bar In Range?")
我们在这里创建了两种类型的输入。前两个是浮点数输入,通过 input.float() 函数创建。第一个,“Price Range Upper Bound”(价格区间上界),定义了价格区间的上限,默认值为8,500。我们使用 rangeUp 变量来追踪其当前值。第二个,“Price Range Lower Bound”(价格区间下界),则设定了区间的下限。
第三个设置是一个布尔型(真/假)输入选项,通过 input.bool() 函数创建。这会生成一个我们可以勾选或取消的复选框。我们将这个选项命名为“Full Bar In Range?”(整根K线位于区间内?),并默认将其关闭(false)。我们使用 fullBarInRange 变量来在后续代码中使用这个输入。
最后一个选项背后的动机是:当我们比较一根K线与一个区间时,我们可能要求整根K线都完全位于该区间内,但也可能希望捕捉到那些部分触及该区间的K线。在下一步中,我们将使用这个输入来决定脚本应该使用哪种判断逻辑。
步骤二:判断当前K线是否落在区间内
现在,我们来判断一根K线与我们设定的价格区间的关系。我们使用上一步中的价格上下限,并编写两种不同的比较逻辑:
// 根据输入偏好,判断K线是否在区间内
insideRange = if fullBarInRange
high < rangeUp and low > rangeDown
else
high > rangeDown and low < rangeUp
我们在这里创建的 insideRange 变量通过一个 if/else 语句来获取其值。我们评估的条件是 fullBarInRange,即“Full Bar In Range?”输入选项的值。
当该输入被启用时,fullBarInRange 为 true,此时 if 代码块会执行。在那里,我们进行两个比较:判断K线的最高价是否低于区间的上界(rangeUp),并且判断K线的最低价是否高于区间的下界(rangeDown)。我们使用 and 运算符连接它们,要求两个条件必须同时满足。
当该输入被禁用时,fullBarInRange 为 false,else 代码块会执行。在那里,我们只判断K线的最高价是否高于区间的下限,同时最低价是否低于区间的上限。当K线确实部分位于区间内时,insideRange 变量变为 true(否则为 false)。
步骤三:绘制区间的上下限价格
接下来,我们绘制价格区间的上下限。这确实有点奇怪。我们不是想为背景着色,而不是在图表上绘图吗?
我们创建这些绘图正是为了着色背景。当我们要填充图表的部分背景时,TradingView需要知道它应该在哪个价格之间进行着色。我们传达这一信息的方式就是通过绘图值。
所以,一旦我们有了两个绘图,就可以告诉TradingView填充它们之间的背景。这就是为什么我们绘制区间的上下限:
// 绘制区间的上下限
ubPlot = plot(insideRange ? rangeUp : na,
style=plot.style_linebr, color=color.new(color.white, 100), title="Upper Bound")
lbPlot = plot(insideRange ? rangeDown : na,
style=plot.style_linebr, color=color.new(color.white, 100), title="Lower Bound")
第一个 plot() 调用在图表上显示区间的上限(rangeUp),第二个则显示下限(rangeDown)。我们将绘图对象分别存储在 ubPlot 和 lbPlot 变量中(我们在下一步中需要它们)。
需要注意的一点是,我们并非在每一根K线上都绘制这些值。相反,我们使用条件运算符(?:)来评估 insideRange 变量是否为 true。如果是,我们就绘制区间的边界;否则,我们使用 na 来禁用绘图。
结果就是:只有当当前K线落在价格区间内时,这些绘图才会被激活。当我们稍后为这些绘图之间的区域着色时,这个着色的背景就只会在绘图被激活时才出现。因此,当K线在价格区间之外时,填充的背景不会显示。
请注意,我们把两个带断点的线图都设为白色,并使用 color.new() 函数将其设为100%的透明度。这样我们就无法在图表上看到这些绘图。这正是我们的目的,因为我们只想为背景着色,而这些绘图仅仅是达到目的的手段。
注意
如果你确实希望在K线落在区间内时显示区间的上下边界线,而不是隐藏它们,那么可以将 color.new() 生成的透明度设为小于100的值。
步骤四:为这些绘图之间的图表背景着色
现在,当一根K线落在区间内时,我们在图表上已经有了绘图,还剩一件事要做:为这些绘图之间的背景着色。我们使用TradingView的 fill() 函数来完成这件事:
// 为价格区间内的K线填充背景
fill(plot1=ubPlot, plot2=lbPlot, color=color.new(#FF8C00, 75))
fill() 函数使用 plot1 和 plot2 参数来指定在哪些绘图之间进行着色。这里,我们把它们设为我们在上一步中创建的 ubPlot 和 lbPlot 变量。
我们为该背景区域赋予的颜色是 #FF8C00,即深橙色的十六进制颜色值。我们使用Pine Script的 color.new() 函数使这个颜色具有75%的透明度。
示例指标:为价格区间内的比特币K线背景着色
我们上面讨论的步骤被包含在下方的示例指标中。(虽然这是一个指标,但你可以在TradingView策略中使用完全相同的代码。)
该脚本会高亮显示落在$7,500-$8,500比特币价格区间内的K线的背景。通过一个输入项,我们可以配置K线是应该完全位于该区间内,还是只需部分触及即可。
该指标的完整代码是:
//@version=5
indicator(title="Colour background in price range", overlay=true)
// 步骤一:
// 通过输入项配置价格区间
rangeUp = input.float(8500, title="Price Range Upper Bound", minval=0)
rangeDown = input.float(7500, title="Price Range Lower Bound", minval=0)
fullBarInRange = input.bool(false, title="Full Bar In Range?")
// 步骤二:
// 根据输入偏好,判断K线是否在区间内
insideRange = if fullBarInRange
high < rangeUp and low > rangeDown
else
high > rangeDown and low < rangeUp
// 步骤三:
// 绘制区间的上下限
ubPlot = plot(insideRange ? rangeUp : na,
style=plot.style_linebr, color=color.new(color.white, 100), title="Upper Bound")
lbPlot = plot(insideRange ? rangeDown : na,
style=plot.style_linebr, color=color.new(color.white, 100), title="Lower Bound")
// 步骤四:
// 为价格区间内的K线填充背景
fill(plot1=ubPlot, plot2=lbPlot, color=color.new(#FF8C00, 75))
让我们看看脚本的行为。默认情况下,该指标会高亮显示仅仅触及该区间的K线。因此,在下面的比特币(BTC/USD)图表上,一旦一根K线的最高价或最低价进入了价格区间,它就会得到一个彩色的背景:
使用该指标的另一种方式是只考虑完全落在该区间内的K线。要实现这种行为,我们启用“Full Bar In Range?”输入选项。
使用相同价格区间的同一张图表看起来是这样的:
















