当我们想创建一段包含多个动态数据的复杂文本时,比如“BTCUSD
在2025-07-27 20:00
收盘于52345.67
,上涨了1.23%
”,如果用+
号和str.tostring()
一个个拼接,代码会变得非常混乱且难以阅读。
为了解决这个问题,PineScript提供了一个终极武器:str.format()
函数。它让你先设计好一个文本模板,然后像完形填空一样,把动态数据精准地填进去,是生成专业图表标签、复杂警报信息的首选工具。
str.format()
函数的核心思想:“挖坑填数”
它的基本语法是:str.format(formatString, arg0, arg1, ...)
formatString
:你的“文本模板”,也就是一段带有“坑”的字符串。arg0, arg1, ...
:用来“填坑”的一系列动态值(数字、布尔值、字符串等)。
程序会把arg0
填到{0}
号坑,arg1
填到{1}
号坑,以此类推,最终生成一段完整的文本。
// 示例:为买入信号生成提示文本
positionSize = 100
buyText = str.format("买入 {0} 手 {1} 于价格 {2}",
positionSize, syminfo.ticker, close)
// 假设 positionSize = 100, syminfo.ticker = "BTCUSD", close = 50000
// 输出文本将是: "买入 100 手 BTCUSD 于价格 50000"
占位符
str.format()
的强大之处在于,这些坑(占位符)不仅能决定填什么,还能决定怎么填(即格式)。一个完整的占位符结构是:{index, format-specifier, custom-specifier}
index
(必需):从0开始的数字,决定用第几个参数来填这个坑。format-specifier
(可选):预设的格式类型,比如number
(数字)或date
(日期)。custom-specifier
(可选):更精细的自定义格式。
基础填坑 {index}
只用索引号,程序会自动用默认格式转换。
str.format("{0} 收盘于 {1}, ATR为 {2}", syminfo.ticker, close, ta.atr(14))
// 输出: "TSLA 收盘于 183.17, ATR为 12.146"
使用预设格式 {index, format-specifier}
对于数字和时间,PineScript提供了一些方便的预设格式。
- 数字 (number):
number,integer
:整数number,currency
:货币number,percent
:百分比
- 日期/时间 (date/time):
date,short
/date,long
等time,short
/time,long
等
str.format("{0} 于 {1,date} 收盘价为 {2,number,currency}.", syminfo.ticker, time_close, close)
// 输出: "TSLA 于 Jul 27, 2025 收盘价为 $183.17."
自定义格式 {index, type, custom}
这是最精细的控制方式,你可以自定义任何想要的格式,使用“模式占位符”,和str.tostring()
中的一样。
自定义日期/时间格式:使用模式字母。
y
: 年 (yy
,yyyy
)M
: 月 (M
,MM
,MMM
,MMMM
)d
: 日 (d
,dd
)H
: 小时 (0-23)m
: 分钟s
: 秒
str.format("{0} 在 {1,date,yyyy-MM-dd HH:mm} 的收盘价是 {2,number,#,###.00}。",
syminfo.ticker, time_close, close)
// 输出: "TSLA 在 2025-07-27 20:00 的收盘价是 183.17。"
实战案例:
创建一个信息丰富的“数据看板”标签,下面的指标脚本综合运用了str.format()
的各种功能,在图表上创建了一个信息密度极高的标签,实时显示当前品种的关键数据。
//@version=6
indicator(title="str.format() 案例", overlay=true)
// 1. 获取图表历史最高/低价
chartHigh = ta.max(high)
chartLow = ta.min(low)
// 2. 创建标签
if barstate.islast
// 计算当前价格的百分比
changeSinceLow = ((close - chartLow) / chartLow)
changeSinceHigh = ((close - chartHigh) / chartHigh)
// 3. 使用 str.format()
chartDataStr = str.format(
"{0} ({1}): 最新价 ${2,number,###.00}\n" +
"全周期最高: {3,number,###.00} (距此 {4,number,0.00%})\n" +
"全周期最低: {5,number,###.00} (距此 {6,number,0.00%})",
// 下方是{0} - {6}参数
syminfo.ticker, // {0}: 品种代码
syminfo.prefix, // {1}: 前缀
close, // {2}: 收盘价
chartHigh, // {3}: 历史最高价
changeSinceHigh, // {4}: 百分比
chartLow, // {5}: 历史最低价
changeSinceLow // {6}: 百分比
)
// 4. 创建文本
label.new(bar_index, hl2, text=chartDataStr,
size=size.large, color=color.new(color.silver, 20),
textcolor=color.black, style=label.style_label_left)
此脚本会在图表最右侧生成一个标签,清晰地展示了品种代码、交易所、最新价、历史高低点以及相应的百分比变动,充分体现了str.format()
在灵活构建信息字符串方面的能力。
避坑指南
str.tostring()
适合转换单个值,且独有format.mintick
和format.volume
格式。str.format()
更适合组合多个值。它们可以配合使用。str.format()
可以格式化时间戳,但如果需要时区转换,必须使用更专业的str.format_time()
。- 你的文本模板可以用
+
号拼接成多行,也可以存放在一个变量里重复使用,甚至可以用if/else
来动态选择不同的模板。 - 参数可以比占位符多,多余的会被忽略,不会报错。
- 如果你想在模板里显示
{
或}
本身,需要用单引号'
把它们括起来,比如str.format("'{0}'", 123)
会输出{123}
。
总结
str.format()
的核心功能是基于一个“文本模板”,将多个动态值格式化并“填空”进去,生成一个新的字符串。模板中的占位符{index, type, custom}
不仅决定了填入哪个值,还能精细地控制其显示格式。它是创建包含多个动态数据的复杂标签、警报和日志信息的首选工具,代码比用+
号拼接更清晰、更易于维护。