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

Pine Script(146):条件性颜色,条件运算符与if/else切换颜色

#Pine Script入门教学

用条件运算符切换颜色

在TradingView Pine语言中,我们可以通过多种编程方式来处理颜色,其中就包括条件性地应用颜色。那么,我们该如何使用条件运算符来实现这一点呢?

使用TradingView的条件运算符实现条件性颜色

我们可以在TradingView Pine中使用多种颜色,从基本的TradingView颜色到任意的十六进制颜色值。除了以编程方式使用这些颜色外,我们也可以手动更改脚本的颜色。

使用这些颜色的基本方法是直接应用它们,比如绘制一条在每根K线上颜色都相同的蓝色移动平均线。然而,我们也可以有条件地使用颜色。这样,我们就能通过编程来定义某些特定情况,当这些情况发生时,就触发使用一种特定的颜色。这使得我们可以,例如,用不同的颜色为图表背景着色,甚至以编程方式关闭颜色显示。

注意

并非所有TradingView函数都接受条件性颜色值。允许条件性颜色的函数包括 barcolor()bgcolor()plot()plotarrow()plotbar()plotcandle()plotchar()plotshape()允许条件性颜色的函数是 fill()hline()

将条件性颜色编码到脚本中有几种方法。一种是使用条件运算符(?:)。该运算符处理三个值:第一个是一个真/假条件。当该条件评估为 true 时,运算符返回其第二个值;当条件为 false 时,则返回其第三个值。

这个类似if/else行为的一个快速示例如下:

//@version=5
indicator(title="Conditional colours with ?:", overlay=true)

plot(close, color=close > ta.sma(close, 5) ? color.green : color.red)

这里,我们使用 plot() 在图表上显示收盘价。该函数的 color 参数被设为由条件运算符返回的值。该运算符在这里评估当前K线的收盘价(close)是否大于一个5周期的收盘价简单移动平均线(ta.sma(close, 5))。

当该条件为 true 时,运算符返回绿色(color.green),该颜色随即被用于绘制线条。如果条件为 false,运算符则返回红色(color.red),线条便以该颜色显示。

使用TradingView的条件运算符编写交替颜色

现在,让我们来看一个更完整的示例指标,它使用条件运算符来有条件地应用颜色。在下方的示例指标中,我们在图表上绘制了三条EMA(指数移动平均线)。每条线的颜色都根据市场趋势有条件地设置:当移动平均线呈多头排列(从上到下依次为快、中、慢线)时,它们变为绿色;当呈空头排列时,变为红色;当均线未对齐时,则为黄色。我们稍后也会看到该指标在图表上的样子,但首先来看代码本身:

//@version=5
indicator(title="Colouring conditionally with ?:", overlay=true)

// 输入选项
priceData = input.source(close, title="Price data")
fastMA    = input.int(10, title="Fast MA")
medMA     = input.int(23, title="Medium MA")
slowMA    = input.int(48, title="Slow MA")

// 计算数值
emaFast = ta.ema(priceData, fastMA)
emaMed  = ta.ema(priceData, medMA)
emaSlow = ta.ema(priceData, slowMA)

// 确定颜色
lineColour = emaFast > emaMed and emaMed > emaSlow ? color.green :
     emaFast < emaMed and emaMed < emaSlow ? color.red :
     color.yellow

// 绘制移动平均线
plot(emaFast, linewidth=2, color=lineColour)
plot(emaMed, linewidth=2, color=lineColour)
plot(emaSlow, linewidth=2, color=lineColour)

我们以 indicator() 函数开始,这是每个指标都必需的。我们设置该函数的 title 参数来为指标命名,并将 overlay 参数设为 true,使脚本能叠加显示在主图表的交易品种上。

然后,我们创建几个输入选项:

// 输入选项
priceData = input.source(close, title="Price data")
fastMA    = input.int(10, title="Fast MA")
medMA     = input.int(23, title="Medium MA")
slowMA    = input.int(48, title="Slow MA")

我们在这里使用专门的Pine Script函数创建了几个输入项。这些函数除了创建输入本身外,还会返回输入的当前值。我们使用赋值运算符(=)将每个返回值存储在一个变量中,这样我们稍后就可以通过该变量在脚本中使用输入的当前值。

第一个输入是所谓的源价格数据输入,我们通过 input.source() 函数创建。这个输入会生成一个下拉菜单,其中包含与图表价格数据相关的值,如最高价、最低价或收盘价。我们为这个输入命名为“Price Data”。我们将 input.source() 返回的值存储在 priceData 变量中,其默认值设为 close,因此最初持有的是交易品种的收盘价。

另外三个输入都是数值整数输入,通过 input.int() 函数创建。其中第一个名为“Fast MA”,默认值为10,其当前值存储在 fastMA 变量中。第二个和第三个整数输入分别名为“Medium MA”和“Slow MA”,它们的默认值分别为23和48,我们通过 medMAslowMA 变量来追踪它们的值。

接下来,我们计算移动平均线:

// 计算数值
emaFast = ta.ema(priceData, fastMA)
emaMed  = ta.ema(priceData, medMA)
emaSlow = ta.ema(priceData, slowMA)

EMA是通过 ta.ema() 函数计算的。该函数需要两个参数:一个要处理的值序列,以及一个指定计算K线数量的整数。我们将这三个 ta.ema() 函数调用的第一个参数都设为 priceData 输入变量。这样,每当我们更改该输入选项时,EMA的值也会随之改变。

第一条EMA的周期由 fastMA 输入变量设置,其默认值为10。我们将这个EMA的值赋给 emaFast 变量。另外两条EMA则默认通过 medMAslowMA 输入变量,分别在23和48根K线上计算。我们将这些移动平均线的值存储在 emaMedemaSlow 变量中。

然后,我们确定用什么颜色来绘制这些EMA:

// 确定颜色
lineColour = emaFast > emaMed and emaMed > emaSlow ? color.green :
     emaFast < emaMed and emaMed < emaSlow ? color.red :
     color.yellow

我们在这里使用两个嵌套的条件运算符(?:)来确定 lineColour 变量应该存储哪种颜色。为此,我们最多会评估两个条件,每个条件都由两个通过 and 逻辑运算符连接的表达式组成。只有当 and 运算符左右两边的表达式都为 true 时,它才会返回 true;只要其中一个或两个表达式为 falseand 就会返回 false

第一个条件运算符判断快周期EMA (emaFast)是否大于中周期均线(emaMed) 并且中周期EMA是否也高于慢周期均线(emaMed > emaSlow)。每当这三条均线呈多头排列时,这个条件就为 true。在这种情况下,条件运算符返回绿色(color.green),并将其赋给 lineColour 变量。

但如果该条件为 false,TradingView Pine会继续评估第二个条件运算符。它会检查快周期EMA是否小于中周期均线(emaFast < emaMed) 并且中周期均线是否也呈空头排列,位于最慢的均线之下(emaMed < emaSlow)。当这两个表达式都为 true 时,第二个条件运算符返回红色(color.red)。但如果这个条件也不成立,则意味着均线既未呈多头也未呈空头排列,此时条件运算符返回黄色(color.yellow)。

既然EMA线的颜色已经确定,我们就在图表上绘制它们:

// 绘制移动平均线
plot(emaFast, linewidth=2, color=lineColour)
plot(emaMed, linewidth=2, color=lineColour)
plot(emaSlow, linewidth=2, color=lineColour)

绘图是通过 plot() 函数完成的,该函数可以在图表上显示一个数据序列。我们通过该函数的第一个参数指定要绘制的值,这里我们分别设为 emaFastemaMedemaSlow 变量,它们持有周期为10、23和48的EMA值。

这三个 plot() 语句的其他参数是相同的。每个的 color 参数都设为我们刚才确定为绿色、红色或黄色的 lineColour 变量。linewidth 参数用于设置绘图线条的粗细,范围从1(默认大小)到4,这里我们设为2,使每条绘制的线都比默认的稍粗一些。

在TradingView中为移动平均线进行条件性着色

当我们将上述示例指标添加到德国DAX指数差价合约图表上时,它看起来是这样的:

该脚本的输入选项如下:

如果我们更改这些输入,例如,将“Price Data”改为基于HL2值(K线的中点),并将移动平均线的周期改为5、15和30,那么前一个图表将变为:

总结

TradingView的颜色可以被直接应用,即在每根K线上使用相同的颜色。但颜色也可以通过编程方式来设置。实现此功能的一种方法是使用条件(三元)运算符(?:)。该运算符需要三个值:一个真/假条件和根据该条件返回的两个值。如果条件评估为 true,则返回第二个值;当条件为 false 时,返回第三个值。通过充当一个简洁的if/else语句,条件运算符可以评估多个条件,并返回一个与该条件相匹配的颜色值。

用if/else语句设置条件性颜色

在TradingView中,我们可以有条件地为指标和交易策略应用颜色。但我们该如何使用 if/else 语句来从多种颜色中进行选择呢?

在TradingView中使用if/else语句实现条件性颜色

在TradingView Pine脚本的代码中,我们可以使用标准的TradingView颜色以及数以百万计的十六进制颜色值。在代码中使用了颜色之后,我们还可以手动更改脚本的颜色。我们甚至可以以编程方式关闭颜色显示。

颜色的标准用法是在每根K线上应用相同的颜色,例如绘制一条红色的振荡器线或黄色的移动平均线。然而,当我们有条件地使用颜色时,就可以直观地传递信息,比如当某个特定事件发生时高亮显示图表背景。

注意

并非所有TradingView函数都接受条件性设置的颜色:fill()hline() 函数无法使用条件性颜色,而 barcolor()bgcolor()plot()plotarrow()plotbar()plotcandle()plotchar()plotshape() 函数则允许使用条件性颜色。

条件性颜色可以通过多种方式进行编程,例如使用条件运算符设置颜色。另一种方法是使用 if/else语句

这种语句会评估一个布尔(真/假)表达式(即一个会返回值的语句)。当该表达式为 true 时,if/else 语句会执行其 if 部分下方的代码。如果该表达式为 false,则会处理 else 下方的代码。

因此,一个 if/else 语句的逻辑是:如果此条件为真,则执行以下语句;否则,执行另一组语句。

快速示例:在TradingView中使用if/else语句设置颜色

除了有条件地执行代码,TradingView的 if/else 语句也使得有条件地设置变量的值成为可能。例如,使用 if/else 语句为一个颜色变量赋值,其基本形式如下:

colourVariable = if condition
    some_colour
else
    another_colour

这里,我们根据括号中条件的真假,将 colourVariable 设为两种颜色值之一。

下面是一个使用 if/else 语句在两种颜色中选择一种进行绘制的快速示例:

//@version=5
indicator(title="conditional colours with if/else - example", overlay=true)

maColour = if volume > volume[1]
    color.blue
else
    color.yellow

plot(ta.sma(close, 20), color=maColour)

我们在这里使用一个 if/else 语句,将蓝色(color.blue)或黄色(color.yellow)这两种TradingView基础颜色之一存储在 maColour 变量中。

if 条件评估的是当前K线的成交量(volume)是否大于前一根K线的成交量(volume[1])。

如果是,我们就将蓝色(color.blue)存储在 maColour 变量中。否则,该变量被赋予黄色(color.yellow)。然后,我们使用 plot() 函数绘制一条20周期的移动平均线,并将其 color 参数设为我们刚刚创建的 maColour 变量。

在TradingView策略中使用if/else语句设置颜色

下方的示例策略是一个更详尽的、使用 if/else 语句设置颜色的例子。该脚本在K线收盘价高于20周期最高点时做多,在收盘价低于过去20根K线的最低点时建立空头头寸。一旦有持仓,策略会提交一个150个跳动点的追踪止损。其中一条绘制的线条会根据策略持仓是盈利、亏损还是无持仓的状态,有条件地被着色为绿色、红色或橙色。在讨论完代码之后,我们再来看看该脚本在图表上的显示效果:

//@version=5
strategy(title="Conditional colours with if/else", overlay=true)

// 输入选项
lookback    = input.int(20, title="Lookback Period", minval=5)
trailOffset = input.int(150, title="Trail offset (ticks)", step=10)

// 计算数值
highestHigh = ta.highest(high, lookback)[1]
lowestLow   = ta.lowest(low, lookback)[1]
avgLine     = (highestHigh + lowestLow) / 2

// 确定策略条件
longSignal = close > highestHigh and 
     close[1] < highestHigh[1]
shortSignal = ta.crossunder(close, lowestLow)

// 进入头寸并提交追踪止损
if longSignal
    strategy.entry("EL", strategy.long)
    strategy.exit("XL", from_entry="EL", trail_offset=trailOffset,
         trail_points=-10)

if shortSignal
    strategy.entry("ES", strategy.short)
    strategy.exit(id="XS", from_entry="ES", trail_offset=trailOffset,
         trail_points=-10)

// 确定中线的颜色
lineColour = if strategy.position_size != 0
    if strategy.openprofit < 0
        color.red
    else
        color.green
else
    color.orange

// 绘制数值
plot(highestHigh, color=#1E90FF, title="Highest high")
plot(lowestLow, color=#1E90FF, title="Lowest low")
plot(avgLine, color=lineColour, title="Mid line", linewidth=2)

我们首先使用 strategy() 函数设置策略的属性,这是每个策略都必须的。我们通过该函数的 title 参数为策略命名,并将 overlay 参数设为 true,使策略显示在主价格图表上,而不是单独的子图中。

然后,我们创建两个输入选项:

// 输入选项
lookback    = input.int(20, title="Lookback Period", minval=5)
trailOffset = input.int(150, title="Trail offset (ticks)", step=10)

我们在这里使用Pine Script的 input.int() 函数创建了两个整数输入项。该函数不仅向TradingView脚本添加了一个输入选项,还会返回该输入的当前值。

第一个输入名为“Lookback period”,其默认值为20。minval 参数将该数值输入的最小值设为5。我们将该输入的值赋给 lookback 变量,稍后在确定计算最高价和最低价的回看K线数量时会使用它。

第二个输入名为“Trail offset (ticks)”,默认值为150。我们将其值存储在 trailOffset 变量中,在提交策略的平仓订单时会用到它。step 参数定义了在设置窗口中通过点击增加/减少按钮时,该输入值的步进值,这里我们设为10。这样,每次点击或按动键盘的上下箭头键,该输入值就会以10为单位进行调整。

创建完输入项后,我们计算脚本所需的数值:

// 计算数值
highestHigh = ta.highest(high, lookback)[1]
lowestLow   = ta.lowest(low, lookback)[1]
avgLine     = (highestHigh + lowestLow) / 2

highestHigh 变量的值由 ta.highest() 函数返回。我们为该函数提供了两个参数:一个值的序列(用于寻找最高值)和一个设定回看K线数量的数字。第一个参数我们使用K线的最高价(high),第二个则设为 lookback 输入变量,其默认值为20。

因为 high 变量也包含了当前K线的最高价,我们在 ta.highest() 函数后面紧跟着加上了值为1的历史运算符 [1]。这样我们得到的是过去20根K线的最高价,而不包含当前K线的最高价。我们需要这样做,是因为如果最高价的计算包含了当前K线,那么我们就无法判断当前K线是否突破了最高价——因为它自己就是最高价的一部分。

我们以同样的方式为 lowestLow 变量设置值,让 ta.lowest() 函数在 low 数据上以 lookback 为周期进行计算。同样,通过在该函数后使用历史引用运算符,我们得到了不包含当前K线值的最低价。

我们创建的第三个变量是 avgLine,它被设为最高价和最低价的平均值((highestHigh + lowestLow) / 2)。这个中点值就是我们稍后将用条件性颜色来绘制的线条。

计算完数值后,我们来确定交易条件:

// 确定策略条件
longSignal = close > highestHigh and 
     close[1] < highestHigh[1]

shortSignal = ta.crossunder(close, lowestLow)

longSignal 这个布尔变量的值由两个表达式决定。由于它们通过 and 逻辑运算符连接,因此两个表达式必须同时为 true,整个条件才为 true。第一个表达式检查当前K线的收盘价(close)是否大于过去20根K线的最高价(highestHigh)。第二个则评估前一根K线的收盘价(close[1])是否小于那一根K线当时的最高价(highestHigh[1])。当这两个表达式都为 true 时,就意味着当前K线的收盘价突破了过去20根K线的最高价。

shortSignal 变量的布尔值则由 ta.crossunder() 函数设定。当该函数的第一个参数在当前K线上小于第二个参数,而在前一根K线上大于第二个参数时,它会返回 true。由于我们传入了 closelowestLow 变量,这意味着 ta.crossunder() 只有在当前K线的收盘价跌破前20根K线的最低价时才会返回 true

除了 ta.crossunder(),还有一个 ta.crossover() 函数。它们都是检查某个值是否下穿/上穿另一个值的便捷方式,因为它们不像我们确定 longSignal 时那样,需要自己组合 and 逻辑运算符和多个比较运算符。

定义好多头和空头条件后,我们来建立头寸:

// 进入头寸并提交追踪止损
if longSignal
    strategy.entry("EL", strategy.long)
    strategy.exit("XL", from_entry="EL", trail_offset=trailOffset,
         trail_points=-10)

第一个 if 语句检查 longSignal 变量是否为 true,这是我们之前定义的使用收盘价和最高价的买入信号。如果是,Pine Script会做两件事。

首先,我们使用 strategy.entry() 函数建立一个多头交易。该函数提交买卖订单来建立一个头寸,并且,如果已经有一个反向的持仓,它会先将反向仓位平掉再开新仓。我们将这个订单命名为"EL"(Enter Long的缩写),并通过 strategy.long 将其指定为多头入场交易。

其次,我们调用 strategy.exit() 函数。该函数通过止损和/或限价订单来平掉已有的策略仓位。这里,我们将平仓订单命名为"XL"(eXit Long的缩写)。通过 from_entry 参数,我们告诉函数要为哪个入场订单设置平仓。这里要平仓的订单是"EL"

我们这里生成的平仓订单是一个追踪止损。我们通过 trail_offsettrail_points 参数来配置这个订单。前者以跳动点(ticks) 为单位指定追踪止损的距离,我们将其设为 trailOffset 输入变量,默认值为150。后者 trail_points 则以跳动点为单位指定追踪止损的激活水平。通过将该参数设为-10,追踪止损单会在头寸建立后立即提交并激活。

我们还提交一个空头入场及相应的止损订单:

if shortSignal
    strategy.entry("ES", strategy.short)
    strategy.exit(id="XS", from_entry="ES", trail_offset=trailOffset,
         trail_points=-10)

这个 if 语句与处理多头订单的那个非常相似。我们首先测试 shortSignal 变量是否为 true,当收盘价下穿20周期最低价时,该条件成立。

在这种情况下,我们首先使用 strategy.entry() 函数建立一个空头头寸。我们将这个订单命名为"ES"(Enter Short),并告知Pine Script执行做空操作(strategy.short)。

同时,我们使用 strategy.exit() 函数生成一个追踪止损平仓单。这个空头平仓订单被命名为"XS",它只针对由"ES"订单建立的仓位。我们通过 trail_offsettrail_points 参数来配置追踪止损的参数。

在编写完订单逻辑后,我们将在图表上绘制最高价、最低价以及它们的中点值。在此之前,我们先用两个嵌套的 if/else 语句来确定中线的颜色:

// 确定中线的颜色
lineColour = if strategy.position_size != 0
    if strategy.openprofit < 0
        color.red
    else
        color.green
else
    color.orange

我们在这里创建的 lineColour 变量,通过最多两个 if/else 语句,被赋予三种TradingView基础颜色(color.redcolor.greencolor.orange)之一。

第一个 if/else 语句评估 strategy.position_size 变量是否不等于(!=) 0。当策略无持仓时,该变量返回0;当持有多头时,返回一个表示仓位规模的正数;当持有空头时,则返回一个负数。因此,只要 strategy.position_size 的值不为0,就表示策略当前持有仓位。

在这种情况下,第二个 if/else 语句会执行。它的条件检查当前持仓的未实现盈亏(由 strategy.openprofit 返回)是否小于0。如果持仓确实处于亏损状态,color.red 就会被返回作为 lineColour 变量的值。如果持仓处于盈亏平衡或盈利状态(即该 if/else 语句的 else 部分),则返回 color.green

策略也可能处于空仓状态(即没有持仓)。在这种情况下,第一个 if/else 语句的 else 代码块会执行。这里我们返回橙色(color.orange),Pine Script随后会将其存储在 lineColour 变量中。

在确定了中线的颜色之后,我们就可以绘制所有三条线,以便直观地验证策略的交易行为:

// 绘制数值
plot(highestHigh, color=#1E90FF, title="Highest high")
plot(lowestLow, color=#1E90FF, title="Lowest low")
plot(avgLine, color=lineColour, title="Mid line", linewidth=2)

我们使用 plot() 函数来绘制这些值,该函数会显示其第一个参数所指定的任何数据。第一个 plot() 语句将其参数设为 highestHigh,即包含20周期最高价的变量。该线条的颜色(plot() 默认绘制线条)被设为道奇蓝的十六进制值(#1E90FF)。“Highest high”字符串是 title 参数的值,这个名称将显示在图表的数据窗口中,以及在手动配置脚本颜色时。

第二个绘图在图表上显示 lowestLow 变量。这些20周期的最低价也被着色为道奇蓝,该绘图被命名为“Lowest low”。

最后一个 plot() 函数调用则负责显示最高价与最低价之间的中线(其值我们已存储在 avgLine 变量中)。这个绘图被命名为“Mid line”,并且通过将 linewidth 参数设为2,使其比默认值稍粗一些。这条线的颜色被设为 lineColour 变量,也就是我们刚才用 if/else 语句为其赋予的三种可能颜色之一。

使用if/else语句有条件地应用TradingView颜色

当我们将上述示例策略添加到S&P 500指数差价合约的图表上时,它看起来是这样的:

在这张图表的左侧部分,策略建立了一个空头头寸,该头寸起初处于亏损状态(中线被着色为红色),但在几根K线后转为盈利。当这个头寸在6:00左右被平仓后,中线再次变为橙色。

我们示例策略的输入选项如下:

当我们把Lookback Period设置改为10,并将追踪止损偏移量改为100(即10个S&P 500指数点),前一个图表将变为:

Trail Offset (Ticks) 这个输入选项的实际效果取决于交易品种的价格刻度:对于S&P 500指数差价合约,该输入的默认值150等于15个指数点。但当该策略被添加到EuroStoxx 50差价合约上时,由于其一个跳动点就是一个指数点,追踪止损会因为设置得离价格太远而无法被触发。取而代之的是,该策略只是不断地反转仓位,始终处于持仓状态:

当我们把追踪止损的输入选项改为例如20个跳动点后,止损就可以被触发,前一个图表就变成了:

总结

TradingView的颜色可以在每根K线上都以相同的颜色应用,但也可以有条件地设置颜色。实现此功能的一种方法是使用 if/else语句,它首先评估一个布尔条件,然后在条件为 true 时执行 if 下方的语句,或在条件为 false 时执行 else 下方的语句。TradingView的 if/else 语句使得有条件地执行代码或返回一个条件性值(如颜色)成为可能,我们可以随后将其存储在一个变量中。我们也可以使用多个 if/else 语句,但这需要我们将一个 if/else 语句嵌套在另一个里面。

如何关闭颜色显示

在TradingView中,除了可以使用各种颜色值,我们还可以关闭颜色。这在TradingView Pine中是如何实现的呢?

以编程方式禁用TradingView脚本的颜色

在TradingView Pine脚本中,我们可以使用多种颜色,从基本的TradingView颜色到任意的十六进制颜色值。在Pine中使用过颜色后,我们还可以手动更改脚本的颜色。但我们该如何通过编程方式来关闭颜色显示呢?

我们通过多个TradingView函数(例如用于绘图的plot()和用于K线着色的barcolor())的color参数来指定颜色。然而,我们也可以将这个color参数设为na。这个值的作用是应用与图表已有颜色相同的颜色,这种透明色使得着色效果看起来像是被关闭了。

na这个内置变量代表了不是一个数字(Not a Number, NaN)的值。这类NaN值也用于像C# 这样的编程语言中,它们通常是不寻常的数学运算(如零除以零、无穷大减去无穷大)的结果。NaN值有时也用于代表一个特殊值,在TradingView中也是如此,na 就代表一种不可见的颜色。

有条件地应用完全透明的颜色

使用 na 变量来应用透明色与有条件地应用颜色密切相关。因为如果我们让某个着色函数在每一根K线上都使用透明色,那么几乎没有理由使用它——毕竟,在这种情况下,我们还不如不把这个函数写进脚本里。

我们有两种主要方式可以有条件地设置TradingView颜色:

  • 使用条件三元运算符(?:) 来有条件地设置颜色。
  • 使用 if/else语句来有条件地设置颜色。

在下面的编程示例中,我们将使用条件三元运算符(?:)来应用透明色。

注意

大多数,但并非所有,处理颜色的TradingView函数都接受条件性设置的颜色(包括用于实现透明的na)。可以用 na 来有条件地关闭其颜色显示的函数包括 barcolor()bgcolor()plot()plotarrow()plotbar()plotcandle()plotchar()plotshape()接受条件性颜色的函数是 fill()hline()

创建一个带有可选透明色的MACD指标

在下方的示例指标中,我们创建了一个MACD(平滑异同移动平均线)指标,它会绘制两条移动平均线之间的差值,以及一条用于产生买卖信号的信号线。

我们编写此脚本,使其可以通过 na 变量来有条件地关闭直方图和K线颜色的显示。在讨论完代码之后,我们将看看脚本的输入选项和指标本身。但首先,是代码:

//@version=5
indicator(title="Using na to turn off colours", overlay=false)

// 输入选项
fastLen     = input.int(12, title="Fast Length")
slowLen     = input.int(26, title="Slow Length")
smoothLen   = input.int(9, title="Smoothing Length")
showHist    = input.bool(true, title="Show Histogram?")
showSignals = input.bool(false, title="Show Signals?")

// 获取MACD值
[macdLine, signalLine, histValues] = ta.macd(close, fastLen, slowLen, smoothLen)

// 绘制线条
plot(macdLine, color=color.blue)
plot(signalLine, color=color.orange)
hline(0, linestyle=hline.style_dotted)

plot(histValues, color=showHist ? #00C78C : na,
     style=plot.style_histogram, linewidth=3)

// 为信号K线上色
macdCrossOver  = ta.crossover(macdLine, signalLine)
macdCrossUnder = ta.crossunder(macdLine, signalLine)

barColour = if showSignals and macdCrossOver
    #00FF7F
else if showSignals and macdCrossUnder
    color.yellow
else
    na

barcolor(barColour)

脚本以 indicator() 函数开始,这是每个指标都必需的。我们设置了该函数的两个参数:title(指定脚本名称)和 overlay。当 overlay 参数被设为 false 时,指标会显示在一个单独的子图中,而不是叠加在主图表的交易品种上。

然后,我们添加脚本的输入选项:

// 输入选项
fastLen     = input.int(12, title="Fast Length")
slowLen     = input.int(26, title="Slow Length")
smoothLen   = input.int(9, title="Smoothing Length")
showHist    = input.bool(true, title="Show Histogram?")
showSignals = input.bool(false, title="Show Signals?")

我们使用多种专门的Pine Script函数来创建输入项。这些函数不仅在脚本的设置窗口中创建一个手动选项,还会返回该输入的当前值。这里我们使用赋值运算符(=)将这些值存储在变量中,这样我们稍后就可以通过引用该变量来使用输入的值。

前三个输入选项用于计算MACD,它们都是数值整数输入,我们通过 input.int() 函数创建。我们将第一个的 title 参数设为“Fast Length”,这个名称会显示在输入选项的前面。该输入的默认值为12,其当前值存储在 fastLen 变量中。

下一个输入名为“Slow Length”,初始值为26,我们使用 slowLen 变量来追踪它的值。第三个也是最后一个整数输入名为“Smoothing Length”,默认值为9,其值存储在 smoothLen 变量中。

另外两个输入是布尔型(真/假)输入。它们会在脚本的设置中添加一个复选框,我们通过 input.bool() 函数来创建它们。其中第一个的标题设为“Show Histogram?”(显示直方图?),并且默认是启用的(true)。这个输入的当前值存储在 showHist 变量中,该变量稍后将用于关闭MACD直方图的颜色显示。

另一个复选框输入名为“Show Signals?”(显示信号?),默认值为 false,其当前值存储在 showSignals 变量中。该变量稍后将用于为价格K线着色或关闭这些颜色。

然后,我们计算MACD本身:

// 获取MACD值
[macdLine, signalLine, histValues] = ta.macd(close, fastLen, slowLen, smoothLen)

我们使用 ta.macd() 函数来计算MACD,它需要四个参数:一个用于计算的序列值,以及快线周期、慢线周期和信号线周期的值。这里我们分别将它们设为 close(基于收盘价计算)以及 fastLenslowLensmoothLen 这几个输入变量,其默认值分别为12、26和9。

大多数TradingView函数通常只返回一个值,但ta.macd()函数会返回一个包含三个值的数组:MACD线、信号线和直方图的值。我们在这里将这三个序列分别存储在macdLinesignalLinehistValues变量中,以供脚本后续使用。由于ta.macd()返回的是一个数组,这些变量在赋值时需要放在方括号[]内,并用逗号分隔。

接下来,我们在图表上绘制MACD的值:

// 绘制线条
plot(macdLine, color=color.blue)
plot(signalLine, color=color.orange)
hline(0, linestyle=hline.style_dotted)

plot(histValues, color=showHist ? #00C78C : na,
     style=plot.style_histogram, linewidth=3)

我们首先使用plot()来显示MACD线和其信号线。默认情况下,该函数会将其第一个参数的数据绘制成一条线。在第一个plot()语句中,我们将该参数设为macdLine变量,并将color参数设为蓝色(color.blue),从而将MACD值绘制成一条蓝色的线。

在下一个plot()函数调用中,我们将MACD的信号线(signalLine)值显示为一条橙色(color.orange)的线。

然后,我们使用hline()函数,它可以在一个固定的价格水平上绘制一条水平线,我们在0值处创建一条线。这样做纯粹是为了视觉效果,因为这让MACD直方图柱看起来像是立在零轴上,更美观。

这些直方图柱是由最后一个plot()语句创建的,它的第一个参数被设为histValues变量,该变量持有MACD直方图的值。通过将style参数设为plot.style_histogram,我们创建了一个直方图。通过将linewidth参数设为3,这些直方图的柱子会非常粗。

这最后一个plot()函数调用的color参数被设为一个由条件运算符(?:)返回的值。该运算符处理三个值:第一个是一个真/假条件。当条件为true时,运算符返回其第二个值;否则,当条件为false时,返回其第三个也是最后一个值。

这里被评估的条件是showHist这个布尔型输入变量,当“Show Histogram?”选项被启用时,其值为true,关闭时则为false。当该输入被启用时,条件运算符返回#00C78C(青蓝色的十六进制颜色值)。当该复选框被禁用时,条件运算符则返回na值。通过这种方式,我们就在“Show Histogram?”输入选项被禁用时,有条件地关闭了直方图的显示。

现在我们已经绘制了MACD值,接着来看看是否需要根据任何买卖信号为价格K线上色:

// 为信号K线上色
macdCrossOver  = ta.crossover(macdLine, signalLine)
macdCrossUnder = ta.crossunder(macdLine, signalLine)

barColour = if showSignals and macdCrossOver
    #00FF7F
else if showSignals and macdCrossUnder
    color.yellow
else
    na

barcolor(barColour)

首先,我们定义我们的信号。我们使用 ta.crossover() 函数来判断MACD线是否上穿了其信号线。为此,我们将macdLinesignalLine变量传递给该函数。我们从ta.crossover()得到的布尔(真/假)结果存入macdCrossOver变量中供后续使用。

接下来,我们判断MACD线是否下穿了其信号线。我们通过 ta.crossunder() 函数来判断,它同样作用于macdLinesignalLine变量。我们从中得到的布尔结果存入macdCrossUnder变量。

然后,我们来确定要使用哪种K线颜色。为此,我们使用了一个级联 if 语句。第一个 if 条件会测试两件事:showSignalsmacdCrossOver 变量。前者在用户启用了“Show Signals?”输入时为 true,否则为 false。后者则在MACD线上穿其信号线时为 true(否则为 false)。我们使用 and 运算符要求这两个条件必须同时为 true。当满足条件时,我们返回春绿色 #00FF7F 作为 barColour 变量的值(我们稍后会用到它)。

如果第一个 if 条件的测试结果为 false,Pine Script会继续评估第二个条件。这一个会判断 showSignalsmacdCrossUnder 变量是否同时为 true。如果是,我们就返回黄色(color.yellow)作为 barColour 变量的颜色。

当第二个条件也为 false 时,我们选择将 na 值存储在 barColour 变量中。na 值的作用是关闭K线着色。所以我们的逻辑是,如果没有MACD信号发生,Pine Script就不应该为价格K线着色。

实际的K线着色,我们接下来通过 barcolor() 函数来完成。我们将 barColour 变量传递给该函数,这样它就知道该使用哪种颜色了(如果适用的话)。最终的结果是,当前K线会变成春绿色、黄色,或者不改变颜色。

以编程方式关闭TradingView脚本的颜色显示

当我们将我们的示例指标添加到富时100指数(FTSE 100)的差价合约图表上时,它看起来是这样的:

该脚本的输入选项如下:

当我们禁用“Show Histogram?”选项时,我们可以看到 na 是如何关闭我们的直方图的:

即使直方图柱不再可见,最后一根K线的值(-12.7046)仍然显示在指标的价格坐标轴上。这表明 na 只是让绘图变得不可见,但并没有真正将其从图表中移除。

当我们启用“Show Signals?”输入选项时,之前被 na 关闭的彩色K线就会显示出来:

当然,当我们再次启用“Show Histogram?”时,直方图柱会重新出现:

总结

在TradingView脚本中,颜色可以在每根K线上被应用,也可以在特定条件发生时被有条件地关闭。为此,我们使用条件三元运算符(?:)if/else语句来评估一个布尔(真/假)条件。然后,根据该条件,我们可以返回一个TradingView颜色或十六进制颜色值,或者返回 nana 这个内置变量代表一个非数字的值,在编程着色的语境下,它能产生一种完全透明的效果,使得颜色看起来像是被关闭了。

赞(0)
未经允许不得转载:图道交易 » Pine Script(146):条件性颜色,条件运算符与if/else切换颜色
分享到

评论 抢沙发

登录

找回密码

注册