Pine Script新手求助:Nadaraya-Watson Envelope策略无输出且条件不更新
问题描述
本人是Pine Script新手,尝试基于Nadaraya-Watson Envelope编写交易策略,但策略测试器无输出。我希望通过布尔变量
envelopeCondition判断收盘价是否在通道外,进而执行开平仓逻辑,但该变量似乎无法更新。
用户提供的原始代码:
//@version=5 strategy("Envelope", overlay=true, initial_capital =1000, default_qty_value =100, default_qty_type = strategy.percent_of_equity) bool envelopeCondition = false length = input.float(500,'Window Size',maxval=500,minval=0) h = input.float(8.,'Bandwidth') mult = input.float(3.) src = input.source(close,'Source') up_col = input.color(#39ff14,'Colors',inline='col') dn_col = input.color(#ff1100,'',inline='col') disclaimer = input(false, 'Hide Disclaimer') n = bar_index var k = 2 var upper = array.new_line(0) var lower = array.new_line(0) if barstate.isfirst for i = 0 to length/k-1 array.push(upper,line.new(na,na,na,na)) array.push(lower,line.new(na,na,na,na)) line up = na line dn = na cross_up = 0.`your text` cross_dn = 0.`your text` if barstate.islast y = array.new_float(0) sum_e = 0. for i = 0 to length-1 sum = 0. sumw = 0. for j = 0 to length-1 w = math.exp(-(math.pow(i-j,2)/(h*h*2))) sum += src[j]*w sumw += w y2 = sum/sumw sum_e += math.abs(src[i] - y2) array.push(y,y2) mae = sum_e/length*mult for i = 1 to length-1 y2 = array.get(y,i) y1 = array.get(y,i-1) up := array.get(upper,i/k) dn := array.get(lower,i/k) if src[i] > y1 + mae and src[i+1] < y1 + mae envelopeCondition := false if src[i] < y1 - mae and src[i+1] > y1 - mae envelopeCondition := true if envelopeCondition strategy.entry("Long",strategy.long) else strategy.close("Long") plot(na)
错误分析
barstate.islast的致命误用:你把通道计算、envelopeCondition更新逻辑全放在barstate.islast块里,这个条件仅在图表最后一根K线触发。策略测试器需要逐根K线计算交易信号,前面所有K线根本不会执行这些逻辑,envelopeCondition始终是初始的false,导致策略只会持续平仓,没有开仓信号,测试器自然无输出。- 语法错误:代码中
cross_up = 0.your text和`cross_dn = 0.`your text是无效语法,直接导致编译失败,这也是策略无法运行的核心原因之一。 - 通道计算逻辑脱节:双重循环计算拟合值的逻辑仅在最后一根K线执行,无法为每根K线生成对应的通道上下轨,无法基于实时价格生成交易信号。
修正后的代码
//@version=5 strategy("Nadaraya-Watson Envelope Strategy", overlay=true, initial_capital=1000, default_qty_value=100, default_qty_type=strategy.percent_of_equity) // 输入参数 length = input.int(500, 'Window Size', maxval=500, minval=10) h = input.float(8., 'Bandwidth') mult = input.float(3.) src = input.source(close, 'Source') up_col = input.color(#39ff14, 'Upper Band Color') dn_col = input.color(#ff1100, 'Lower Band Color') // 存储历史拟合值和MAE的变量 var float[] y_values = array.new_float() var float mae = na // 当K线数量满足窗口长度时,计算拟合值和MAE if bar_index >= length - 1 y = array.new_float() sum_e = 0. // 计算Nadaraya-Watson拟合值 for i = 0 to length - 1 sum = 0. sumw = 0. for j = 0 to length - 1 w = math.exp(-(math.pow(i - j, 2) / (h * h * 2))) sum += src[j] * w sumw += w y2 = sum / sumw array.push(y, y2) sum_e += math.abs(src[i] - y2) // 存储最新拟合值并计算MAE array.clear(y_values) array.push(y_values, array.get(y, length - 1)) mae := sum_e / length * mult // 获取当前K线的通道上下轨 current_y = array.size(y_values) > 0 ? array.get(y_values, 0) : na upper_band = current_y + mae lower_band = current_y - mae // 更新信号变量:价格跌破下轨时触发多单 envelopeCondition = not na(lower_band) and src < lower_band // 交易逻辑 if envelopeCondition strategy.entry("Long", strategy.long) else strategy.close("Long") // 绘制通道便于验证 plot(upper_band, color=up_col, title="Upper Envelope") plot(lower_band, color=dn_col, title="Lower Envelope")
关键修改说明:
- 移除
barstate.islast限制,确保每根符合窗口长度的K线都会计算通道值 - 删除无效的
cross_up/cross_dn错误代码,修复编译问题 - 调整
envelopeCondition逻辑为实时价格判断(可根据需求修改开平仓触发条件) - 添加通道绘图代码,方便可视化验证信号是否正确
内容的提问来源于stack exchange,提问作者Halosydnus
相关产品推荐
相关产品推荐

