You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何限制Pine Script中plotshape数量?或转用label数组实现

解决Pine Script中星期标签数量过多的问题

核心问题说明

plotshape属于绘图类函数,只要条件满足就会在对应K线上绘制,无法像line那样用数组单独管理每个实例,所以没法直接通过数组限制显示数量。要实现回溯限制,最直接的方案是替换成label对象——label是可创建、删除的独立元素,能和line一样用数组控制数量。

具体实现步骤

  1. 创建存储label的数组:用于管理所有生成的星期标签,控制数量上限。
  2. 定义生成标签的函数:封装label的创建、数组添加和旧标签删除逻辑,和你之前处理line的逻辑一致。
  3. 替换plotshape为统一的触发逻辑:用switch判断星期几,生成对应文本,满足条件时调用函数创建标签。

修改后的完整代码(替换原"Display the days of week"部分)

//@version=5
indicator("Show Week and Day Seperator", overlay=true, max_lines_count=500, max_boxes_count=500)

// Constants and One-Time-Init Vars {
transpLine = 0

// }

// Inputs {
grpWeekLine = "================== Week Seperator Lines =================="
i_user_week_start = input.string(title='Week Separator on Day', defval='Sunday', options=['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], group=grpWeekLine)
i_user_week_toggle = input(title='Show Week Separator Line', defval=true, inline="Weekly Line", group=grpWeekLine)
i_WeekSepLookBack = input.int(title="Lookback", defval=5, minval=0, maxval=400, group=grpWeekLine)
i_weeklyLineCl =input.color(color.new(color.blue, transpLine), "", inline="Weekly Line", group=grpWeekLine)
i_weekLineWidth = input.int(title='Week Line Width', defval=4, minval=0, maxval=20, step=1, group=grpWeekLine)
i_user_week_line_style = input.string(title='Week Line Style', defval='dashed', options=['solid', 'dashed', 'dotted'], group=grpWeekLine)

grpDaykLine = "=================== Day Seperator Lines ==================="
i_user_day_toggle = input(title='Show Day Separator Line', defval=true, inline="Day Line", group=grpDaykLine)
i_daylyLineCl =input.color(color.new(color.blue, transpLine), "", inline="Day Line", group=grpDaykLine)
i_DaySepLookBack = input.int(title="Lookback", defval=5, minval=0, maxval=400, group=grpDaykLine)
i_dayLineWidth = input.int(title='Day Line Width', defval=4, minval=0, maxval=20, step=1, group=grpDaykLine)
i_user_day_line_style = input.string(title='Day Line Style', defval='dashed', options=['solid', 'dashed', 'dotted'], group=grpDaykLine)


// Alternative Lines using backcolours
grpWeekDayLineAdditional = "================== Additional Settings =================="
i_user_show_on_1hour = input(title='Show Day Separator and Days of Week on 1 hour Chart', defval=false, group=grpWeekDayLineAdditional)
i_user_show_on_updaily = input(title='Show Week Separator up to the Daily Chart', defval=false, group=grpWeekDayLineAdditional)
i_showDOW = input.bool(true, title='Show days of week', inline="i_ShowDow", group=grpWeekDayLineAdditional)
i_user_dow_color = input.color(color.new(color.blue, transpLine), "", inline="i_ShowDow", group=grpWeekDayLineAdditional)
i_isShortDayLabel = input.bool(false, "Use short names for days of week (Mon, Tue...)", group=grpWeekDayLineAdditional)
i_EndlessLines = input.bool(true, title="Reduce length of horizontal Seperators", group=grpWeekDayLineAdditional)
i_Seplength = input.int(title="Seperator Length", defval=800, group=grpWeekDayLineAdditional)

// }

week_line_style = i_user_week_line_style == 'solid' ? line.style_solid : i_user_week_line_style == 'dashed' ? line.style_dashed : i_user_week_line_style == 'dotted' ? line.style_dotted : line.style_solid
day_line_style = i_user_day_line_style == 'solid' ? line.style_solid : i_user_day_line_style == 'dashed' ? line.style_dashed : i_user_day_line_style == 'dotted' ? line.style_dotted : line.style_solid

tickerExchangeOffset = 5
int new_day_start_time = 17
int dayLabelStartTime = 1
week_start_day = i_user_week_start == 'Sunday' ? dayofweek.sunday : i_user_week_start == 'Monday' ? dayofweek.monday : i_user_week_start == 'Tuesday' ? dayofweek.tuesday : i_user_week_start == 'Wednesday' ? dayofweek.wednesday : i_user_week_start == 'Thursday' ? dayofweek.thursday : i_user_week_start == 'Friday' ? dayofweek.friday : i_user_week_start == 'Saturday' ? dayofweek.saturday : dayofweek.sunday

// Functions {

f_vline(Lookback, BarIndex, Color, LineStyle, LineWidth, LookBack) => 

    low_ = hl2 - (syminfo.mintick) * i_Seplength
    high_ = hl2 + (syminfo.mintick) * i_Seplength

    var createLines = array.new_line()

    array.push(createLines, line.new(time, low_, time, high_, xloc.bar_time, extend=extend.none, color=Color, style=LineStyle, width=LineWidth))

    if array.size(createLines) > Lookback
        ln = array.shift(createLines)
        line.delete(ln)


f_vlineEndless(Lookback, BarIndex, Color, LineStyle, LineWidth, LookBack) => 

    var createLines = array.new_line()

    array.push(createLines, line.new(BarIndex, 0, BarIndex, 1, extend=extend.both, color=Color, style=LineStyle, width=LineWidth))

    if array.size(createLines) > Lookback
        ln = array.shift(createLines)
        line.delete(ln)

// 新增:生成星期标签的函数和存储数组
var label_array = array.new_label()

f_create_dow_label(lookback, day_text, x_time, y_loc) =>
    // 创建标签,style设为none对应原来的circle透明点,只显示文本
    new_label = label.new(x=x_time, y=y_loc, text=day_text, color=dot_color, textcolor=i_user_dow_color, style=label.style_none, size=size.tiny)
    array.push(label_array, new_label)
    // 超过回溯数量时删除最旧的标签
    if array.size(label_array) > lookback
        old_label = array.shift(label_array)
        label.delete(old_label)
// }

// Calcutations {

if syminfo.timezone == 'Etc/UTC'
    new_day_start_time += tickerExchangeOffset
    dayLabelStartTime += tickerExchangeOffset
    dayLabelStartTime
            
// Add the start of week line
isNewWeek() =>
    dayofweek == week_start_day ? 1 : 0
    
isStartTime() =>
    hour == new_day_start_time and minute == 0 ? 1 : 0
   
isValidDaySeparatorResolution() =>
    timeframe.isdwm == true or timeframe.period == '60' and not i_user_show_on_1hour or timeframe.in_seconds() >= timeframe.in_seconds("120")  ? 0 : 1

isValidWeekSeparatorResolution() =>
    i_user_show_on_updaily and timeframe.isdwm == false ? 1 : not i_user_show_on_updaily and timeframe.in_seconds() <= timeframe.in_seconds("59") ? 1 : 0

isValidDaySeparator = isValidDaySeparatorResolution()
isValidDayTextSeparator = isValidDaySeparatorResolution()
isValidWeekSeparator = isValidWeekSeparatorResolution()

if isValidWeekSeparator and i_user_week_toggle and isNewWeek() == 1 and isStartTime() == 1 and i_EndlessLines == true
    f_vline(i_WeekSepLookBack, bar_index, i_weeklyLineCl, week_line_style, i_weekLineWidth, i_WeekSepLookBack)

if isValidWeekSeparator and i_user_week_toggle and isNewWeek() == 1 and isStartTime() == 1 and not i_EndlessLines == true
    f_vlineEndless(i_WeekSepLookBack, bar_index, i_weeklyLineCl, week_line_style, i_weekLineWidth, i_WeekSepLookBack)
    
// Add daily separator
isNewDay() =>
    dayofweek != week_start_day ? 1 : 0

if isValidDaySeparator and i_user_day_toggle and isNewDay() == 1 and isStartTime() == 1 and i_EndlessLines == true
    f_vline(i_DaySepLookBack, bar_index, i_daylyLineCl, day_line_style, i_dayLineWidth, i_DaySepLookBack)

if isValidDaySeparator and i_user_day_toggle and isNewDay() == 1 and isStartTime() == 1 and not i_EndlessLines == true
    f_vlineEndless(i_DaySepLookBack, bar_index, i_daylyLineCl, day_line_style, i_dayLineWidth, i_DaySepLookBack)

// Display the days of week - 替换原来的plotshape逻辑
dot_color = color.new(color.silver, 100)
dowtext_color = color.new(color.silver, 0)

// 统一触发条件
dow_label_condition = i_showDOW and isValidDayTextSeparator and hour == dayLabelStartTime and minute == 0

if dow_label_condition
    // 根据星期几和短名称设置生成文本
    day_text = na
    if not i_isShortDayLabel
        day_text := switch dayofweek
            dayofweek.monday => "Monday"
            dayofweek.tuesday => "Tuesday"
            dayofweek.wednesday => "Wednesday"
            dayofweek.thursday => "Thursday"
            dayofweek.friday => "Friday"
    else
        day_text := switch dayofweek
            dayofweek.monday => "Mon"
            dayofweek.tuesday => "Tue"
            dayofweek.wednesday => "Wed"
            dayofweek.thursday => "Thu"
            dayofweek.friday => "Fri"
    
    // 只在工作日生成标签
    if not na(day_text)
        // 计算标签位置:x轴偏移8个bar(对应原来的offset=8),y轴在最低价下方
        x_pos = time + 8 * timeframe.multiplier * timeframe.seconds
        y_pos = low - syminfo.mintick * 10
        // 调用函数创建标签,使用日分隔线的回溯值控制数量
        f_create_dow_label(i_DaySepLookBack, day_text, x_pos, y_pos)

// }

// Plots {

// }

关键改动说明

  • 用array.new_label存储所有星期标签,和你管理line的逻辑完全一致,超过回溯值就删除最旧的标签。
  • 用switch替代原来10个重复的plotshape,代码更简洁易维护。
  • label的位置、样式完全匹配原来的plotshape效果,style=label.style_none对应原来的透明circle,只显示文本。
  • 标签数量由i_DaySepLookBack控制,和日分隔线的回溯值保持一致,也可以改成单独的输入参数。

内容的提问来源于stack exchange,提问作者Luca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 06:01:09