文本和形状
介绍
您可以使用 Pine Script™ 的五种不同方式显示文本或形状:
- 绘图字符()
- 绘图形状()
- 图箭头()
- 使用label.new()创建的标签
- 使用table.new()创建的表 (参见表格)
使用哪一个取决于您的需求:
- 表格可以在图表上以各种相对位置显示文本,这些文本不会随着用户滚动或水平缩放图表而移动。其内容不受条形图的束缚。相比之下,使用 plotchar()、 plotshape() 或 label.new()显示的文本始终受特定条形图的束缚,因此它将随着图表上条形图的位置而移动。有关它们的更多信息,请参阅表格 页面 。
- 包括三个函数能够显示预定义的形状: plotshape(), plotarrow()和用label.new() 创建的标签 。
- plotarrow() 不能显示文本,只能显示向上或向下的箭头。
- plotchar() 和 plotshape() 可以在图表的任意条或所有条上显示非动态文本。
- plotchar() 只能显示一个字符,而 plotshape() 可以显示字符串,包括换行符。
- label.new() 最多可在图表上显示 500 个标签。其文本可以 包含动态文本或“系列字符串”。标签文本还支持换行。
- 虽然 plotchar() 和 plotshape() 可以以过去或将来的固定偏移量显示文本,并且该偏移量在脚本执行期间不会改变,但每个 label.new() 调用都可以使用可以动态计算的“系列”偏移量。
关于 Pine Script™ 琴弦,需要记住以下几点:
- 由于plotchar()
和
plotshape()
text
中的参数都 需要“const string”参数,因此它不能包含只能在条形图上知道的值(例如价格(“系列字符串”)。 - 要在使用label.new()显示的文本中包含“系列”值 ,首先需要使用str.tostring()将它们转换为字符串 。
- Pine 中的字符串连接运算符是
+
。它用于将字符串组件连接成一个字符串,例如msg = "Chart symbol: " + syminfo.tickerid
(其中 syminfo.tickerid 是一个内置变量,以字符串格式返回图表的交易所和符号信息)。 - 所有这些函数显示的字符都可以是 Unicode 字符,其中可能包括 Unicode 符号。请参阅此Exploring Unicode 脚本,了解 Unicode 字符可以做什么。
- 有时可以使用函数参数来控制文本的颜色或大小,但无法进行内联格式化(粗体、斜体、等宽字体等)。
- Pine 脚本中的文本始终以 Trebuchet MS 字体显示在图表上,该字体用于许多 TradingView 文本,包括这个。
该脚本使用 Pine Script™ 中提供的四种方法显示文本:
//@version=5
indicator("Four displays of text", overlay = true)
plotchar(ta.rising(close, 5), "`plotchar()`", "🠅", location.belowbar, color.lime, size = size.small)
plotshape(ta.falling(close, 5), "`plotchar()`", location = location.abovebar, color = na, text = "•`plotshape()•`\n🠇", textcolor = color.fuchsia, size = size.huge)
if bar_index % 25 == 0
label.new(bar_index, na, "•LABEL•\nHigh = " + str.tostring(high, format.mintick) + "\n🠇", yloc = yloc.abovebar, style = label.style_none, textcolor = color.black, size = size.normal)
printTable(txt) => var table t = table.new(position.middle_right, 1, 1), table.cell(t, 0, 0, txt, bgcolor = color.yellow)
printTable("•TABLE•\n" + str.tostring(bar_index + 1) + " bars\nin the dataset")
注意:
- 用于显示每个文本字符串的方法与文本一起显示,除了使用plotchar()显示的向上箭头外 ,因为它只能显示一个字符。
- 标签和表格调用可以插入条件结构中,以控制何时执行它们,而
plotchar()
和
plotshape()
则不能。它们的条件绘图必须使用其第一个参数来控制,该参数是一个“系列布尔值”,其
true
或false
值决定何时显示文本。 - 表格和标签中显示的数字值首先使用 str.tostring()转换为字符串。
- 我们使用
+
运算符来连接字符串组件。 - plotshape()
旨在显示带有文本的形状。其
size
参数控制形状的大小,而不是文本的大小。我们使用 na 作为其color
参数,这样形状就不可见了。 - 与其他文本相反,表格文本不会随着图表滚动或缩放而移动。
- 一些文本字符串包含🠇 Unicode 箭头 (U+1F807)。
- 一些文本字符串包含
\n
代表新行的序列。
`plotchar()`
此函数可用于在条形图上显示单个字符。其语法如下:
有关 plotchar() 参数的详细信息,请参阅参考手册中的条目。
正如我们调试页面中当必须保留脚本的比例部分 所述 ,该函数可用于显示和检查数据窗口中的值,或图表上脚本名称右侧显示的指标值:
//@version=5
indicator("", "", true)
plotchar(bar_index, "Bar index", "", location.top)
注意:
- 光标位于图表的最后一条柱上。
- 该条 上的bar_index值 显示在指标值 (1) 和数据窗口 (2) 中。
- 我们使用 location.top 因为默认的 location.abovebar 会在脚本的比例中考虑价格,这通常会干扰其他图表。
plotchar()
还可以很好地识别图表上的特定点或验证条件是否true
符合我们的预期。此示例在
收盘价、
最高价
和
成交量
连续两个柱状图上升的柱状图下方显示一个向上箭头:
//@version=5
indicator("", "", true)
bool longSignal = ta.rising(close, 2) and ta.rising(high, 2) and (na(volume) or ta.rising(volume, 2))
plotchar(longSignal, "Long", "▲", location.belowbar, color = na(volume) ? color.gray : color.blue, size = size.tiny)
注意:
- 我们使用,这样我们的脚本就可以在没有成交量
(na(volume) or ta.rising(volume, 2))
数据的情况下工作 。如果我们没有为没有 成交量数据的情况做好准备,那么 变量的值永远不会是, 因为在这些情况下会产生收益。na(volume)
true
longSignal
true
ta.rising(volume, 2)
false
- 当没有成交量时,我们会将箭头显示为灰色,以提醒我们所有三个基本条件均未得到满足。
- 因为
plotchar()
现在在图表上显示一个字符,我们用它
size = size.tiny
来控制它的大小。 - 我们已经调整了
location
论点,以显示条下的字符。
如果您不介意只绘制圆形,您也可以使用 plot() 来实现类似的效果:
//@version=5
indicator("", "", true)
longSignal = ta.rising(close, 2) and ta.rising(high, 2) and (na(volume) or ta.rising(volume, 2))
plot(longSignal ? low - ta.tr : na, "Long", color.blue, 2, plot.style_circles)
这种方法的不便之处在于,由于plot()没有相对定位机制,因此 必须使用类似ta.tr (条形图的“真实范围”) 将圆圈向下移动 :
`plotshape()`
此函数可用于在条形图上显示预定义的形状和/或文本。其语法如下:
有关 plotshape() 参数的详细信息,请参阅参考手册中的条目。
让我们使用该函数来实现与上一节的第二个示例大致相同的结果:
//@version=5
indicator("", "", true)
longSignal = ta.rising(close, 2) and ta.rising(high, 2) and (na(volume) or ta.rising(volume, 2))
plotshape(longSignal, "Long", shape.arrowup, location.belowbar)
请注意,这里我们没有使用箭头字符,而是使用参数
shape.arrowup
作为参数style
。
可以使用不同的
plotshape()
调用将文本叠加在条形图上。您需要使用\n
后跟不会被删除的特殊非打印字符来保留换行符的功能。这里我们使用 Unicode 零宽度空格 (U+200E)。虽然您在以下代码的字符串中看不到它,但它确实存在并且可以复制/粘贴。对于向上的文本,特殊的 Unicode 字符必须是字符串中的最后一个字符,而当您在条形图下方绘图并且文本向下时,则必须是第一个字符:
//@version=5
indicator("Lift text", "", true)
plotshape(true, "", shape.arrowup, location.abovebar, color.green, text = "A")
plotshape(true, "", shape.arrowup, location.abovebar, color.lime, text = "B\n")
plotshape(true, "", shape.arrowdown, location.belowbar, color.red, text = "C")
plotshape(true, "", shape.arrowdown, location.belowbar, color.maroon, text = "\nD")
可以与style
参数一起使用的形状有:
争论 | 形状 | 带文字 | 争论 | 形状 | 带文字 |
---|---|---|---|---|---|
shape.xcross | shape.arrowup | ||||
shape.cross | shape.arrowdown | ||||
shape.circle | shape.square | ||||
shape.triangleup | shape.diamond | ||||
shape.triangledown | shape.labelup | ||||
shape.flag | shape.labeldown |
`plotarrow()`
plotarrow函数 根据函数第一个参数中使用的系列的相对值显示可变长度的向上或向下箭头。它的语法如下:
有关其参数的详细信息,请参阅参考手册中的 plotarrow() 条目。
plotarrow()series
中的参数
不是
plotchar
()
和
plotshape()中的“系列布尔值” ;它是一个“系列 int/float”,它不仅仅是一个简单的
或值,用于确定何时绘制箭头。这是控制提供给 plotarrow() 的参数如何影响plotarrow()行为的
逻辑:true
false
series
series > 0
:显示一个向上的箭头,其长度与该条上的系列相对于其他系列值的相对值成比例。series < 0
:显示向下的箭头,使用相同的规则按比例调整大小。series == 0 or na(series)
:不显示箭头。
minheight
可以使用和参数控制箭头的最大和最小可能尺寸(以像素为单位)maxheight
。
这是一个简单的脚本,说明 plotarrow() 的 工作原理:
//@version=5
indicator("", "", true)
body = close - open
plotarrow(body, colorup = color.teal, colordown = color.orange)
请注意箭头的高度与条体的相对尺寸成比例。
您可以使用任何系列来绘制箭头。这里我们使用“Chaikin 振荡器”的值来控制箭头的位置和大小:
//@version=5
indicator("Chaikin Oscillator Arrows", overlay = true)
fastLengthInput = input.int(3, minval = 1)
slowLengthInput = input.int(10, minval = 1)
osc = ta.ema(ta.accdist, fastLengthInput) - ta.ema(ta.accdist, slowLengthInput)
plotarrow(osc)
请注意,我们在图表下方的窗格中显示实际的“Chaikin 振荡器”,因此您可以看到使用哪些值来确定箭头的位置和大小。
标签
标签仅在 Pine Script™ v4 及更高版本中可用。它们的工作方式与 plotchar() 和 plotshape()非常不同。
标签是对象,如 线条和框或 表格。与它们一样,它们使用 ID 来引用,其作用类似于指针。标签 ID 属于“标签”类型。与其他对象一样,标签 ID 是“时间序列”,用于管理它们的所有函数都接受“序列”参数,这使它们非常灵活。
标签具有以下优势:
- 它们允许将“系列”值转换为文本并放置在图表上。这意味着它们非常适合显示无法提前知道的值,例如价格值、支撑位和阻力位,以及脚本计算的任何其他值。
- 它们的定位选项比功能的定位选项更灵活
plot*()
。 - 它们提供更多显示模式。
- 与
plot*()
函数相反,标签处理函数可以插入条件或循环结构中,从而更容易控制其行为。 - 您可以向标签添加工具提示。
与plotchar()
和
plotshape()相比,使用标签的一个缺点
是,您只能在图表上绘制有限数量的标签。默认值为 ~50,但您可以使用indicator()
或
strategies()max_labels_count
声明语句中的参数
指定最多 500 个。标签(如
线条和框)使用垃圾收集机制进行管理,该机制会删除图表上最旧的标签,以便只有最近绘制的标签可见。
用于管理标签的内置工具箱全部位于label
命名空间中。它们包括:
- label.new() 创建标签。
label.set_*()
函数来修改现有标签的属性。label.get_*()
函数来读取现有标签的属性。- label.delete() 删除标签
- label.all数组
始终包含图表上所有可见标签的 ID。数组的大小取决于脚本的最大标签数量以及您绘制的标签数量。
aray.size(label.all)
将返回数组的大小。
创建和修改标签
label.new () 函数创建一个新标签。它具有以下签名:
允许您更改标签属性的设置器函数是:
- 标签.set_x()
- 标签.set_y()
- 标签.set_xy()
- 标签.设置文本()
- 标签.set_xloc()
- 标签.set_yloc()
- 标签.设置颜色()
- 标签.设置样式()
- 标签.设置文本颜色()
- 标签.设置大小()
- 标签.set_textalign()
- 标签.设置工具提示()
它们都有类似的签名。label.set_color ()的签名 是:
在哪里:
id
是要修改属性的标签的ID。- 下一个参数是要修改的标签的属性。这取决于使用的 setter 函数。label.set_xy () 会更改两个属性,因此它有两个这样的参数。
您可以按照以下方式以最简单的形式创建标签:
//@version=5
indicator("", "", true)
label.new(bar_index, high)
注意:
- 该标签是使用参数
x = bar_index
(当前条的索引, bar_index)和y = high
(条的 最高 值)创建的。 - 我们没有为函数的
text
参数提供实参。其默认值为空字符串,不显示任何文本。 - 没有逻辑控制我们的 label.new() 调用,因此在每个条上都会创建标签。
- 仅显示最后 54 个标签,因为我们的
indicator()
调用没有使用
max_labels_count
参数来指定除 ~50 默认值之外的值。 - 标签会一直保留在条形图上,直到脚本使用 label.delete()将其删除,或被垃圾收集器移除。
在下一个示例中,我们在最近 50 个条形图中具有最高高值的条形图上显示一个标签 :
//@version=5
indicator("", "", true)
// Find the highest `high` in last 50 bars and its offset. Change it's sign so it is positive.
LOOKBACK = 50
hi = ta.highest(LOOKBACK)
highestBarOffset = - ta.highestbars(LOOKBACK)
// Create label on bar zero only.
var lbl = label.new(na, na, "", color = color.orange, style = label.style_label_lower_left)
// When a new high is found, move the label there and update its text and tooltip.
if ta.change(hi)
// Build label and tooltip strings.
labelText = "High: " + str.tostring(hi, format.mintick)
tooltipText = "Offest in bars: " + str.tostring(highestBarOffset) + "\nLow: " + str.tostring(low[highestBarOffset], format.mintick)
// Update the label's position, text and tooltip.
label.set_xy(lbl, bar_index[highestBarOffset], hi)
label.set_text(lbl, labelText)
label.set_tooltip(lbl, tooltipText)
注意:
- 我们仅通过使用var
关键字声明
lbl
包含标签 ID 的变量,即可在第一个条形图上创建标签 。label.new()调用中的x
、y
和参数 无关紧要,因为标签将在后续条形图上更新。不过,我们确实会小心使用和我们想要的标签,这样它们以后就不需要更新了。text
color
style
- 在每根柱线上,我们通过测试以下值的变化来检测是否发现了新高:
hi
- 当高值发生变化时,我们会用新信息更新标签。为此,我们使用三个
label.set*()
调用来更改标签的相关信息。我们使用lbl
包含标签 ID 的变量来引用标签。因此,脚本在所有条形图中都保持相同的标签,但在检测到新高值时移动它并更新其信息。
这里我们在每个条形上创建一个标签,但是我们根据条形的极性有条件地设置它的属性:
//@version=5
indicator("", "", true)
lbl = label.new(bar_index, na)
if close >= open
label.set_text( lbl, "green")
label.set_color(lbl, color.green)
label.set_yloc( lbl, yloc.belowbar)
label.set_style(lbl, label.style_label_up)
else
label.set_text( lbl, "red")
label.set_color(lbl, color.red)
label.set_yloc( lbl, yloc.abovebar)
label.set_style(lbl, label.style_label_down)
定位标签
标签根据x(条形图)和y (
价格)坐标定位在图表上。五个参数影响此行为:x
、y
、
xloc
和:yloc
style
x
可以是条形索引或时间值。使用条形索引时,值可以偏移过去或将来(未来最多 500 条)。使用时间值时,也可以计算过去或未来的偏移。可以使用label.set_x()
或
label.set_xy()x
修改现有标签的值
。
xloc
是
xloc.bar_index
(默认) 或
xloc.bar_time。它决定必须使用哪种类型的参数x
。对于
xloc.bar_index,
x
必须是绝对条形索引。对于
xloc.bar_time,
必须是与
条形的
打开时间x
值相对应的 UNIX 时间(以毫秒为单位)
。可以使用label.set_xloc()修改现有标签的值
。xloc
y
yloc
标签所在的价格水平。只有在使用默认值时才会考虑yloc.price
。如果
yloc
是
yloc.abovebar
或
yloc.belowbar
,则y
忽略该参数。可以使用label.set_y()
或
label.set_xy()y
修改现有标签的值
。
yloc
可以是
yloc.price
(默认值)、
yloc.abovebar
或
yloc.belowbar。 使用的参数仅在yloc.pricey
时考虑
。可以使用label.set_yloc()修改现有标签的值
。yloc
style
使用的参数会影响标签的外观,以及当
使用yloc.abovebar
或
yloc.belowbary
时,其相对于参考点的位置(由条形图的值或顶部/底部
决定)。可以使用label.set_style()修改现有标签的样式
。style
这些是可用的style
参数:
争论 | 标签 | 带文本的标签 | 争论 | 标签 | 带文本的标签 |
---|---|---|---|---|---|
label.style_xcross | label.style_label_up | ||||
label.style_cross | label.style_label_down | ||||
label.style_flag | label.style_label_left | ||||
label.style_circle | label.style_label_right | ||||
label.style_square | label.style_label_lower_left | ||||
label.style_diamond | label.style_label_lower_right | ||||
label.style_triangleup | label.style_label_upper_left | ||||
label.style_triangledown | label.style_label_upper_right | ||||
label.style_arrowup | label.style_label_center | ||||
label.style_arrowdown | label.style_none |
使用
xloc.bar_time时,该x
值必须是以毫秒为单位的 UNIX 时间戳。
有关更多信息,
请参阅时间页面。当前条的开始时间可以从time
内置变量中获取。前几条的条时间为time[1]
,依此类推。还可以使用timestamptime[2]
函数
将时间设置为绝对值
。您可以添加或减去时间段以实现相对时间偏移。
我们在最后一栏的日期前一天放置一个标签:
//@version=5
indicator("")
daysAgoInput = input.int(1, tooltip = "Use negative values to offset in the future")
if barstate.islast
MS_IN_ONE_DAY = 24 * 60 * 60 * 1000
oneDayAgo = time - (daysAgoInput * MS_IN_ONE_DAY)
label.new(oneDayAgo, high, xloc = xloc.bar_time, style = label.style_label_right)
请注意,由于市场关闭时存在不同的时间间隔和缺失条形图,标签的定位可能并不总是准确的。这种时间偏移在 24x7 市场上往往更可靠。
您还可以使用条形索引来偏移值x
,例如:
label.new(bar_index + 10, high)
label.new(bar_index - 10, high[10])
label.new(bar_index[10], high[10])
读取标签属性
标签可以使用以下getter函数:
它们都有类似的签名。label.get_text ()的签名 是:
其中id
是要检索其文本的标签。
克隆标签
label.copy () 函数用于克隆标签。其语法为:
删除标签
label.delete () 函数用于删除标签。其语法为:
为了在图表上仅保留用户定义数量的标签,可以使用如下代码:
//@version=5
MAX_LABELS = 500
indicator("", max_labels_count = MAX_LABELS)
qtyLabelsInput = input.int(5, "Labels to keep", minval = 0, maxval = MAX_LABELS)
myRSI = ta.rsi(close, 20)
if myRSI > ta.highest(myRSI, 20)[1]
label.new(bar_index, myRSI, str.tostring(myRSI, "#.00"), style = label.style_none)
if array.size(label.all) > qtyLabelsInput
label.delete(array.get(label.all, 0))
plot(myRSI)
注意:
- 我们定义一个
MAX_LABELS
常量来保存脚本可以容纳的最大标签数量。我们使用该值来设置 indicator()max_labels_count
调用中的参数值 ,并将其作为input.int()调用中的值 来限制用户值。maxval
- 当我们的 RSI 突破过去 20 条的最高值时,我们会创建一个新标签。请注意
[1]
我们在 中使用 的偏移量。这是必要的。如果没有它, ta.highest()if myRSI > ta.highest(myRSI, 20)[1]
返回的值 将始终包含 的当前值,因此永远不会高于函数的返回值。myRSI
myRSI
- 之后,我们删除 label.all数组中最旧的标签 ,该数组由 Pine Script™ 运行时自动维护,包含我们脚本绘制的所有可见标签的 ID。我们使用 array.get () 函数检索索引为零的数组元素(最旧的可见标签 ID)。然后我们使用 label.delete() 删除与该 ID 关联的标签。
请注意,如果只想在最后一个条形图上放置标签,则创建和删除标签是不必要的,也是低效的,因为脚本会在所有条形图上执行,因此只保留最后一个标签:
// INEFFICENT!
//@version=5
indicator("", "", true)
lbl = label.new(bar_index, high, str.tostring(high, format.mintick))
label.delete(lbl[1])
这是实现相同任务的有效方法:
//@version=5
indicator("", "", true)
if barstate.islast
// Create the label once, the first time the block executes on the last bar.
var lbl = label.new(na, na)
// On all iterations of the script on the last bar, update the label's information.
label.set_xy(lbl, bar_index, high)
label.set_text(lbl, str.tostring(high, format.mintick))
实时行为
标签可执行提交和回滚操作,这些操作会影响脚本在实时栏中执行时的行为。请参阅 Pine Script™ 的执行模型页面 。
此脚本演示了在实时栏中运行时回滚的效果:
//@version=5
indicator("", "", true)
label.new(bar_index, high)
在实时柱上, label.new() 会在每次脚本更新时创建一个新标签,但由于回滚过程,同一柱上上次更新时创建的标签将被删除。只有在实时柱关闭前创建的最后一个标签才会被提交,从而保留下来。