取整到整十位
Pine Script 有几个函数可以对数值进行取整。这些函数利用数值的小数部分将其取整为整数。例如,将 42.80 变为 43。
但如果我们想将数值取整到整十位呢?这将使得 42.80 变为 40,87.1 变为 90。通过这种方式,我们可以将计算出的仓位大小取整到最接近的整十股,或者以整十为单位输出数值,以方便阅读。
有三种方法可以实现取整到十位。让我们来逐一了解。
四舍五入到整十位
第一种方法是进行四舍五入。当个位数字为5或更高时,我们向上取整;否则向下取整。这样,128.9 会变为 130,而 203 则会被取整为 200。
下面的这个小函数可以将数值四舍五入到最接近的整10位:
// RoundToTens() 函数将指定的值四舍五入到
// 最近的整十位。
RoundToTens(value) =>
math.round(value / 10.0) * 10
这个 RoundToTens() 函数有一个参数 value。在函数内部,我们首先将该参数除以 10.0。(如果我们用整数10相除,Pine Script 会舍弃小数部分,因此我们使用 10.0。)这样做会将小数点(.)向左移动一位。例如,56 会变为 5.6。
然后,我们使用 Pine Script 的 math.round() 函数将该数字取整为整数,这会使 5.6 变为 6。之后,我们再乘以10,将小数点向右移回一位。最终的结果是一个与原始参数数量级相同的值。
要使用该函数,我们只需用一个数值作为其参数来调用它即可。例如:
RoundToTens(2532) // 2530
RoundToTens(-9.75) // -10
取整范例
以下是更多的示例数字以及 RoundToTens() 返回的取整结果:
| 原始值 | 四舍五入到十位 |
|---|---|
| 3 | 0 |
| 21 | 20 |
| 49 | 50 |
| 101 | 100 |
| 2532 | 2530 |
| 0.01 | 0 |
| -0.01 | 0 |
| -3.6 | 0 |
| -9.75 | -10 |
| -28 | -30 |
| -456 | -460 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
当我们取整到十位时,取整后的值可能变大(例如 49 变为 50),也可能变小(例如 -456 变为 -460)。
向上取整到整十位
第二种方法是始终向上取整到整十位。这会使得 42 和 48 都变为 50。
下面的自定义 Pine Script 函数演示了如何实现这一点:
// RoundToTensUp() 函数将指定的值向上取整到下一个
// 整数十 (10s) 值。
RoundToTensUp(value) =>
math.ceil(value / 10.0) * 10
这个 RoundToTensUp() 函数同样只有一个数值参数(value)。在函数内部,我们首先除以 10.0 来移动小数点,然后使用 Pine Script 的 math.ceil() 函数向上取整为整数,最后再乘以10,以恢复到与函数参数相同的数量级。
要使用这个函数,我们用一个数值调用它,像这样:
RoundToTensUp(2532) // 2540
RoundToTensUp(-9.75) // 0
取整范例
以下是 RoundToTensUp() 函数对其他一些示例值的返回结果:
| 原始值 | 向上取整到十位 |
|---|---|
| 3 | 10 |
| 21 | 30 |
| 49 | 50 |
| 101 | 110 |
| 2532 | 2540 |
| 0.01 | 10 |
| -0.01 | 0 |
| -3.6 | 0 |
| -9.75 | 0 |
| -28 | -20 |
| -456 | -450 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
当我们向上取整到十位时,取整后的值总是会变大。也就是说,正数变得更大(例如101变为110),负数则更接近0(例如-28变为-20)。
向下取整到整十位
第三种也是最后一种方法是,始终向下取整到最接近的整十位。这会使得 22 和 28 都变为 20。
当我们在计算仓位大小时,这种方法能确保我们的风险不会超过设定的最大风险水平。
下面的这个小型 Pine Script 函数可以将数值向下取整到整十位:
// RoundToTensDown() 函数将指定的值向下取整到下一个
// 整数十 (10s) 值。
RoundToTensDown(value) =>
math.floor(value / 10.0) * 10
在 RoundToTensDown() 函数内部,我们首先将 value 参数除以 10.0,这一步会移动小数点一个位置。然后,我们使用 Pine Script 的 math.floor() 函数向下取整。最后,我们将该结果乘以10,以便将小数点移回其原始位置。
以下是如何使用该函数:
RoundToTensDown(2532) // 2530
RoundToTensDown(-9.75) // -10
取整范例
以下是 RoundToTensDown() 函数对其他各种值的返回结果:
| 原始值 | 向下取整到十位 |
|---|---|
| 3 | 0 |
| 21 | 20 |
| 49 | 40 |
| 101 | 100 |
| 2532 | 2530 |
| 0.01 | 0 |
| -0.01 | -10 |
| -3.6 | -10 |
| -9.75 | -10 |
| -28 | -30 |
| -456 | -460 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
当我们向下取整到十位时,取整后的值总是会变小。对于正数,其值会变小(例如49变为40)。对于负数,其值也会变小、离0更远(例如-3.6变为-10)。
脚本范例
现在,让我们看看这些自定义的取整函数在 TradingView 脚本中是如何运作的。下面的指标会绘制一个指数移动平均线(EMA),然后我们使用 RoundToTens() 函数将该平均值四舍五入到最接近的整十位。
该脚本的完整代码如下:
//@version=5
indicator(title="Round to tens example", overlay=true)
// RoundToTens() 函数将指定的值四舍五入到
// 最近的整十位。
RoundToTens(value) =>
math.round(value / 10.0) * 10
// 计算并绘制一个指数移动平均线
emaValue = ta.ema(close, 20)
plot(emaValue, color=color.orange, linewidth=2, title="EMA")
// 显示四舍五入到十位的EMA
plot(RoundToTens(emaValue), color=color.teal, linewidth=3,
title="EMA Rounded to Tens")
这个指标首先通过 indicator() 函数定义其脚本设置,用于命名该脚本并将其叠加显示在主图的交易品种上。
然后,我们把 RoundToTens() 函数加入脚本。(我们当然也可以在这里使用 RoundToTensDown() 或 RoundToTensUp() 函数。)
接下来,我们使用 Pine Script 的 ta.ema() 函数计算 EMA。我们将这个20周期的平均值存储在 emaValue 变量中。
然后我们用 plot() 函数绘制这个变量。由于没有设置绘图类型,Pine Script 会默认创建一个标准的常规线图。这条线以橙色(color.orange)显示,并且比正常更粗(linewidth=2)。
之后,我们创建另一个绘图。这个绘图显示的是取整到整十位的平均值。因此,我们调用 RoundToTens() 函数并传入 emaValue 变量。这条线以青色(color.teal)显示。
该指标在图表上看起来是这样的:
从图中我们可以看到,当布伦特原油 CFD (Brent Oil CFD) 的移动平均线越过55时,取整到十位的值从50跳升到60。当平均线突破65时,也发生了类似的情况。
总结
- 要实现取整到整十位,我们首先将待取整的数值除以10.0,然后对结果进行取整,最后再乘以10。
- 我们所使用的取整函数,决定了最终是进行四舍五入(
math.round()函数的功能)、始终向上取整(math.ceil()函数的功能),还是始终向下取整(math.floor()函数的功能)。
取整到整百位
Pine Script 提供了几种对数值进行取整的方法。标准的取整函数会处理数值的小数部分,将其变为整数。例如,将 842.90 变为 843,将 372.25 变为 372。
但如果我们想将数值取整到整百位呢?这将使得 842 变为 800,372 转换为 400。通过这种方式,我们可以将计算出的仓位大小向下取整到最接近的整百股,或者以整百为单位显示成交量,以方便阅读。
有三种不同的方法可以实现取整到百位。让我们来逐一探讨:
四舍五入到整百位
第一种选择是进行四舍五入。当小数点(.)前的最后两位数字为50或更高时,我们向上取整;否则向下取整。这将使得 363 变为 400,348.7 变为 300。
下面的这个自定义函数可以将数值四舍五入到最接近的整100位:
// RoundToHundreds() 函数将指定的值四舍五入到
// 最近的整百位。
RoundToHundreds(value) =>
math.round(value / 100.0) * 100
这个 RoundToHundreds() 函数有一个参数 value。在函数内部,我们首先将该参数除以 100.0。(如果我们用整数100相除,Pine Script 会舍弃小数部分,因此我们使用 100.0。)这样做会将小数点(.)向左移动两位。例如,520 会变为 5.20。
然后,我们使用 Pine Script 的 math.round() 函数将该数字取整为整数,这会使 5.20 变为 5。之后,我们再乘以100,将小数点向右移回两位。最终的结果是一个与原始参数数量级相同的值。
要使用该函数,我们只需用一个数值或变量来调用它即可。例如:
RoundToHundreds(102) // 100
RoundToHundreds(190.95) // 200
RoundToHundreds(983) // 1000
取整范例
以下是 RoundToHundreds() 函数对其他一些值的返回结果:
| 原始值 | 四舍五入到百位 |
|---|---|
| 3 | 0 |
| 75 | 100 |
| 102 | 100 |
| 190.95 | 200 |
| 983 | 1000 |
| 4312 | 4300 |
| 0.01 | 0 |
| -0.01 | 0 |
| -4.2 | 0 |
| -8.75 | 0 |
| -329 | -300 |
| -992 | -1000 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
从表中我们可以看出,当我们取整到百位时,取整后的值可能变大(例如 983 变为 1000),也可能变小(例如 102 变为 100)。
向上取整到最接近的整百位
另一种方法是始终向上取整到下一个整百位。这样,620 和 673 都会变为 700。
下面的自定义函数实现了所需的代码:
// RoundToHundredsUp() 函数将指定的值向上取整到下一个
// 整数百 (100s) 值。
RoundToHundredsUp(value) =>
math.ceil(value / 100.0) * 100
这个 RoundToHundredsUp() 函数同样只有一个参数(value)。在函数内部,我们首先除以 100.0 来移动小数点,接着使用 Pine Script 的 math.ceil() 函数向上取整为整数,然后我们再乘以100,以恢复到与函数参数相同的数量级。
要使用这个函数,我们用一个数调用它,像这样:
RoundToHundredsUp(102) // 200
RoundToHundredsUp(190.95) // 200
RoundToHundredsUp(983) // 1000
取整范例
以下是 RoundToHundredsUp() 函数对其他值的返回结果:
| 原始值 | 向上取整到百位 |
|---|---|
| 3 | 100 |
| 75 | 100 |
| 102 | 200 |
| 190.95 | 200 |
| 983 | 1000 |
| 4312 | 4400 |
| 0.01 | 100 |
| -0.01 | 0 |
| -4.2 | 0 |
| -8.75 | 0 |
| -329 | -300 |
| -992 | -900 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
如上所示,取整后的值总是会变大。也就是说,一个像 102 这样的正数会被取整为 200。而像 -329 这样的负数则会更接近0(变为-300)。
向下取整到最接近的整百位
第三种也是最后一种方法是,始终向下取整到最接近的整百位。这会使得 119 和 189 都变为 100。
当我们在计算仓位大小时,这种方法能确保我们最终不会买入过多的股票。
下面的这个自定义函数可以将数值向下取整到下一个整百位:
// RoundToHundredsDown() 函数将指定的值向下取整到下一个
// 整百位。
RoundToHundredsDown(value) =>
math.floor(value / 100.0) * 100
在这个 RoundToHundredsDown() 函数内部,我们首先将 value 参数除以 100.0,这一步会移动小数点两个位置。然后,我们使用 Pine Script 的 math.floor() 函数向下取整。最后,我们将该结果乘以100,以便将小数点(.)移回其原始位置。
要使用该函数,只需用一个数值或变量来调用它即可。例如:
RoundToHundredsDown(102) // 100
RoundToHundredsDown(190.95) // 100
RoundToHundredsDown(983) // 900
取整范例
以下是 RoundToHundredsDown() 函数对其他各种值的返回结果:
| 原始值 | 向下取整到百位 |
|---|---|
| 3 | 0 |
| 75 | 0 |
| 102 | 100 |
| 190.95 | 100 |
| 983 | 900 |
| 4312 | 4300 |
| 0.01 | 0 |
| -0.01 | -100 |
| -4.2 | -100 |
| -8.75 | -100 |
| -329 | -400 |
| -992 | -1000 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
当我们向下取整到百位时,取整后的值总是更小或保持不变。对于正数,其值会变小(例如983变为900)。对于负数,其值也会变小、离0更远(例如-4.2取整为-100)。
脚本范例
现在,让我们在实践中使用这些自定义的取整函数。下面的指标会绘制一个简单移动平均线(SMA),然后 RoundToHundreds() 函数将该平均值四舍五入到最接近的整百位。
该脚本的完整代码如下:
//@version=5
indicator(title="Round to hundreds example", overlay=true)
// RoundToHundreds() 函数将指定的值四舍五入到
// 最近的整百位。
RoundToHundreds(value) =>
math.round(value / 100.0) * 100
// 计算并绘制一个简单移动平均线
smaValue = ta.sma(close, 20)
plot(smaValue, color=color.silver, linewidth=2, title="SMA")
// 显示四舍五入到百位的平均值
plot(RoundToHundreds(smaValue), color=color.navy,
linewidth=3, title="SMA Rounded to Hundreds")
我们首先通过 indicator() 函数来定义指标的设置,用于命名该脚本并将其叠加显示在主图的交易品种上。
然后,我们插入了上面讨论过的自定义 RoundToHundreds() 函数。(当然,我们也可以在这里使用 RoundToHundredsDown() 或 RoundToHundredsUp() 函数。)
接下来,我们使用 Pine Script 的 ta.sma() 函数计算 SMA。我们将这个20周期的平均值存储在 smaValue 变量中。然后 plot() 函数将该变量的值显示在图表上。由于没有设置绘图类型,Pine Script 会默认创建一个常规的线图。这条线以银灰色(color.silver)显示。
之后我们创建另一个绘图。这个绘图显示的是取整到整百位的平均值。为了得到这个值,我们用 smaValue 变量调用 RoundToHundreds() 函数。这条实线以海军蓝(color.navy)显示。
该指标在图表上看起来是这样的:
如此 Tesla 图表所示,一旦移动平均线上涨超过450,取整后的平均值便从400跳升至500的水平。当平均线相继越过550和650时,也发生了类似的情况。
总结
- 要实现取整到整百位,我们首先将待取整的数值除以100.0,然后对结果进行取整,最后再乘以100。
- 我们所使用的取整函数,决定了最终是进行四舍五入(
math.round()函数的功能)、始终向上取整(math.ceil()函数的功能),还是始终向下取整(math.floor()函数的功能)。
取整到整千位
Pine Script 有几个函数可以对数值进行取整。它们会处理数值的小数部分,将其转换为整数。例如,将 12.50 变为 13。
但如果我们想将数值取整到整千位呢?这将使得 450 变为 1000,2234 变为 2000。这对于绘制成交量是一种有用的方式。或者,在交易低价加密货币时,将仓位大小取整到最接近的千位。
有三种不同的方法可以实现取整到千位。让我们来逐一探讨:
四舍五入到整千位
我们可以采取的第一种方法是进行四舍五入。当小数点(.)前的最后三位数字为500或更高时,我们向上取整;否则向下取整。这将使得 4680 变为 5000,8230 变为 8000。
下面的这个自定义函数可以将数值四舍五入到最接近的整千位:
// RoundToThousands() 函数将指定的数值向上或向下舍入到
// 最近的整千位。
RoundToThousands(value) =>
math.round(value / 1000.0) * 1000
这个 RoundToThousands() 函数有一个参数:value。在函数内部,我们首先将该数值除以 1000.0。(如果使用整数除法,Pine Script 会舍弃小数部分,因此我们使用 1000.0。)这个除法运算会将小数点(.)向左移动三位。这样,4375.82 就会变为 4.37582。
然后,我们使用 Pine Script 的 math.round() 函数将该值取整为整数。对于 4.37582,结果是 4。之后,我们再乘以1000,以便将小数点向右移回三位。该函数的结果是一个与原始参数数量级相同的取整值。
要使用该函数,我们只需用一个数值或变量来调用它即可。例如:
RoundToThousands(2285) // 2000
RoundToThousands(9982) // 10000
RoundToThousands(-2010.01) // -2000
取整范例
以下是 RoundToThousands() 函数对其他一些值的返回结果:
| 原始值 | 四舍五入到千位 |
|---|---|
| 5.25 | 0 |
| 275 | 0 |
| 980 | 1000 |
| 2285 | 2000 |
| 9982 | 10000 |
| 0.01 | 0 |
| -0.01 | 0 |
| -25 | 0 |
| -689 | -1000 |
| -41260 | -41000 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
从表中我们可以看出,当我们四舍五入到千位时,取整后的值可能变大(例如 980 变为 1000),也可能变小(例如 2285 变为 2000)。
向上取整到整千位
第二种方法是始终向上取整到下一个整千位。这将使得 2104.5 和 2900 都被取整为 3000。
下面的 Pine Script 函数可以实现这种取整:
// RoundToThousandsUp() 函数将指定的数值向上取整到下一个
// 整数千 (1000s) 值。
RoundToThousandsUp(value) =>
math.ceil(value / 1000.0) * 1000
这个 RoundToThousandsUp() 函数同样只有一个参数(value)。在函数内部,我们首先除以 1000.0 来移动小数点。然后使用 Pine Script 的 math.ceil() 函数将结果向上取整为整数。我们之后再乘以1000,以恢复到原始的数量级。
以下是如何调用这个函数:
RoundToThousandsUp(2285) // 3000
RoundToThousandsUp(9982) // 10000
RoundToThousandsUp(-2010.01) // -2000
取整范例
以下是该函数对一些示例值的返回结果:
| 原始值 | 向上取整到千位 |
|---|---|
| 5.25 | 1000 |
| 275 | 1000 |
| 980 | 1000 |
| 2285 | 3000 |
| 9982 | 10000 |
| 0.01 | 1000 |
| -0.01 | 0 |
| -25 | 0 |
| -689 | 0 |
| -41260 | -41000 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
如表所示,当我们取整到下一个千位时,其值总是会变大。也就是说,像 2285 这样的正数会被取整为 3000。而像 -689 这样的负数在被取整为 0 后,就不再是负数了。
向下取整到整千位
第三种方法是始终向下取整到最接近的整千位。这将使得像 1200 和 1975.25 这样的值都变为 1000。
下面的这个 Pine Script 自定义函数实现了这种取整:
// RoundToThousandsDown() 函数将指定的数值向下取整到下一个
// 整千位。
RoundToThousandsDown(value) =>
math.floor(value / 1000.0) * 1000
在 RoundToThousandsDown() 函数内部,我们首先将 value 参数除以 1000.0,这一步会移动小数点三个位置。然后,我们使用 Pine Script 的 math.floor() 函数向下取整。最后我们再乘以1000,以便将小数点移回其原始位置。
要使用该函数,我们只需用一个数值或变量来调用它即可。例如:
RoundToThousandsDown(2285) // 2000
RoundToThousandsDown(9982) // 9000
RoundToThousandsDown(-2010.01) // -3000
取整范例
以下是 RoundToThousandsDown() 函数对其他值的返回结果:
| 原始值 | 向下取整到千位 |
|---|---|
| 5.25 | 0 |
| 275 | 0 |
| 980 | 0 |
| 2285 | 2000 |
| 9982 | 9000 |
| 0.01 | 0 |
| -0.01 | -1000 |
| -25 | -1000 |
| -689 | -1000 |
| -41260 | -42000 |
| na | 错误;不能对 na 参数调用用户定义的函数。 |
| “1.83” | 错误;不能对字符串值调用此函数。 |
当我们向下取整到最近的整千位时,取整后的值总是更小或保持不变。对于正数,其值会变小(例如275变为0)。对于负数,其值也会变小、离0更远(例如-25取整为-1000)。
脚本范例
现在,让我们看看一个 TradingView 脚本是如何使用这些自定义取整函数的。下面的指标会绘制一个加权移动平均线(WMA),然后 RoundToThousands() 函数将该平均值取整到最接近的千位。
该脚本的完整代码如下:
//@version=5
indicator(title="Round to thousands example", overlay=true)
// RoundToThousands() 函数将指定的数值向上或向下舍入到
// 最近的整千位。
RoundToThousands(value) =>
math.round(value / 1000.0) * 1000
// 计算并绘制 WMA
wmaValue = ta.wma(close, 10)
plot(wmaValue, color=color.orange, linewidth=2, title="WMA")
// 绘制舍入到最近的千位的平均值
plot(RoundToThousands(wmaValue), color=color.fuchsia,
linewidth=3, title="WMA Rounded to Thousands")
首先,我们通过 indicator() 函数来配置指标的设置,用于命名该脚本并将其叠加显示在主图的交易品种上。
然后,我们引入了早先讨论过的 RoundToThousands() 函数。(当然,我们也可以在这里使用 RoundToThousandsUp() 或 RoundToThousandsDown() 函数;它们的用法是相同的。)
接下来,我们使用 Pine Script 的 ta.wma() 函数计算 WMA。我们将这个10周期的平均值存储在 wmaValue 变量中。然后 plot() 函数将该变量的值显示在图表上。由于没有设置绘图类型,Pine Script 会默认创建一个常规的线图。这条线以橙色(color.orange)显示。
之后我们创建第二个绘图。这个绘图显示的是取整到最接近的千位的平均值。因此,我们用 wmaValue 变量调用 RoundToThousands() 函数。这些值显示为一条紫红色(color.fuchsia)的线。
该指标在图表上看起来是这样的:
如此 Ethereum (ETH/USD) 期货图表所示,一旦平均线越过3500,取整后的值就从3000跳升至4000的水平。每当平均线移动到两个整数千位之间的中点之上时,都会发生类似的情况。
总结
- 要实现取整到整千位,我们首先将待取整的数值除以1000.0,然后对结果进行取整,最后再乘以1000。
- 我们所使用的取整函数,决定了最终是进行四舍五入(使用
math.round())、始终向上取整(使用math.ceil()),还是始终向下取整(使用math.floor())。
截断(truncation):直接切掉小数部分
Pine Script 可以通过多种方式对数字进行取整。其中一种选择是截断(truncation)。当我们截断一个数值时,该数字的小数部分会被直接移除 。换句话说,就是将数值的小数部分直接切掉,从而得到一个整数 。
截断操作会将 10.34 和 10.98 都变为 10,也会将 -4.75 和 -4.10 都转换为 -4。
有两种执行截断的方式:
- 截断为整数。
- 截断到指定的小数位数。
下面我们来逐一探讨。
截断为整数
Pine Script 的 int() 函数可以将一个浮点值截断为一个整数 。其原理是该函数会直接丢弃数值的小数部分。
int() 的默认语法格式如下 :
int(x)
x 指的是我们希望转换为整数的值。
要使用 int(),我们只需用希望截断的值来调用它即可。例如:
int(9.10) // 返回: 9
int(3.85) // 3
int(-1.97) // -1
int(-0.25) // 0
int(2) // 2
截断范例
为了更好地理解 int() 的截断方式,下表展示了该函数对一些示例值的返回结果:
| 原始值 | int() 截断后的值 |
|---|---|
| 5.92991 | 5 |
| 3.72 | 3 |
| 1.23 | 1 |
| 0.00002 | 0 |
| 0.000 | 0 |
| -0.00009 | 0 |
| -1.12 | -1 |
| -4.75 | -4 |
| -9.8953 | -9 |
| na | na |
| “1.83” | 错误;不能对字符串值调用 int()。 |
从表中我们可以看出,int() 既不向上也不向下取整,而是直接删除数值的小数部分。这就是 -9.8953 被截断为 -9,以及 1.23 变为 1 的原因。
脚本范例
让我们在一个完整的脚本中使用 int()。下面的指标会绘制一条指数移动平均线及其被截断后的版本。我们将使用 Pine Script 的标签来精确展示这两个值的差异。该指标的完整代码如下:
//@version=5
indicator(title="Truncate to whole number example", overlay=true)
// 计算45周期的指数移动平均线及其
// 截断后的整数版本
emaValue = ta.ema(close, 45)
emaTruncated = int(emaValue)
// 绘制EMA及其截断值
plot(emaValue, color=color.teal, linewidth=2, title="EMA")
plot(emaTruncated, color=color.orange, linewidth=2,
title="EMA Truncated")
// 每30根K线,用一个文本标签显示EMA及其截断值
if bar_index % 30 == 0
label.new(x=bar_index, y=emaValue, color=color.black,
textcolor=color.white,
text="EMA: " + str.tostring(emaValue, "0.000") +
"\nTruncated: " + str.tostring(emaTruncated, "0.000"))
这个指标首先通过 indicator() 函数来配置其设置,用于命名该脚本并将其叠加显示在主图的交易品种上。
接着,ta.ema() 函数计算45周期的指数移动平均线 (EMA)。我们将这个平均值存储在 emaValue 变量中。然后,我们使用 int() 函数将其截断为整数,并将结果存储在 emaTruncated 变量中。
下一步,plot() 函数在图表上显示这些值。EMA 以青色 (color.teal) 显示,而被截断的值则以橙色 (color.orange) 出现。由于我们没有明确指定绘图类型,Pine Script 默认会创建一个常规的线图。
为了看清 EMA 及其截断值的差异,我们创建一个文本标签。但我们不在每一根K线上都创建,因为那样会让每个标签都难以阅读。因此,一个 if 语句会检查当前的K线编号(bar_index)是否为30的倍数。当取模运算符(%)返回0时,即为真。
如果条件成立,if 内的代码就会调用 label.new() 函数。这会在当前K线(bar_index)和移动平均线的值(emaValue)所在的位置创建一个标签。其背景为黑色(color.black),文字为白色(color.white)。
标签的文本内容是通过 + 运算符拼接起来的几个字符串片段。其中有字面字符串,也有通过 str.tostring() 函数将数值转换为文本的动态内容。我们正是通过这种方式在标签文本中显示 EMA 及其截断值的。
在图表上,该指标会绘制移动平均线和截断后的值。每隔一段K线,一个文本标签就会显示这两条绘图线的精确数值:
(标签可能会显示在价格K线的后面。要让它们显示在前面,请将脚本的“视觉顺序”(Visual Order)设置为“置于顶层”(Bring to Front)。)
截断到指定的小数位数
另一种方法是截断到指定的小数位数。这会切掉超出特定数量的任何小数。
例如,这将 2.99 变为 2.9,也可以将 6.2092 变为 6.20。
自定义函数
目前,Pine Script 没有内置函数可以实现按小数位数进行截断。但没关系,我们可以自己创建一个:
// Truncate() 函数将给定的数值截断到指定的
// 小数位数。
Truncate(number, decimals) =>
factor = math.pow(10, decimals)
int(number * factor) / factor
这个自定义的 Truncate() 函数有两个参数:一个是需要被截断的值(number),另一个是说明结果应保留多少位小数(decimals)。
在函数内部,我们首先将10进行 decimals 次幂的运算,这会得到一个修正因子,我们将用它来向右移动小数点(.)。
然后,在 int() 函数内部,我们将 number 值与 factor 变量相乘。这一步首先将小数点向右移动,然后 int() 将结果截断为整数。最后,我们将这个截断后的结果再除以 factor 变量,从而将小数点向左移回其原始位置。
让我们来看一个例子。假设我们想将 12.8934 截断到2位小数。当我们将10的2次幂时,得到100。它乘以输入值 12.8934 得到 1289.34。当我们用 int() 对该值进行截断时,得到 1289。最后我们再除以100,以恢复正确的数量级,这样就得到了 12.89 这个最终结果。
我们可以像这样使用这个自定义的 Truncate() 函数:
Truncate(12.89, 1) // 返回: 12.8
Truncate(1.209, 2) // 1.20
Truncate(383.7924, 0) // 383
截断范例
为了更好地理解该函数的返回值,下表将一些示例值截断到1位小数:
| 原始值 | 截断到1位小数 |
|---|---|
| 5.92991 | 5.9 |
| 3.72 | 3.7 |
| 1.23 | 1.2 |
| 0.00002 | 0.0 |
| 0.000 | 0.0 |
| -0.00009 | 0.0 |
| -1.12 | -1.1 |
| -4.75 | -4.7 |
| -9.8953 | -9.8 |
| na | 错误;不能对 na 参数调用函数。 |
| “1.83” | 错误;不能对字符串参数调用此函数。 |
自定义的 Truncate() 函数与四舍五入不同。它并非总是向上或向下取整,而是简单地切掉小数。这对数值符号的正负有不同的影响。
负数值(如-4.75)会变大(-4.7),因为舍弃小数部分对负数来说相当于向上取整;而正数值则会变小(1.23变为1.2),相当于向下取整。
脚本范例
让我们看看脚本如何使用 Truncate()。像上面一样,下面的脚本会绘制两个值:一个是简单移动平均线(SMA),另一个是该平均线被截断到指定小数位数后的值。
每隔一定数量的K线,我们会创建一个标签来显示平均线及其截断值的精确数值。
该指标的完整代码如下:
//@version=5
indicator(title="Truncate to decimals example", overlay=true)
// Truncate() 函数将给定的数值截断到指定的
// 小数位数。
Truncate(number, decimals) =>
factor = math.pow(10, decimals)
int(number * factor) / factor
// 创建一个输入来设置要截断到的小数位数
decimalAmount = input.int(1, title="Number of Decimals", minval=0)
// 计算简单移动平均线及其截断后的版本
smaValue = ta.sma(close, 20)
smaTruncated = Truncate(smaValue, decimalAmount)
// 绘制SMA及其截断值
plot(smaValue, color=color.purple, linewidth=2, title="SMA")
plot(smaTruncated, color=color.yellow, linewidth=2,
title="SMA Truncated")
// 每30根价格K线,创建一个标签来显示
// SMA值及其截断到小数后的版本
if bar_index % 30 == 0
label.new(x=bar_index, y=smaValue, style=label.style_label_up,
color=#f2f2f2, textcolor=color.black,
text="SMA: " + str.tostring(smaValue, "0.000") +
"\nTruncated: " + str.tostring(smaTruncated, "0.000"))
indicator() 函数首先配置指标的设置,用于为脚本命名并将其叠加显示在主图的交易品种上。
然后,我们引入了上面讨论过的自定义 Truncate() 函数。
接着,我们使用 input.int() 函数创建一个整数输入选项。这个输入的名称是 Number of Decimals。它用于指定 Truncate() 函数应使用的小数位数。我们为其设置了默认值为1,最小值为0。我们将这个输入值存储在 decimalAmount 变量中,之后可以通过访问该变量来获取输入的当前值。
然后,ta.sma() 函数计算20周期的收盘价(close)的简单移动平均线。我们将这个平均值存储在 smaValue 变量中。接着我们对该变量调用 Truncate() 函数,将其截断到由输入选项(decimalAmount)设置的小数位数。我们将截断后的值存入 smaTruncated 变量。
plot() 函数随后绘制 SMA 及其截断值。前者显示为一条紫色(color.purple)的线;后者则以黄色(color.yellow)显示。由于我们没有设置绘图类型,Pine Script 默认会为两者创建常规的线图。
最后一段代码是一个 if 语句。这个语句判断当前的K线编号(bar_index)是否为30的倍数。当它是时,K线编号对30取模(%)的结果等于(==)零。通过这种方式,if 语句可以每30根K线执行一次。
在 if 语句内部,label.new() 函数创建一个文本标签。这个绘图显示在当前K线(bar_index)的 SMA 值(smaValue)位置。其样式指向上方(label.style_label_up)。背景为浅灰色,通过十六进制颜色值 #f2f2f2 设置,其上的字母以黑色(color.black)显示。
标签的文本内容是通过 + 运算符拼接起来的几个字符串片段。其中两个是 str.tostring() 函数的调用。第一个将 SMA 的值转换为字符串,另一个则将截断后的值转换为文本。这使得两个数值都能与标签所需的字符串片段兼容。
在图表上,该脚本会显示移动平均线及其截断值。在其标准设置下,这些值被截断到1位小数:
如果我们把脚本的输入选项改为2,移动平均线就会被截断到两位小数。这会将标签更改为:
你可以亲自试用该脚本,看看它是如何运作的。(如果你将脚本添加到图表,标签可能会部分显示在价格K线的下方。要让标签显示在K线之上,请将脚本的“视觉顺序”(Visual Order)设置为“置于顶层”(Bring to Front)。)
截断与四舍五入的对比
截断与四舍五入(向上或向下取整)会产生不同的结果。当我们进行四舍五入时,我们会根据一个数的小数部分来决定是应该向上还是向下取整。但对于截断,我们不关心小数部分(只是直接扔掉它)。
- 当我们四舍五入时,我们将一个数转换为其最接近的整数。这将 2.8 变为 3,5.2 变为 5。小数部分为 .5 的值会被向上取整;低于此值的小数部分则会被向下舍去。
- 然而,截断是不同的。当我们截断时,我们移除一个数的小数部分。也就是说,我们切掉小数部分,从而得到一个整数。通过这种方式,2.8 变为 2,而 5.2 也被变为 5。
注意事项
看待这两者差异的另一种方式如下:当我们截断时,小数点(.)前的数值永远不会改变。但如果我们进行四舍五入,该值则可能向上或向下改变。
示例值对比
以下是四舍五入和截断操作对一些示例值的不同结果:
| 原始值 | 四舍五入为整数 (math.round()) | 截断为整数 (int()) |
|---|---|---|
| 5.92991 | 6 | 5 |
| 3.72 | 4 | 3 |
| 1.23 | 1 | 1 |
| 0.00002 | 0 | 0 |
| 0.000 | 0 | 0 |
| -0.00009 | 0 | 0 |
| -1.12 | -1 | -1 |
| -4.75 | -5 | -4 |
| -9.8953 | -10 | -9 |
| na | 0 | na |
| “1.83” | 错误;不能对字符串调用 math.round()。 |
错误;不能对字符串调用 int()。 |
如上所示,截断和四舍五入有时可以得到相同的结果。但这只发生在我们将一个正数向下取整时(例如 1.23 变为 1),以及我们将一个负数向上取整时(例如 -1.12 变为 -1)。在其他情况下,四舍五入和截断会得出不同的结果。
由于这些结果会根据数值的符号(正或负)而有所不同,截断操作能提供我们通过四舍五入无法实现的结果。
总结
- 当我们截断一个数时,我们是直接丢弃其小数部分。
- 与四舍五入不同,截断永远不会改变小数点(.)前的数值。
- 要截断为整数,我们使用 Pine Script 的
int()函数。 - 通过一个自定义函数,我们也可以截断到指定的小数位数。








