Pine Script中ta.atr()参数类型错误及策略代码修复求助
问题背景
编写基于ATR的多空交易策略,策略条件如下:
- 多头条件:
- 价格涨幅≥30%
- 最近至少7根K线的ATR<5%
- 前一根K线收盘价在10周期EMA上方
- 前一根K线ATR>5%
- 空头条件:
- 价格跌幅≥30%
- 最近至少7根K线的ATR<5%
- 前一根K线收盘价在10周期EMA下方
- 前一根K线ATR>5%
原始代码运行时出现错误:
Cannot call 'ta.atr' with argument 'length'='i'. An argument of 'series int' type was used but a 'simple int' is expected.
错误出现在循环中调用ta.atr(i)的语句。
错误原因
ta.atr()函数的length参数要求是简单整数(simple int),但循环变量i属于序列整数(series int),Pine Script不允许用序列值作为该参数。此外,原始代码的循环逻辑无法正确实现“最近至少7根K线满足条件”的要求,且未对齐策略中“前一根K线”的条件。
修复后的代码
//@version=5 strategy(title="ATR-based Long/Short Trading Strategy", overlay=true) // Input variables length = input.int(title="ATR Lookback Length", defval=7, minval=1) atrLength = input.int(title="ATR Length", defval=10, minval=1) atrPercent = input.float(title="ATR Percent", defval=5, minval=1, maxval=50) / 100 // 计算1周期ATR(真实波幅),生成序列值 atr_1 = ta.atr(1) // 计算ATR的移动均线 atr_ma = ta.sma(atr_1, atrLength) // 计算length周期内的价格变化率 priceChange = (close - close[length]) / close[length] * 100 // 前一根K线的条件判断 price_above_ema_prev = close[1] > ta.ema(close, 10) atr_break_prev = atr_1[1] > atr_ma * atrPercent // 统计连续满足ATR<设定比例的K线数量 var int count_valid_atr = 0 if atr_1 < atr_ma * atrPercent count_valid_atr := count_valid_atr + 1 else count_valid_atr := 0 // 确认连续达标K线数达到要求 all_bars_atr_valid = count_valid_atr >= length // 多头开仓条件 buy_condition = (priceChange >= 30) and all_bars_atr_valid and price_above_ema_prev and atr_break_prev // 空头开仓条件 sell_condition = (priceChange <= -30) and all_bars_atr_valid and (not price_above_ema_prev) and atr_break_prev // 执行交易 if buy_condition strategy.entry("Long", strategy.long) if sell_condition strategy.entry("Short", strategy.short)
关键修复说明
修正ATR历史值获取:
先计算每根K线的1周期ATR序列(atr_1 = ta.atr(1)),后续通过atr_1[i]引用历史K线的ATR值,避免直接在循环中调用ta.atr(i)导致的类型不匹配。修复连续K线条件逻辑:
用count_valid_atr变量统计连续满足ATR条件的K线数量,当计数≥设定的length时,判定“最近至少N根K线达标”,替代原始循环中错误的终止逻辑。对齐“前一根K线”策略要求:
将收盘价和ATR的判断对象改为前一根K线(close[1]、atr_1[1]),符合策略条件的描述。修正空头条件4的逻辑错误:
原始代码中错误使用not atr_break,改为和多头条件4一致的atr_break_prev,匹配策略中“前一根K线ATR>5%”的要求。
内容的提问来源于stack exchange,提问作者Long token

