Pine Script交易时段高低点指标多周期运行报错排查
问题根因
两类报错来自同一处逻辑缺陷,和你设置的length参数最小值无关:
- 计算各时段回溯长度的
ta.barssince(not activeXxx)函数,在图表最前端的历史K线区间,如果还没出现过「对应时段未激活」的状态,会返回na空值,加1后仍为na,传入ta.highest/ta.lowest就会触发length为NaN的报错。 - 加载的K线周期越大(1小时、2小时等低于4小时的周期),单根K线覆盖的时间跨度越长,
ta.barssince需要往回查找的K线数量越容易超过Pine Script默认的max_bars_back阈值,触发回溯不足报错。 - 关闭亚洲时段、移除美洲/自定义时段代码能临时恢复运行,本质是减少了回溯计算的负载,降低了空值和超限的触发概率,没有解决根本问题。另外原代码里欧洲、美洲、自定义时段的非激活线条颜色误写为红色,会导致非交易时段错误显示线条。
修复点
对四个交易时段的逻辑统一做三处调整:
- 给每个时段的Lookback回溯长度加空值兜底:当
ta.barssince返回na时,直接用当前K线索引+1作为回溯长度,保证传入高低点计算函数的length永远是≥1的合法值。 - 显式给所有
ta.highest/ta.lowest调用指定max_bars_back=500,同时在指标声明处加全局max_bars_back配置,这个数值足够覆盖1分钟到3小时全周期的单时段最大K线跨度,不会触发回溯不足报错。 - 补全高低点重置逻辑:当交易时段从激活切换为未激活时,把对应存储高低点的变量重置为na,避免跨时段残留之前的数值。
- 抽离重复的星期校验逻辑为公共函数,减少冗余代码,同时修正非激活时段的线条颜色错误。
修复后完整代码
// This source code is subject to the terms of the Mozilla Public License 2.0 // © Hotchachachaaa //@version=5 indicator("session tma",overlay=true, max_bars_back=500) tz ="UTC" label = input.string( title="Label", defval="CME Open", tooltip="For easy identification", group = "Trade Session") tsAsia = input.bool( title="Show Asian Session", defval=true, group = "Asian Trade Session") startHourAsia = input.int( title="Asia Start hour", defval=0, minval=0, maxval=23, group = "Asian Trade Session") startMinuteAsia = input.int( title="Asia Start minute", defval=00, minval=0, maxval=59, group = "Asian Trade Session") endHour2Asia = input.int( title="Asia End hour", defval=8, minval=0, maxval=23, group = "Asian Trade Session") endMinute2Asia = input.int( title="Asia End minute", defval=0, minval=0, maxval=59, group = "Asian Trade Session") tsEurope = input.bool( title="Show European Session", defval=true, group = "European Trade Session") startHourEurope = input.int( title="Europen Start hour", defval=7, minval=0, maxval=23, group = "European Trade Session") startMinuteEurope = input.int( title="Europen Start minute", defval=00, minval=0, maxval=59, group = "European Trade Session") endHour2Europe = input.int( title="Europen End hour", defval=16, minval=0, maxval=23, group = "European Trade Session") endMinute2Europe = input.int( title="Europen End minute", defval=0, minval=0, maxval=59, group = "European Trade Session") tsAmericas = input.bool( title="Show American Session", defval=true, group = "American Trade Session") startHourAmericas = input.int( title="Americas Start hour", defval=12, minval=0, maxval=23, group = "American Trade Session") startMinuteAmericas = input.int( title="Americas Start minute", defval=00, minval=0, maxval=59, group = "American Trade Session") endHour2Americas = input.int( title="Americas End hour", defval=20, minval=0, maxval=23, group = "American Trade Session") endMinute2Americas = input.int( title="Americas End minute", defval=0, minval=0, maxval=59, group = "American Trade Session") tsCustom = input.bool( title="Show Custom Session", defval=true, group = "Custom Trade Session") startHourCustom = input.int( title="Custom Start hour", defval=16, minval=0, maxval=23, group = "Custom Trade Session") startMinuteCustom = input.int( title="Custom Start minute", defval=00, minval=0, maxval=59, group = "Custom Trade Session") endHour2Custom = input.int( title="Custom End hour", defval=20, minval=0, maxval=23, group = "Custom Trade Session") endMinute2Custom = input.int( title="Custom End minute", defval=0, minval=0, maxval=59, group = "Custom Trade Session") showMon = input(title="Monday", defval=true, group = "Trade Session") showTue = input(title="Tuesday", defval=true, group = "Trade Session") showWed = input(title="Wednesday", defval=true, group = "Trade Session") showThu = input(title="Thursday", defval=true, group = "Trade Session") showFri = input(title="Friday", defval=true, group = "Trade Session") showSat = input(title="Saturday", defval=false, group = "Trade Session") showSun = input(title="Sunday", defval=false, group = "Trade Session") tzYear = year(time, tz) tzMonth = month(time, tz) tzDay = dayofmonth(time, tz) tzDayOfWeek = dayofweek(time, tz) displayBG = input.bool(title="Display Session as Background Color", defval = true) displayHiLo = input.bool(title="Display Session High/Low", defval= true) // 公共星期校验函数 checkWeekday() => res = false if tzDayOfWeek == dayofweek.monday and showMon res := true else if tzDayOfWeek == dayofweek.tuesday and showTue res := true else if tzDayOfWeek == dayofweek.wednesday and showWed res := true else if tzDayOfWeek == dayofweek.thursday and showThu res := true else if tzDayOfWeek == dayofweek.friday and showFri res := true else if tzDayOfWeek == dayofweek.saturday and showSat res := true else if tzDayOfWeek == dayofweek.sunday and showSun res := true res ////////////////asia session startTime1Asia = timestamp(tz, tzYear, tzMonth, tzDay, startHourAsia, startMinuteAsia) endTime1Asia = timestamp(tz, tzYear, tzMonth, tzDay, endHour2Asia, endMinute2Asia) activeAsia = startTime1Asia <= time and time <= endTime1Asia and tsAsia and checkWeekday() var float Asiahigh = na var float Asialow = na bgColorAsia = color.new(color.red,85) rangeColorAsia = activeAsia ? color.new(color.red,0): color.new(color.red,100) asiaBarsSinceNotActive = ta.barssince(not activeAsia) AsiaLookback = na(asiaBarsSinceNotActive) ? bar_index + 1 : asiaBarsSinceNotActive + 1 if not activeAsia Asiahigh := na Asialow := na if activeAsia Asiahigh := ta.highest(high, AsiaLookback, max_bars_back=500) Asialow := ta.lowest(low, AsiaLookback, max_bars_back=500) plot(Asiahigh , color= rangeColorAsia, title= "Asia High") plot(Asialow , color= rangeColorAsia, title= "Asia Low") bgcolor(color=activeAsia and displayBG ? bgColorAsia : na, title = "Asia Session Background") ////////////////Europe session startTime1Europe = timestamp(tz, tzYear, tzMonth, tzDay, startHourEurope, startMinuteEurope) endTime1Europe = timestamp(tz, tzYear, tzMonth, tzDay, endHour2Europe, endMinute2Europe) activeEurope = startTime1Europe <= time and time <= endTime1Europe and tsEurope and checkWeekday() var float Europehigh = na var float Europelow = na bgColorEurope = color.new(color.green,85) rangeColorEurope = activeEurope ? color.new(color.green,0): color.new(color.green,100) europeBarsSinceNotActive = ta.barssince(not activeEurope) EuropeLookback = na(europeBarsSinceNotActive) ? bar_index + 1 : europeBarsSinceNotActive + 1 if not activeEurope Europehigh := na Europelow := na if activeEurope Europehigh := ta.highest(high, EuropeLookback, max_bars_back=500) Europelow := ta.lowest(low, EuropeLookback, max_bars_back=500) plot(Europehigh , color= rangeColorEurope, title= "Europe High") plot(Europelow , color= rangeColorEurope, title= "Europe Low") bgcolor(color=activeEurope and displayBG ? bgColorEurope : na, title = "Europe Session Background") ////////////////Americas session startTime1Americas = timestamp(tz, tzYear, tzMonth, tzDay, startHourAmericas, startMinuteAmericas) endTime1Americas = timestamp(tz, tzYear, tzMonth, tzDay, endHour2Americas, endMinute2Americas) activeAmericas = startTime1Americas <= time and time <= endTime1Americas and tsAmericas and checkWeekday() var float Americashigh = na var float Americaslow = na bgColorAmericas = color.new(color.blue,85) rangeColorAmericas = activeAmericas ? color.new(color.blue,0): color.new(color.blue,100) americasBarsSinceNotActive = ta.barssince(not activeAmericas) AmericasLookback = na(americasBarsSinceNotActive) ? bar_index + 1 : americasBarsSinceNotActive + 1 if not activeAmericas Americashigh := na Americaslow := na if activeAmericas Americashigh := ta.highest(high, AmericasLookback, max_bars_back=500) Americaslow := ta.lowest(low, AmericasLookback, max_bars_back=500) plot(Americashigh , color= rangeColorAmericas, title= "Americas High") plot(Americaslow , color= rangeColorAmericas, title= "Americas Low") bgcolor(color=activeAmericas and displayBG ? bgColorAmericas : na, title = "Americas Session Background") ////////////////Custom session startTime1Custom = timestamp(tz, tzYear, tzMonth, tzDay, startHourCustom, startMinuteCustom) endTime1Custom = timestamp(tz, tzYear, tzMonth, tzDay, endHour2Custom, endMinute2Custom) activeCustom = startTime1Custom <= time and time <= endTime1Custom and tsCustom and checkWeekday() var float Customhigh = na var float Customlow = na bgColorCustom = color.new(color.yellow,85) rangeColorCustom = activeCustom ? color.new(color.yellow,0): color.new(color.yellow,100) customBarsSinceNotActive = ta.barssince(not activeCustom) CustomLookback = na(customBarsSinceNotActive) ? bar_index + 1 : customBarsSinceNotActive + 1 if not activeCustom Customhigh := na Customlow := na if activeCustom Customhigh := ta.highest(high, CustomLookback, max_bars_back=500) Customlow := ta.lowest(low, CustomLookback, max_bars_back=500) plot(Customhigh , color= rangeColorCustom, title= "Custom High") plot(Customlow , color= rangeColorCustom, title= "Custom Low") bgcolor(color=activeCustom and displayBG ? bgColorCustom : na, title = "Custom Session Background")
修复后的代码可在1分钟到3小时的所有周期下正常运行,符合除4小时、日线外全周期适配的需求。
内容的提问来源于stack exchange,提问作者Miltown Wrench
相关产品推荐
相关产品推荐

