0

I wrote an Indicator in Pincescript, which shows seperator lines for the weekdays and also for the weekend. Additional to that, its possible to show the weekday names.

With the kind help of stack overflow users I was already able to reduce the amount of lines, and learned about the array.new_line functions.

Now I realised that I also have to reduce the amount of the Weekday Names according to the Day Seperator Limit, otherwise it looks quite bad. I checked the other variants of array.* but I didn't find a possibility for plotshapes so far.

Is there a way to work with plotshapes in the same way as its possible with the array.new_line? Or do you see any other possibility to reduce the plotshapes? The plotshapes are in the "Display the days of the Week" part at the end. I think it should be possible to use the array.new_label, but im not sure how to change from plotshape to labels.

Here is the code

//@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)
// }

// 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
dot_color = color.new(color.silver, 100)
dowtext_color = color.new(color.silver, 0)

plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.monday : false, text='Monday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.tuesday : false, text='Tuesday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.wednesday : false, text='Wednesday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.thursday : false, text='Thursday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.friday : false, text='Friday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)

plotshape((i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.monday : false, text='Mon', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.tuesday : false, text='Tue', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.wednesday : false, text='Wed', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.thursday : false, text='Thu', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)
plotshape((i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.friday : false, text='Fri', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)

// }

// Plots {

// }
Luca
  • 17
  • 5

1 Answers1

0

No, you cannot do that with plotshapes(). You need to use labels instead.

What you need to do is, whenever the series argument in your plotshape condition is true, call label.new() and create a new label.

Just like you did with the lines, you need to store your labels in an array and then delete them whenever you limit is reached.

Edit:

Let's have a look at this example:

plotshape((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator ? hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.monday : false, text='Monday', color=dot_color, offset=8, style=shape.circle, location=location.bottom, textcolor=i_user_dow_color, size=size.tiny, editable=false)

The condition to plot this shape is:

cond = ((not i_isShortDayLabel and i_showDOW or i_showDOW and timeframe.period == '60' and i_user_show_on_1hour and not i_isShortDayLabel) and isValidDayTextSeparator and hour == dayLabelStartTime and minute == 0 and dayofweek == dayofweek.monday)

Text is 'Monday', color is dot_color, text color is i_user_dow_color.

For the location, you can do loc=yloc.belowbar.

You have offset=8, so you need to place it at bar_index - 8.

if (cond)
    lbl = label.new(bar_index - 8, low, 'Monday', yloc=yloc.belowbar, color=dot_color, style=label.style_circle, textcolor=i_user_dow_color, size=size.tiny)
vitruvius
  • 15,740
  • 3
  • 16
  • 26
  • Thanks for your help. Appreciate it a lot.. Can you please give me a tip on how I can place it at the same spot? In the plotshape i was able to use `location=location.bottom`, but with `label.new()` I have to use an integer value. – Luca Dec 15 '22 at 19:02
  • Hmm thanks for your explanation, I was also getting closer to this solution. For the moment the label.new looks like this: `label1 = label.new(bar_index + 8, low, text='TestMonday', yloc=yloc.belowbar, color=dot_color, textcolor=i_user_dow_color, style=label.style_circle, size=size.normal)`. But like this is not appearing at the place where I would like to place it.. Do you think its even possible with label.new? See the screenshot, TestMonday is from label.new, Monday Tag is from plotshape's location.bottom. https://i.stack.imgur.com/zd3Wn.png – Luca Dec 15 '22 at 20:54
  • Yea, you cannot place it exactly at the bottom like you do with the `plotshape`. – vitruvius Dec 15 '22 at 22:26
  • Hmm is there a way to get closer to it? Could I maybe use the seperator lines as reference? Something like this: https://i.stack.imgur.com/tYd9A.jpg – Luca Dec 17 '22 at 19:36
  • Sure, you can use the same the price value of your seperator lines. Use the `low_` calculation in `f_vline()`. – vitruvius Dec 17 '22 at 20:12
  • Hmm thats what I actually tried already, but the behavior is strange. One time its on the right spot, at the end of the seperator line. But always one in between is at another position. You can see it on the picture: https://i.stack.imgur.com/WMFDw.jpg. Do you have an idea why? I tried it like this: `low2 = hl2 - (syminfo.mintick) * i_Seplength label1 = label.new(x=time + 8, y=low2, text='TestMonday', xloc=xloc.bar_time, color=dot_color, textcolor=i_user_dow_color, style=label.style_circle, size=size.normal) array.push(createDays, label1)` – Luca Dec 20 '22 at 19:30