如何获取自某个条件发生以来的最低值?
当TradingView脚本分析图表上的K线时,它会遇到各种各样的情况,例如移动平均线交叉或创出新的周度高点。如果我们想知道从某个特定情况发生以来的最低值是多少,我们该如何实现呢?
首先,我们需要将这个特定情况转换成一个布尔(true/false)条件。当该情况发生时,条件为 true,未发生时则为 false。然后,我们就可以利用这个条件来寻找自其发生以来的最低值。接下来就让我们一探究竟。
“自……以来的最低值”函数
下面的这个自定义函数,能够返回自某个特定条件上一次为 true 以来的最低值:
// GetLowestSince() 函数返回给定序列自指定条件
// 最近一次出现以来的最低值。
// 如果该条件从未发生,或者在条件发生时
// 序列值为'na',则函数返回'na'。
GetLowestSince(condition, series=low) =>
var float lowestValueSince = na
if condition or series < lowestValueSince
lowestValueSince := series
lowestValueSince
这个 GetLowestSince() 函数有两个参数。condition 是一个布尔类型的条件,代表了我们需要寻找的那个特定情况。series 参数则指定了我们要从哪个数据序列中寻找最低值,如果我们不设置这个参数,它会默认使用K线的最低价 (low)。
在函数内部,我们做了三件事。首先,我们使用 var 关键字声明了一个名为 lowestValueSince 的持久性变量。我们用它来持续跟踪自 condition 上一次为 true 以来的最低值。它初始时为一个空的 na 值。(当 condition 第一次为 true 时,这个 na 值会被当时的 series 值所替代。)
然后,一个 if 语句会检查两个情况:要么 condition 参数本身为 true,要么当前的 series 值小于 (<) 我们已经记录的最低值 (lowestValueSince)。
当这两个情况中的任意一个(或两个都)发生时,if语句内的代码就会执行,将 lowestValueSince 变量的值更新为当前的 series 值。因此,每当重置条件发生或出现新的更低值时,我们都会用新的信息来更新这个变量。
函数的第三部分,也是最后一行,仅仅是 lowestValueSince 这个变量本身。因为我们将它放在了函数的最后,所以它的值就是该函数的返回值。
GetLowestSince() 函数被设计为在每一根K线上都去寻找新的最低值。因此,我们必须在每一根K线上都调用它。如果我们在某根K线上没有调用它,函数就会错过那根K线的数据。如果那根K线恰好创下了新低,这就会导致不正确的结果(因为函数对此一无所知)。
函数应用示例
在我们将上述函数复制粘贴到我们的脚本后,便可以通过多种方式来使用它。
例如,我们可以获取自本月开始以来的最低低点。要获取这个值,我们可以使用 month != month[1] 这个条件来调用函数:
// 跟踪自本月开始以来的最低低点
monthLow = GetLowestSince(month != month[1])
该函数可以从任何变量序列中获取最低值。假设我们想知道自价格穿越一条指数移动平均线以来的最低成交量,我们可以像这样使用 GetLowestSince():
// 获取自价格穿越移动平均线以来的最低成交量
maCross = ta.cross(close, ta.ema(close, 40))
volumeLowSinceCross = GetLowestSince(maCross, volume)
我们也可以从其他函数返回的数据中获取最低值。比如,我们想知道自当天开始以来的最低20周期简单移动平均线值,可以这样使用 GetLowestSince():
// 跟踪自当天开始以来的最低SMA值
dayMaLow = GetLowestSince(dayofmonth != dayofmonth[1], ta.sma(close, 20))
完整示例脚本
让我们在一个完整的脚本中应用 GetLowestSince()。下方的指标使用该函数来跟踪自本年度开始以来的最低低点、最低收盘价和最低简单移动平均线。我们在图表上绘制这些值,以观察它们自年初以来的变化。
该指标的完整代码如下:
//@version=5
indicator(title="Get lowest value since condition", overlay=true)
// GetLowestSince() 函数返回给定序列自指定条件
// 最近一次出现以来的最低值。
// 如果该条件从未发生,或者在条件发生时
// 序列值为'na',则函数返回'na'。
GetLowestSince(condition, series=low) =>
var float lowestValueSince = na
if condition or series < lowestValueSince
lowestValueSince := series
lowestValueSince
// 计算并绘制简单移动平均线
smaValue = ta.sma(close, 40)
plot(smaValue, title="SMA", color=color.fuchsia)
// 定义条件并通过背景色进行可视化验证
newYearStart = year > year[1]
bgcolor(newYearStart ? color.new(color.orange, 75) : na)
// 显示自条件发生以来的最低低点、最低收盘价和最低SMA
plot(GetLowestSince(newYearStart), color=color.red,
title="Lowest low since condition", linewidth=2)
plot(GetLowestSince(newYearStart, close), color=color.teal,
title="Lowest close since condition", linewidth=2)
plot(GetLowestSince(newYearStart, smaValue), color=color.orange,
title="Lowest SMA since condition", linewidth=2)
我们首先使用 indicator() 函数来配置指标,这行代码为脚本命名,并将其叠加显示在主图的交易品种上。
接着,我们包含了上文讨论过的 GetLowestSince() 自定义函数。
然后,ta.sma() 函数计算了一条40周期的简单移动平均线 (SMA)。plot() 函数将这条均线以紫红色 (color.fuchsia) 的常规线图形式显示在图表上。
之后,我们定义了需要寻找的那个特定情况。我们编写了一个条件,判断当前K线的年份 (year) 是否大于 (>) 其前一根K线的年份。这个条件只在新的一年开始时才为 true,在所有其他K线上均为 false。我们将这个布尔条件储存在 newYearStart 变量中,以备后用。
接下来,bgcolor() 函数为图表背景上色。但并非在每根K线上都上色,而是通过条件运算符 (?:) 来判断 newYearStart 的值。当新的一年开始时,该变量为 true,运算符会返回一个带有75%透明度的橘色 (color.orange),bgcolor() 便用这个颜色来高亮图表背景。在所有其他K线上,运算符返回 na,这会禁用背景色。
最后,我们在图表上绘制出各种最低值:
// 显示自条件发生以来的最低低点、最低收盘价和最低SMA
plot(GetLowestSince(newYearStart), color=color.red,
title="Lowest low since condition", linewidth=2)
plot(GetLowestSince(newYearStart, close), color=color.teal,
title="Lowest close since condition", linewidth=2)
plot(GetLowestSince(newYearStart, smaValue), color=color.orange,
title="Lowest SMA since condition", linewidth=2)
这段代码通过 plot() 函数绘制了三条线图。
- 第一条显示自年初以来的最低低点。我们通过调用
GetLowestSince()并传入newYearStart作为条件来获取该值。由于函数默认使用最低价,我们无需额外指定。 - 第二条显示本年度的最低收盘价。为此,我们调用
GetLowestSince(),传入newYearStart作为条件,并使用close变量来告诉函数分析收盘价。 - 第三条,也是最后一条,显示最低的SMA值。我们再次执行
GetLowestSince(),并传入newYearStart和smaValue变量作为参数。
在图表上,只要新的一年开始,脚本就会开始跟踪这些最低值。下图是一个反转后的图表,处于下降趋势中,因此最低低点、最低收盘价和最低移动平均线都在频繁更新:
内容总结
- 要获取自某个特定情况发生以来的最低值,我们首先需要将该情况转换成一个布尔(
true/false)条件。 - 然后,我们使用一个变量来跟踪最低值。每当条件发生时,我们就为该变量赋予一个初始值(重置)。
- 之后,在每一根K线上,我们都去判断是否出现了新的更低值,并相应地更新我们的跟踪变量。
如何获取自某个条件发生以来的最高值?
当TradingView脚本处理图表上的K线时,它会遇到各种各样的情况,例如移动平均线交叉、开盘跳空或MACD信号。但如果我们想知道从某个特定情况发生以来的最高值是多少,该如何实现呢?
要获取这个值,我们首先需要将这个特定情况转换成一个布尔(true/false)条件。当该情况发生时,条件为 true,未发生时则为 false。然后,我们就可以利用这个条件来寻找自其发生以来的最高值。接下来就让我们一探究竟。
“自……以来的最高值”函数
下面的这个自定义函数,能够返回自某个特定条件上一次为 true 以来的最高值:
// GetHighestSince() 函数返回给定序列自指定条件
// 最近一次出现以来的最高值。
// 如果该条件从未发生,或者在条件发生时
// 序列值为'na',则函数返回'na'。
GetHighestSince(condition, series=high) =>
var float highestValueSince = na
if condition or series > highestValueSince
highestValueSince := series
highestValueSince
这个 GetHighestSince() 函数有两个参数:
condition:一个布尔类型的条件,代表了我们需要寻找的那个特定情况。series:指定了我们要从哪个数据序列中寻找最高值。如果我们不提供这个参数,它会默认使用K线的最高价 (high)。
在函数内部,我们做了三件事。首先,我们使用 var 关键字声明了一个名为 highestValueSince 的持久性变量。我们用它来持续跟踪自 condition 上一次为 true 以来的最高值。它初始时为一个空的 na 值。(当 condition 第一次为 true 时,这个 na 值会被当时的 series 值所替代。)
然后,一个 if 语句会检查两个情况:要么 condition 参数本身为 true(重置条件),要么当前的 series 值大于 (>) 我们已经记录的最高值 highestValueSince(更新条件)。
当这两个情况中的任意一个(或两个都)发生时,if语句内的代码就会执行,将 highestValueSince 变量的值更新为当前的 series 值。这样,每当重置条件发生或出现新的更高值时,我们都会更新这个跟踪变量。
函数的最后一行,仅仅是 highestValueSince 这个变量本身。这将该变量的当前值作为函数的计算结果返回。
重要提示:
GetHighestSince()函数被设计为在每一根K线上都去寻找新的最高值。因此,我们必须在每一根K线上都调用它。如果我们在某根K线上漏掉了调用,函数就会错过那根K线的数据,从而可能导致不准确的结果(例如,如果那根K线恰好创下了新高,而函数对此一无所知)。
函数应用示例
在我们将上述函数复制粘贴到我们的脚本后,便可以通过多种方式来使用它。
例如,我们可以获取自本月开始以来的最高高点。要获取这个值,我们可以使用 month != month[1] 这个条件来调用函数:
// 跟踪自本月开始以来的最高高点
monthHigh = GetHighestSince(month != month[1])
从任何变量或函数返回的序列中获取最高值也是可行的。假设我们想知道自价格穿越一条指数移动平均线以来的最高单日成交量,可以像这样使用 GetHighestSince():
// 获取自价格穿越移动平均线以来的最高成交量
maCross = ta.cross(close, ta.ema(close, 20))
volumeHighSinceCross = GetHighestSince(maCross, volume)
另一个选项是从其他函数的结果中获取最高值。比如,我们想知道自当天开始以来的最高20周期简单移动平均线值:
// 跟踪自当天开始以来的最高SMA值
dayMaHigh = GetHighestSince(dayofmonth != dayofmonth[1], ta.sma(close, 20))
完整示例脚本
让我们在一个完整的脚本中应用 GetHighestSince() 函数。下方的指标用于跟踪自本年度开始以来的最高高点、最高收盘价和最高简单移动平均线。我们在图表上绘制这些值,以观察它们自年初以来的演变。
该指标的完整代码如下:
//@version=5
indicator(title="Get highest value since condition", overlay=true)
// GetHighestSince() 函数返回给定序列自指定条件
// 最近一次出现以来的最高值。
// 如果该条件从未发生,或者在条件发生时
// 序列值为'na',则函数返回'na'。
GetHighestSince(condition, series=high) =>
var float highestValueSince = na
if condition or series > highestValueSince
highestValueSince := series
highestValueSince
// 计算并绘制简单移动平均线
smaValue = ta.sma(close, 40)
plot(smaValue, title="SMA", color=color.fuchsia)
// 定义条件并通过背景色进行可视化验证
newYearStart = year > year[1]
bgcolor(newYearStart ? color.new(color.orange, 75) : na)
// 显示自条件发生以来的最高高点、最高收盘价和最高SMA
plot(GetHighestSince(newYearStart), color=color.green,
title="Highest high since condition", linewidth=2)
plot(GetHighestSince(newYearStart, close), color=color.teal,
title="Highest close since condition", linewidth=2)
plot(GetHighestSince(newYearStart, smaValue), color=color.orange,
title="Highest SMA since condition", linewidth=2)
代码解析
我们首先调用 indicator() 函数来配置指标,这行代码为脚本命名,并将其叠加显示在主图的交易品种上。
接着,我们包含了上文讨论过的 GetHighestSince() 自定义函数。
然后,ta.sma() 函数计算了一条40周期的简单移动平均线 (SMA)。plot() 函数将这条均线以紫红色 (color.fuchsia) 的常规线图形式显示在图表上。
之后,我们定义了需要寻找的那个特定情况。我们编写了一个条件,判断当前K线的年份 (year) 是否大于 (>) 其前一根K线的年份。这个条件只在新的一年开始时才为 true,在所有其他K线上均为 false。我们将这个布尔条件储存在 newYearStart 变量中。
bgcolor() 函数接着为新年开始的时刻标记背景色。为了实现这一点,条件运算符 (?:) 会判断 newYearStart 变量的值。当其为 true 时,运算符会返回一个带有75%透明度的橘色 (color.orange),bgcolor() 便用这个颜色来填充图表背景。如果不是新年的第一根K线,条件运算符返回 na,这会禁用背景色。
最后,我们显示自年初以来的各种最高值:
// 显示自条件发生以来的最高高点、最高收盘价和最高SMA
plot(GetHighestSince(newYearStart), color=color.green,
title="Highest high since condition", linewidth=2)
plot(GetHighestSince(newYearStart, close), color=color.teal,
title="Highest close since condition", linewidth=2)
plot(GetHighestSince(newYearStart, smaValue), color=color.orange,
title="Highest SMA since condition", linewidth=2)
这段代码通过 plot() 函数绘制了三条线图,它们都显示为常规的线条。
- 第一条显示自年初以来的最高高点。我们调用
GetHighestSince()并传入newYearStart作为条件来获取该值。由于函数默认分析的是最高价,我们无需额外指定。 - 第二条显示本年度的最高收盘价。为此,我们调用
GetHighestSince(),传入newYearStart作为条件,并使用close变量来告诉函数分析收盘价序列。 - 第三条显示最高的SMA值。我们再次执行
GetHighestSince(),这次传入newYearStart和smaValue变量作为参数。
当我们在图表上运行该脚本时,只要新的一年开始,它就会开始跟踪这些最高值。下图是一个上升趋势的图表,因此最高高点、最高收盘价和最高移动平均线都在频繁地向上更新:
内容总结
要获取自某个特定情况发生以来的最高值,我们通常遵循以下步骤:
- 定义条件:首先,将您关心的特定情况转换成一个布尔值(
true或false)。 - 跟踪最高值:然后,使用一个变量来持续跟踪最高值。每当第一步的条件发生时(即重置信号出现时),我们就为该变量赋予一个初始值。
- 持续更新:之后,在每一根K线上,我们都去判断是否出现了新的更高值,并相应地更新我们的跟踪变量。
用ta.highest() 获取近期最高值
借助Pine Script的 ta.highest() 函数,我们可以获取某个变量或函数在近期内的最高值。该函数会返回回溯指定K线数量周期内的那个最高值。
该函数可以以两种不同的方式使用:
ta.highest(length)
ta.highest(source, length)
length:一个整数,代表回溯的K线周期长度。它设定了Pine Script在多长的时间窗口内寻找最高值。source(可选):我们想要从中寻找最高值的时间序列数据。这些数据可以是整数或浮点数。如果我们不提供这个参数,该函数会默认使用图表品种的最高价 (high)。
ta.highest() 函数会返回一个浮点数值,该值即为给定序列在指定周期内的最高值。
快速上手示例
要使用 ta.highest(),我们最多需要向它提供两条信息:要处理的数据序列,以及回溯的K线周期长度。
使用该函数最详尽(也最清晰)的方式是这样:
// 获取20周期内的最高高点
highestHigh = ta.highest(source=high, length=20)
这里,我们将函数的 source 参数设为 high 变量(即K线的最高价),并将 length 参数设为 20。这使得函数在过去20根K线的数据中进行计算。
由于 ta.highest() 只有这两个参数,大多数时候我们并不会写出可选的 source 和 length 关键字。我们通常直接告诉函数要使用哪个数据和多长的周期。例如:
// 获取20周期内的最高高点,省略了
// 可选的 'source=' 和 'length=' 部分
highestHigh = ta.highest(high, 20)
更进一步,由于 ta.highest() 默认就是处理K线的最高价,我们甚至可以省略 high 变量。下面这段更简洁的代码能得到完全相同的结果:
// 获取20周期内的最高高点
highestHigh = ta.highest(20)
我个人偏好明确地写出 high,这样能让代码的意图更清晰,但您可以随意选择自己喜欢的风格。
ta.highest() 当然也可以分析其他数据。为此,我们就必须明确指定数据序列。例如,如果我们想要最高收盘价,我们可以使用 close 变量:
// 获取10周期内的最高收盘价
highestClose = ta.highest(close, 10)
除了像 high 和 close 这样的内置变量,ta.highest() 也可以处理我们自己创建的变量。下面的例子展示了该函数如何返回一个移动平均线变量在20个周期内的最高值:
// 计算10周期简单移动平均线
smaValue = ta.sma(close, 10)
// 获取20周期内的最高SMA值
highestSMA = ta.highest(smaValue, 20)
此外,ta.highest() 还可以直接处理其他函数返回的结果,只要那个函数返回的是一个时间序列数据。例如,上一个例子中的 ta.sma() 函数就符合要求,所以我们也可以将 ta.sma() 直接嵌套在 ta.highest() 内部:
// 获取10周期SMA在20个周期内的最高值
highestSMA = ta.highest(ta.sma(close, 10), 20)
为何要在突破判断中排除当前K线?
有一个重点需要记住:ta.highest() 函数返回的最高值,是包含当前K线数据的。如果这正是我们想要的,那没有问题。但有时,这可能会导致意想不到的结果,尤其是在处理突破逻辑时。
假设我们想获取常见的20周期最高高点。我们可能会这样编码:
// 获取20周期的最高高点(包含当前K线的数据)
highestHigh = ta.highest(high, 20)
这行代码会返回一个包含了当前K线数据的最高高点值。也就是说,我们获取的是最近20根K线的数据,包括脚本当前正在其上计算的那一根。
当我们把这个最高高点绘制出来时,图表上会是这样:
正如我们所见,ta.highest() 计算出的最高高点值,总是包含了当前这根K线的最高价。所以,当一根K线创出新高时,这个最高高点的值也会在同一根K线上随之增加。
当我们编写突破策略时,这种情况就会引发一个问题。因为如果最高高点这个基准已经包含了当前K线的数据,那么当前K线的价格就永远不可能上穿这个最高值。因此,我们期望的价格突破信号也就永远不会出现。
为了解决这个问题,我们在 ta.highest() 函数的后面,加上一个带有值 1 的历史引用运算符 ([])。
代码看起来是这样:
// 获取前面20根K线的最高高点(不包含当前K线)
highestHigh = ta.highest(high, 20)[1]
这个 [1] 所做的,就是将 ta.highest() 的计算结果向过去偏移一根K线。这意味着,我们得到的仍然是20个周期内的最高高点,但计算的起点是前一根K线,从而排除了当前K线的数据。
因为我们现在参考的是之前的最高高点,所以当前K线的价格就有可能上穿这个高点。图表上的效果是这样的:
这展示了最高高点如何延迟了一根K线。所以,当一根K线创出更高的高点时,它首先是向上突破了之前的20周期高点,从而产生突破信号。然后,在下一根K线上,这个最高高点的值才会更新到这个新的高点。
当我们使用 ta.highest() 并配合 [1] 时,我们的脚本就能够正确地发现并交易价格突破了。
ta.highest() 的特性
在Pine Script第4版及更早版本中,ta.highest() 函数曾被命名为 highest() 函数。除了名称上的变化,该函数在Pine Script第5版中的功能行为没有改变。
完整示例脚本
让我们在一个完整的脚本中使用 ta.highest() 函数。下方的指标计算了最高高点和最高收盘价,两者的回看周期都设为20。我们在图表上绘制这两个值,并填充它们之间的背景区域,从而在这些最高价格周围创建出一个彩色的价格通道。
该指标的完整代码如下:
//@version=5
indicator(title="Recent highest values", overlay=true)
// 计算近期的最高高点和最高收盘价
highestHigh = ta.highest(high, 20)
highestClose = ta.highest(close, 20)
// 在图表上绘制这两个最高值
highPlot = plot(series=highestHigh, color=color.green, title="Highs")
closePlot = plot(series=highestClose, color=color.green, title="Closes")
// 填充两个绘图之间的背景,形成一个通道
fill(plot1=highPlot, plot2=closePlot, color=color.new(color.green, 80))
代码解析
首先,我们使用Pine Script的 indicator() 函数来定义指标的设置,这行代码为脚本命名,并将其叠加显示在主图的交易品种上。
接下来,我们计算20周期的最高高点。为此,我们调用 ta.highest() 函数并传入两个参数:使用 high 变量指定要分析的数据,并用 20 设置计算的周期长度。我们将返回的最高高点值储存在 highestHigh 变量中,以备后用。
为了计算最高收盘价,我们再次调用 ta.highest()。这次,我们让它使用 close 价格数据,周期长度同样为 20。我们将最高收盘价储存在 highestClose 变量中。
然后,我们使用 plot() 函数绘制最高高点 (highestHigh),并用第二个 plot() 调用来绘制最高收盘价 (highestClose)。两条线都以绿色 (color.green) 显示,并且由于我们没有设置绘图类型,它们默认为常规的线图。因为后续填充背景时需要用到这两个绘图对象,我们将它们分别储存在 highPlot 和 closePlot 变量中。
最后,我们使用 fill() 函数来填充两个绘图之间的图表背景区域。通过 highPlot 和 closePlot 变量,我们告诉函数应该在哪个区域进行填充。对于这个阴影区域,我们使用绿色 (color.green),并通过 color.new() 函数为其设置了80%的透明度。
当这个脚本在图表上运行时,它会高亮显示最高高点和最高收盘价之间的区域。在一个2小时周期的AUDCAD图表上,效果如下:
内容总结
ta.highest()函数返回一个数据序列在回溯指定K线数量内的最高值。- 如果我们不告诉
ta.highest()要分析哪个序列,它会默认使用图表品种的最高价 (high)。 ta.highest()的计算结果包含当前K线的数据。这使得我们无法直接用它来判断当前K线是否向上突破。- 当我们需要判断突破时,可以通过历史引用运算符
[1]来偏移其结果(例如:ta.highest(20)[1])。这样,我们获取的就是不包含当前K线的前期最高值,从而使突破判断成为可能。
用ta.lowest() 获取近期最低值
借助Pine Script的 ta.lowest() 函数,我们可以获取某个变量或函数在近期内的最低值。该函数会返回回溯指定K线数量周期内的那个最低值。
该函数可以以两种不同的方式使用:
ta.lowest(length)
ta.lowest(source, length)
length:一个整数,代表回溯的K线周期长度。它设定了Pine Script在多长的时间窗口内寻找最低值。source(可选):我们想要从中寻找最低值的时间序列数据。这些数据可以是整数或浮点数。如果我们不提供这个参数,ta.lowest()会默认使用图表品种的最低价 (low)。
ta.lowest() 函数会返回一个浮点数值,该值即为给定序列在指定周期内的最低值。
快速上手示例
要使用 ta.lowest(),我们最多需要向它提供两条信息:要处理的数据序列,以及回溯的K线周期长度。
使用该函数最详尽(也最清晰)的方式是这样:
// 获取20周期内的最低低点
lowestLow = ta.lowest(source=low, length=20)
这里,我们将函数的 source 参数设为 low 变量(即K线的最低价),并将 length 参数设为 20。这使得函数在过去20根K线的数据中进行计算。
由于 ta.lowest() 只有这两个参数,我们很少会写出可选的 source 和 length 关键字。我们通常直接告诉函数要使用哪个数据和多长的周期。像这样:
// 获取20周期内的最低低点,省略了
// 可选的 'source=' 和 'length=' 部分
lowestLow = ta.lowest(low, 20)
我们甚至可以进一步简化代码。因为 ta.lowest() 默认就是处理K线的最低价,所以它并不需要 low 变量。下面这段更简洁的代码能得到完全相同的结果:
// 获取20周期内的最低低点
lowestLow = ta.lowest(20)
我个人偏好明确地写出 low,这样能让代码的意图更清晰,但您可以随意选择自己喜欢的风格。
ta.lowest() 当然也可以分析其他数据。为此,我们就必须明确指定数据序列。例如,如果我们想要最低收盘价,我们可以使用 close 变量:
// 获取10周期内的最低收盘价
lowestClose = ta.lowest(close, 10)
除了像 low 和 close 这样的Pine Script内置变量,ta.lowest() 也可以处理我们自己创建的变量。下面的例子展示了该函数如何处理一个持有10周期指数移动平均线的变量:
// 计算10周期EMA
emaValue = ta.ema(close, 10)
// 获取20周期内的最低EMA值
lowestEMA = ta.lowest(emaValue, 20)
此外,ta.lowest() 还可以直接处理其他函数返回的结果,只要那个函数返回的是一个时间序列数据。例如,上一个例子中的 ta.ema() 函数就符合要求,所以我们也可以将 ta.ema() 直接嵌套在 ta.lowest() 内部:
// 获取10周期EMA在20个周期内的最低值
lowestEMA = ta.lowest(ta.ema(close, 10), 20)
为何要在突破判断中排除当前K线?
有一个值得记住的重点是:ta.lowest() 函数返回的最低值,是包含当前K线数据的。如果这正是我们想要的,那没有问题。但有时,这可能会产生我们不希望看到的效果,尤其是在处理向下的突破(breakdown)逻辑时。
假设我们想获取常规的20周期最低低点。我们可能会这样编码:
// 获取20周期的最低低点(包含当前K线的数据)
lowestLow = ta.lowest(low, 20)
这行代码会返回一个包含了当前K线数据的最低低点值。也就是说,我们获取的是最近20根K线的数据,包括脚本当前正在其上计算的那一根。
当我们把这个最低低点绘制出来时,我们看到的是这样:
在这张图表上,最低值总是包含了每一根K线的最低价。当某一根K线创出新低时,这个最低值也会在同一根K线上立即更新。
当我们编写向下的突破(breakdown)策略时,这种行为会引发一个问题。因为如果最低低点这个基准已经包含了当前K线的数据,那么当前K线的价格就永远不可能下穿这个最低值。这意味着,我们期望的价格向下跌破的信号也就永远不会出现。
为了解决这个问题,我们在 ta.lowest() 函数的后面,加上一个带有值 1 的历史引用运算符 ([])。
代码看起来是这样:
// 获取前面20根K线的最低低点(不包含当前K线)
lowestLow = ta.lowest(low, 20)[1]
这个 [1] 所做的,就是将 ta.lowest() 的计算结果向过去偏移一根K线。也就是说,我们得到的仍然是20个周期内的最低低点,但计算的起点是前一根K线,从而排除了当前K线的数据。
因为我们现在参考的是之前的最低低点,所以当前K线的价格就有可能跌破这个低点。在图表上的效果是这样的:
现在,最低低点延迟了一根K线。当一根K线创出更低的低点时,它首先是向下跌破了之前的20周期低点,从而产生突破信号。然后,在下一根K线上,这个最低低点的值才会更新到这个新的低点。
当我们使用 ta.lowest() 并配合 [1] 时,我们的脚本就能够正确地发现并交易价格的向下跌破了。
ta.lowest() 的特性
在Pine Script第4版及更早版本中,ta.lowest() 函数曾被命名为 lowest()。除了名称上的变化,该函数在Pine Script第5版中的功能行为没有改变。
完整示例脚本
让我们在一个完整的脚本中使用 ta.lowest()。下方的指标计算了20周期的最低低点和最低收盘价。这两个值都以线条的形式绘制出来,然后脚本会填充它们之间的背景区域,从而创建一个价格带来高亮显示最低低点和最低收盘价。
该指标的代码如下:
//@version=5
indicator(title="Recent lowest values", overlay=true)
// 计算近期的最低低点和最低收盘价
lowestLow = ta.lowest(low, 20)
lowestClose = ta.lowest(close, 20)
// 在图表上绘制这两个最低值
lowPlot = plot(series=lowestLow, color=color.red, title="Lows")
closePlot = plot(series=lowestClose, color=color.red, title="Closes")
// 通过填充两个绘图之间的背景来创建一个价格带
fill(plot1=lowPlot, plot2=closePlot, color=color.new(color.red, 80))
代码解析
首先,我们使用 indicator() 函数来配置脚本,这行代码为脚本命名,并将其输出叠加在主图的交易品种上。
为了计算20周期的最低低点,我们调用 ta.lowest() 函数并传入两个参数:low 明确告诉函数要使用K线的最低价,20 则设置了计算周期。我们将返回的最低低点值存入 lowestLow 变量。
对于最低收盘价,我们再次调用 ta.lowest()。这次我们指定 close 变量作为要分析的序列,并使用相同的回看周期(20)。我们将这个最低收盘价储存在 lowestClose 变量中。
接下来,我们两次执行 plot() 函数。第一个在图表上显示最低低点 (lowestLow),另一个则显示最低收盘价 (lowestClose)。两条线都以红色 (color.red) 显示。由于我们没有指定绘图类型,Pine Script默认将它们创建为常规的线图。因为后续填充背景时需要用到这两个绘图对象,我们将它们分别储存在 lowPlot 和 closePlot 变量中。
最后的代码是 fill() 函数,用于为两个绘图之间的背景着色。这里我们使用了上一步创建的绘图变量,这样函数就知道应该在哪个区域进行填充。这个阴影背景区域将是红色的 (color.red),并通过 color.new() 函数为其设置了80%的透明度。
当脚本在图表上运行时,它会高亮显示最低低点和最低收盘价之间的区域。在一个2小时周期的AUDCAD图表上,这个价格带看起来是这样的:
内容总结
ta.lowest()函数返回一个数据序列在回溯指定K线数量内的最低值。- 如果我们不给
ta.lowest()指定要分析的序列,它会默认使用图表品种的最低价 (low)。 ta.lowest()的计算结果包含当前K线的数据。这使得我们无法直接用它来判断当前K线是否向下跌破。- 当我们需要判断突破时,可以通过历史引用运算符
[1]来偏移其结果(例如:ta.lowest(10)[1])。这样,我们获取的就是不包含当前K线的前期最低值,从而使向下的突破判断成为可能。










