如何把趋势线延伸至整个图表
指标或策略创建一条趋势线之后,我们可能希望把这条线向左和/或向右无限延伸。这一节来看看怎么实现。
line.set_extend()函数
在TradingView中,脚本用line.new()函数画趋势线。图表上有了线之后,我们可以对它做多种修改,其中之一就是延伸趋势线:让它向右无限延伸,跨越未来的所有价格K线;或者向左延伸,覆盖图表上的所有历史K线;也可以同时向两个方向无限延伸。这些延伸效果都由line.set_extend()函数实现。
该函数要延伸一条趋势线,必须知道两件事:调整哪条线、用哪种延伸样式。标准语法如下:
line.set_extend(id, extend)
id参数指定要更改的线,用的是line.new()创建趋势线时返回的线条引用;extend参数设置线的新延伸样式。TradingView提供了四种延伸方式:
- extend.right:让线段从终点(x2、y2坐标)开始向右无限延伸。
- extend.left:让线段从起点(x1、y1坐标)开始向左无限延伸。
- extend.both:让线段从起点和终点向两侧无限延伸。
- extend.none:禁用延伸,让线恢复为只连接起点(x1、y1)和终点(x2、y2)的原始线段。
下图展示了这四种延伸选项在图表上的视觉效果:

实现趋势线延伸有两种方式:一种是创建时通过line.new()函数的extend参数直接设定;另一种是用line.set_extend()函数修改一条已存在的线的延伸状态。
快速示例
假设我们想让一条线向过去无限延伸(向左侧的历史K线延伸),可以这样写:
// 创建一条连接10根K线前至今的趋势线
myLine = line.new(x1=bar_index[10], y1=close[10],
x2=bar_index, y2=close)
// 将该线向左无限延伸
line.set_extend(id=myLine, extend=extend.left)
这段代码先创建一条趋势线,引用存入myLine变量。然后调用line.set_extend(),传入myLine和extend.left,线就向左无限延伸了。
另一个例子是向两侧延伸:
// 绘制一条短的水平线
myLine = line.new(x1=bar_index[1], y1=close,
x2=bar_index, y2=close)
// 将该线向两侧延伸
line.set_extend(id=myLine, extend=extend.both)
这里先创建一条只连接当前K线和前一根K线的短水平线,然后通过line.set_extend()和extend.both,把它变成一条横贯整个图表的无限长水平线。
顺便一提,Pine Script中的关键字参数通常是可选的,省略它们可以让代码更简洁:
// 绘制一条短的水平线
myLine = line.new(bar_index[1], close, bar_index, close)
// 将该线向两侧延伸
line.set_extend(myLine, extend.both)
示例脚本:用延伸线展示开盘区间
通过一个完整脚本深入了解line.set_extend()的用法。这个指标的核心逻辑是:每个交易日第一根K线收盘后,自动画出开盘区间的最高价和最低价水平线,并向右无限延伸,作为当日的支撑和阻力参考。
脚本的完整代码如下:
//@version=5
indicator(title="延伸开盘区间", overlay=true)
// 判断是否是新的一天开始
firstBarOfDay = dayofmonth != dayofmonth[1]
// 创建持久化的线变量(以便后续能访问到历史线条)
var line highLine = na
var line lowLine = na
// 当日内第一根K线收盘时,创建向右延伸的水平线
if firstBarOfDay and barstate.isconfirmed
// 创建开盘区间的高点和低点线
highLine := line.new(x1=bar_index[1], y1=high,
x2=bar_index, y2=high,
color=color.green, width=2)
lowLine := line.new(x1=bar_index[1], y1=low,
x2=bar_index, y2=low,
color=color.red, width=2)
// 将两条线都向右无限延伸
line.set_extend(highLine, extend.right)
line.set_extend(lowLine, extend=extend.right)
// 清理掉前一天的旧线
line.delete(highLine[1])
line.delete(lowLine[1])
脚本先通过dayofmonth != dayofmonth[1]判断新交易日的开始。接着声明两个持久化变量(var)highLine和lowLine,用来在不同K线之间追踪最新创建的水平线引用。
当if语句检测到新交易日第一根K线收盘(barstate.isconfirmed)时,脚本做三件事。第一,创建新线:用line.new()在开盘K线的高点和低点分别创建两条短水平线,引用存入highLine和lowLine变量。第二,延伸新线:紧接着调用line.set_extend()两次,把两条新线都设为向右无限延伸(extend.right),让它们贯穿整个交易日。第三,删除旧线:为保持图表整洁,用line.delete()配合历史引用[1](如highLine[1])删掉前一个交易日的旧线。
脚本运行效果如下,两条线从每日开盘K线开始向右无限延伸,清晰标示出当日开盘区间的高低点:

line.set_extend()的特性
line.set_extend()函数有几个值得注意的特性:
- 延伸趋势线只改变它的视觉长度,定义起点和终点的数据坐标保持不变。也就是说无论线是否延伸,通过line.get_x1()等函数获取的坐标值都相同。
- 要修改一条线的延伸状态,必须有它的引用。获得引用的唯一方法是创建时把line.new()的返回值存进变量。
- 目前无法通过代码查询一条线当前的延伸样式,确保其状态的唯一方法就是主动设置。
- 内置的延伸功能是无限的。想只延伸特定数量K线或特定时间的有限延伸,需要自定义代码逻辑。
- 如果只需一次性的延伸设置,直接在创建时用line.new()的extend参数会更简洁。
- 代码创建的趋势线无法在图表上手动修改属性,包括延伸状态。
- line.set_extend()是void函数(无返回值函数),不返回任何值表示操作是否成功。
总结
用代码创建趋势线后,可以用line.set_extend()函数修改它的延伸状态。该函数需要两个参数:第一个是目标线的引用,第二个是新的延伸样式。
可用的样式包括向左延伸(extend.left)、向右延伸(extend.right)、双向延伸(extend.both),以及禁用延伸(extend.none)。如果创建时就需要延伸,用line.new()函数的extend参数是更直接的选择。
如何用代码更改趋势线的粗细
在TradingView中用代码画趋势线时,它在图表上会以标准尺寸显示。但如果我们想让线条更粗呢?这一节来看看怎么做。
line.set_width()函数
在Pine Script中,我们用line.new()函数画趋势线。图表上有了线之后,可能还想对它做些调整,这就需要用到几个专门的函数,line.set_width()是其中之一,它用于改变趋势线的粗细。
该函数在改变线条粗细之前,必须知道要修改哪条线,以及新的粗细是多少。标准语法格式如下:
line.set_width(id, width)
id参数指定要修改哪条线,值是line.new()函数返回的线条引用;width参数设置线条新的粗细,单位是像素。趋势线的最小粗细为1像素,设置的值小于1时自动按1像素处理;上限似乎没有——即使把粗细设为200,趋势线也能正常显示。
那么不同的像素值对应多粗的线条?下面是六条不同像素粗细的趋势线,可以给你一个直观的感受:

快速示例
假设我们想把一条趋势线的宽度设置为3像素,可以这样写:
// 新建一条趋势线
myLine = line.new(x1=bar_index[25], y1=close[25],
x2=bar_index, y2=close)
// 将该线的宽度修改为3像素
line.set_width(id=myLine, width=3)
这段代码先用line.new()画一条连接25根K线前收盘价和当前收盘价的趋势线,返回的引用存入myLine变量,之后就能随时引用并修改这条线。
接下来改变粗细:调用line.set_width(),用myLine变量指定要修改的线,width参数设为3,线就变成了3像素粗。
值得一提的是,代码中的关键字参数(如id=和width=)并非强制要求,示例里加它们只是为了让意图更清晰。下面这种写法也完全有效:
// 新建一条趋势线
myLine = line.new(bar_index[25], close[25], bar_index, close)
// 将该线的宽度修改为3像素
line.set_width(myLine, 3)
示例脚本:用不同粗细的线画价格目标位
来看一个完整脚本,学习line.set_width()的实战用法。下面的指标寻找收盘价上穿20周期简单移动平均线(SMA)的K线。条件满足时,脚本基于当时的移动平均线价格,算出上涨0.75%和1.5%的两个价格目标位。
我们用趋势线在图表上标出这两个目标位,并用line.set_width()函数改变它们的粗细。以下是指标的完整代码:
//@version=5
indicator(title="Trend line width example", overlay=true)
// 计算简单移动平均线
smaValue = ta.sma(close, 20)
// 在图表上绘制SMA
plot(smaValue, color=color.orange, linewidth=3)
// 判断价格是否收盘于SMA之上
crossAbove = barstate.isconfirmed and
ta.crossover(close, smaValue)
// 声明线段变量(以便后续访问历史线段)
var line firstTarget = na
var line secondTarget = na
// 当上穿发生时,绘制两个价格目标线
if crossAbove
// 确定基于SMA的价格目标位
targetOne = smaValue * 1.0075
targetTwo = smaValue * 1.015
// 在两个价格目标位上创建趋势线
firstTarget := line.new(x1=bar_index[1], y1=targetOne,
x2=bar_index, y2=targetOne, extend=extend.right,
color=color.green)
secondTarget := line.new(x1=bar_index[1], y1=targetTwo,
x2=bar_index, y2=targetTwo, extend=extend.right,
color=color.navy)
// 修改两条线的粗细
line.set_width(firstTarget, width=2)
line.set_width(secondTarget, width=5)
// 删除前一次绘制的线
line.delete(firstTarget[1])
line.delete(secondTarget[1])
首先用indicator()函数配置脚本的基本属性,然后用ta.sma()计算SMA,结果存入smaValue变量,再用plot()函数把它作为普通曲线画到图表上。
下一步判断价格是否上穿了移动平均线:
// 判断价格是否收盘于SMA之上
crossAbove = barstate.isconfirmed and
ta.crossover(close, smaValue)
这里同时检查两个条件。第一,K线必须已经走完(barstate.isconfirmed),避免在K线尚未收盘时产生不成熟的信号;第二,收盘价要上穿(ta.crossover())移动平均线。两个条件都满足时(and),crossAbove变量才为true,否则为false。
然后声明两个线段变量:
// 声明线段变量(以便后续访问历史线段)
var line firstTarget = na
var line secondTarget = na
这里创建了firstTarget和secondTarget两个线段变量,并用var关键字声明为持久性变量。为什么要在线实际画出来之前就声明?因为提前声明后,才能在后续K线上通过这两个变量访问之前创建的线段。不用var的话,变量在每根K线上都会重置,就引用不到历史的线条引用了。
脚本其余的核心代码都放在一个if语句块里,执行条件是crossAbove为true——没发生上穿,这部分代码就不运行。
if语句块的第一部分是计算价格目标:
// 确定基于SMA的价格目标位
targetOne = smaValue * 1.0075
targetTwo = smaValue * 1.015
接着仍在if语句块内,用line.new()函数创建两条趋势线:
// 在两个价格目标位上创建趋势线
firstTarget := line.new(x1=bar_index[1], y1=targetOne,
x2=bar_index, y2=targetOne, extend=extend.right,
color=color.green)
secondTarget := line.new(x1=bar_index[1], y1=targetTwo,
x2=bar_index, y2=targetTwo, extend=extend.right,
color=color.navy)
第一条趋势线画在第一个价格目标位上(价格由targetOne变量指定),连接前一根K线(bar_index[1])和当前K线。这本来只是一条一根K线长的短线,但extend.right参数把它向右无限延长了。
这样就得到一条长长的水平线。颜色设为绿色(color.green),line.new()返回的引用存入firstTarget变量。
第二条趋势线的创建方式类似:同样是连接前后两根K线的短线,画在第二个价格目标位(targetTwo)上,也向右延伸(extend.right),颜色为海军蓝(color.navy),引用存入secondTarget变量备用。
然后调整这两条线的粗细:
// 修改两条线的粗细
line.set_width(firstTarget, width=2)
line.set_width(secondTarget, width=5)
这里两次调用line.set_width():第一次把+0.75%价格目标线(firstTarget)的宽度增加到2像素,第二次把+1.5%价格目标线的宽度设为5像素。
最后一段代码负责清理图表上旧的趋势线:
// 删除前一次绘制的线
line.delete(firstTarget[1])
line.delete(secondTarget[1])
这个指标只需要显示最新一次上穿信号生成的价格目标位,之前的目标位已经失效。所以每当创建新线,就用line.delete()函数把上一次的线删掉。
获取旧线的引用要结合线段变量和历史操作符([]):firstTarget[1]和secondTarget[1]指向上一根K线上这两个变量的值,也就是旧线的引用。这样就能精确删除旧线,而保留当前新创建的线(引用存在当前的firstTarget和secondTarget里)。
来看看这个指标在图表上的最终效果:

如图所示,最近一次价格上穿移动平均线时,图表上出现了两条水平线,分别标记0.75%和1.5%的价格目标。由于加了线条宽度,它们在图表上非常醒目,难以忽视。
line.set_width()的特性
line.set_width()函数有几个值得注意的特性:
- 必须传入线条引用,否则函数不知道要修改哪条线。获得引用的唯一方法是把line.new()的返回值保存在变量里。没有引用,就无法修改已存在趋势线的宽度。
- 代码无法获取一条线当前的粗细,也就不能在现有粗细的基础上增加宽度。想知道线的粗细,唯一方法是通过line.set_width()为它明确设定一个值。
- line.set_width()只能修改当前脚本创建的趋势线,无法访问(也就无法修改)任何手动绘制的或其他脚本创建的线。
- 无法只让趋势线的一部分变粗,效果总是作用于整条线,包括无限延伸的部分。
- 即使(不小心)传入na值而不是有效的线条引用,line.set_width()也不会报错,但这时它也修改不了任何线的粗细。
- line.new()创建的线无法用鼠标手动修改,所以line.set_width()是加粗程序化绘制趋势线的唯一途径。
- 如果只需在创建时设定一次粗细,直接用line.new()函数自带的width参数即可,比先创建再修改的代码更少。
- line.set_width()没有返回值,不会返回成功或失败的状态,也不需要用变量去接收执行结果。
总结
用line.new()在图表上创建趋势线后,仍然可以调整它的粗细,这通过line.set_width()函数实现。该函数需要两个参数:第一个是线条引用,指定要修改哪条线;第二个是一个整数,代表以像素为单位的新粗细。线条最小粗细为1像素,且似乎没有上限。
当然,也可以在创建线条时直接设定粗细,在line.new()函数中使用width参数即可。


