Pine Script v4/v5 平滑循环RSI添加EMA信号线报错修复
问题背景
尝试在v4版本循环平滑RSI(Cyclic Smoothed RSI)指标上添加带平滑线的EMA信号指标,所用EMA代码为Pine Script v5版本,将EMA代码降级适配v4后运行出现报错:
Syntax error: Arguments of input function must be of constant type, or 'source' builtin variables.
若直接将代码升级到v5版本,又会出现iff()函数相关报错:
line 44: Could not find function or function reference 'iff'.
原v4版本代码如下:
//@version=4 study(title="Smoothed Cyclic RSI with EMA", shorttitle="cRSI-EMA") src = close domcycle = input(20, minval=10, title="Dominant Cycle Length") crsi = 0.0 cyclelen = domcycle / 2 vibration = 10 leveling = 10.0 cyclicmemory = domcycle * 2 //set min/max ranges? h1 = hline(30, color=color.silver, linestyle=hline.style_dashed) h2 = hline(50, color=color.silver, linestyle=hline.style_dashed) h3 = hline(70, color=color.silver, linestyle=hline.style_dashed) torque = 2.0 / (vibration + 1) phasingLag = (vibration - 1) / 2.0 up = rma(max(change(src), 0), cyclelen) down = rma(-min(change(src), 0), cyclelen) rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down) csrsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * nz(crsi[1]) lmax = -999999.0 lmin = 999999.0 for i = 0 to cyclicmemory - 1 by 1 if nz(csrsi[i], -999999.0) > lmax lmax := nz(csrsi[i]) lmax else if nz(csrsi[i], 999999.0) < lmin lmin := nz(csrsi[i]) lmin mstep = (lmax - lmin) / 100 aperc = leveling / 100 db = 0.0 for steps = 0 to 100 by 1 testvalue = lmin + mstep * steps above = 0 below = 0 for m = 0 to cyclicmemory - 1 by 1 below := below + iff(crsi[m] < testvalue, 1, 0) below ratio = below / cyclicmemory if ratio >= aperc db := testvalue break else continue ub = 0.0 for steps = 0 to 100 by 1 testvalue = lmax - mstep * steps above = 0 for m = 0 to cyclicmemory - 1 by 1 above := above + iff(crsi[m] >= testvalue, 1, 0) above ratio = above / cyclicmemory if ratio >= aperc ub := testvalue break else continue fill(h1, h2, color=color.silver, transp=90) plot(csrsi, "CS-RSI", color.fuchsia) //EMA with Signal //Inputs len = input(9, minval=1, title="Length") esrc = input(csrsi, title="Source") smoothingLength = input(title = "Length", defval = 5, minval = 1, maxval = 100, group="Smoothing") offset = input(title="Offset", defval=0, minval=-500, maxval=500) //Calculation out = ema(esrc, len) smoothingLine = sma(out, smoothingLength) //Plotting plot(out, title="EMA", color=color.green, offset=offset) plot(smoothingLine, title="Smoothing Line", color=color.red, offset=offset, display=display.none)
报错原因
- v4版本input报错:Pine Script中
input()函数的默认值仅支持常量或内置行情源变量(如close/open等),原代码直接将动态计算得到的自定义序列csrsi作为input默认值,不符合语法规则。 - v5版本iff报错:Pine Script v5已正式移除
iff()函数,统一使用三元运算符实现等价条件判断逻辑。 - 隐藏逻辑bug:原代码计算高低位阈值的循环中,错误引用了未赋值的
crsi变量,且相位滞后参数计算结果为浮点数,作为K线索引引用时会触发类型报错。
修复后可运行v5版本代码
//@version=5 indicator(title="Smoothed Cyclic RSI with EMA", shorttitle="cRSI-EMA", overlay=false) src = close domcycle = input.int(20, minval=10, title="Dominant Cycle Length") crsi = 0.0 cyclelen = domcycle / 2 vibration = 10 leveling = 10.0 cyclicmemory = domcycle * 2 h1 = hline(30, color=color.silver, linestyle=hline.style_dashed) h2 = hline(50, color=color.silver, linestyle=hline.style_dashed) h3 = hline(70, color=color.silver, linestyle=hline.style_dashed) torque = 2.0 / (vibration + 1) phasingLag = math.round((vibration - 1) / 2.0) up = ta.rma(math.max(ta.change(src), 0), cyclelen) down = ta.rma(-math.min(ta.change(src), 0), cyclelen) rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down) csrsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * nz(crsi[1]) lmax = -999999.0 lmin = 999999.0 for i = 0 to cyclicmemory - 1 by 1 if nz(csrsi[i], -999999.0) > lmax lmax := nz(csrsi[i]) if nz(csrsi[i], 999999.0) < lmin lmin := nz(csrsi[i]) mstep = (lmax - lmin) / 100 aperc = leveling / 100 db = 0.0 for steps = 0 to 100 by 1 testvalue = lmin + mstep * steps below = 0 for m = 0 to cyclicmemory - 1 by 1 below := below + (csrsi[m] < testvalue ? 1 : 0) ratio = below / cyclicmemory if ratio >= aperc db := testvalue break ub = 0.0 for steps = 0 to 100 by 1 testvalue = lmax - mstep * steps above = 0 for m = 0 to cyclicmemory - 1 by 1 above := above + (csrsi[m] >= testvalue ? 1 : 0) ratio = above / cyclicmemory if ratio >= aperc ub := testvalue break fill(h1, h2, color=color.new(color.silver, 90)) plot(csrsi, "CS-RSI", color=color.new(color.fuchsia, 0)) //EMA with Signal //Inputs len = input.int(9, minval=1, title="EMA Length") smoothingLength = input.int(title = "Smoothing Length", defval = 5, minval = 1, maxval = 100, group="Smoothing") offset = input.int(title="Offset", defval=0, minval=-500, maxval=500) //Calculation out = ta.ema(csrsi, len) smoothingLine = ta.sma(out, smoothingLength) //Plotting plot(out, title="EMA", color=color.new(color.green, 0), offset=offset) plot(smoothingLine, title="Smoothing Line", color=color.new(color.red, 0), offset=offset, display=display.none)
关键修复点
- 全量适配v5语法:将
study替换为indicator,通用输入函数替换为类型明确的input.int,所有技术计算函数归入ta命名空间,颜色、透明度参数适配v5规范,删除循环中多余的无意义返回行。 - 解决input类型报错:删除原代码中错误的
esrc = input(csrsi, title="Source")行,由于EMA计算源固定为csrsi,无需额外提供源选择输入,直接将csrsi传入EMA计算函数即可,从根源规避input参数类型限制。 - 解决iff函数报错:将所有
iff(cond, val1, val2)写法替换为等价三元运算符cond ? val1 : val2,符合v5语法要求。 - 修复隐藏逻辑问题:将循环中错误引用的未赋值变量
crsi统一替换为计算完成的csrsi序列;对phasingLag增加取整逻辑,保证K线索引为整数,避免历史值引用报错。
内容的提问来源于stack exchange,提问作者Krishnendu Bhattacharyya
相关产品推荐
相关产品推荐

