0

I have a pretty standard bollinger indicator with lines plotted as "upper" and "lower", and I want to put a "tag" on the last occurrence of a cross above or below the band. I am using barssince to get high > upper and low < lower, and then adding labels with a bar index per the below code.

The calculations work, and it is printing the tags, but I was expecting only 1 high, and 1 low result from Barssince, but I am instead getting multiple highs and lows.

I have tried a few different ways from other answers, but can't seem to just get the LAST one only

Any help greatly appreciated.

Thanks

//@version=4
study(title="BB flag", shorttitle="BB flag", overlay=true)

source = close
Boll_Length = input(20, minval=1), Mult = input(2.0, minval=0.001, maxval=50)
basis = sma(source, Boll_Length)
dev = Mult * stdev(source, Boll_Length)
upper = basis + dev
lower = basis - dev

plot(upper, color=color.blue, title="Upper")
plot(lower, color=color.blue, title="Lower")

Last_Top = barssince(high >= upper)
Last_Bot = barssince(low <= lower)

label1 = label.new(bar_index[Last_Top] , high[Last_Top], text=tostring(high[Last_Top]), style = label.style_labeldown, color = color.orange)
label2 = label.new(bar_index[Last_Bot], low[Last_Bot], text=tostring(low[Last_Bot]), style = label.style_labelup, color = color.green)

Oarsham
  • 1
  • 2

3 Answers3

0

barssince returns a series of data, not a simple data

You should save the bar_index instead

if crossover(high, upper)
    Last_Top := bar_index

if crossunder(low, lower)
    Last_Bot := bar_index

label1 = label.new(Last_Top , high, text=tostring(high[Last_Top]), style = label.style_labeldown, color = color.orange)

label2 = label.new(Last_Bot, low, text=tostring(low[Last_Bot]), style = label.style_labelup, color = color.green)
Dave
  • 847
  • 1
  • 2
  • 7
  • Thanks very much for the quick reply, but the above doesn't really work. Firstly, crossover/crossunder will only trigger if the previous bar close was below, where I might have multiple candles above the upper in a sequence. Also, when I suspect this will not return me just a single value for bar_index, but I can't tell, because it gives an error "The study references too many candles in history(10001)" – Oarsham Aug 06 '22 at 06:15
  • indeed I used the crossover/crossunder to remove the multiple labels but if you want them, switch back to my crossover/crossunder to what you had before I'll add another possible answer – Dave Aug 06 '22 at 06:19
0
if high >= upper
    Last_Top := bar_index

if low <= lower
    Last_Bot := bar_index

if Last_Top != Last_Top[1]
    label1 = label.new(Last_Top , high, text=tostring(high[Last_Top]), style 
     = label.style_labeldown, color = color.orange)

if Last_Bot != Last_Bot[1]
    label2 = label.new(Last_Bot, low, text=tostring(low[Last_Bot]), style = 
    label.style_labelup, color = color.green)
Dave
  • 847
  • 1
  • 2
  • 7
  • Hi @Daveatt, this still gives the error "The study references too many candles in history" – Oarsham Aug 06 '22 at 06:45
  • try limiting the calculated data then Solution: https://stackoverflow.com/questions/62790233/error-messagethe-study-references-too-many-candles-in-history10001 – Dave Aug 06 '22 at 07:02
  • I can resolve the "Too many candles error", but this is still not really doing what I want. It still returns a series of candles, counting from the last candle to the first. not just the last, most recent candle – Oarsham Aug 06 '22 at 07:05
0

Just providing an answer in case anyone comes across this.

I figured out that I had made a rooky error of not understanding the difference between indicators (which run for every bar) and Strategies, which execute on the close of a bar (or tick), and hence not understanding the nature of the output of the functions I was using... Anyhoo...

I have managed to get it to do what I wanted by only drawing the label once, and simply updating the attributes of the label. (ie when I get a new signal, move the label, rather than draw a new one...). Another option is to draw a new label, but delete the last one. Either works fine (I have tested both)

Strictly speaking though, I suspect I will move this to my strategy anyway, rather than have it in an indicator its not really the right place for this.

Last_Top = ta.barssince(high >= upper)
Last_Bot = ta.barssince(low <= lower)

if Last_Top < Last_Bot
    _xarr       := bar_index[Last_Top]
    _yarr       := high[Last_Top]
    _textstr    := str.tostring(high[Last_Top])
    _style      := label.style_label_down
    _color      := color.orange
else
    _xarr       := bar_index[Last_Bot]
    _yarr       := low[Last_Bot]
    _textstr    := str.tostring(low[Last_Bot])
    _style      := label.style_label_up
    _color      := color.green

var label1 = label.new(_xarr,_yarr, text = _textstr, style = _style , color = _color)

if barstate.islast
    label.set_xy(label1, _xarr, _yarr)
    label.set_text(label1, _textstr)
    label.set_style(label1, _style)
    label.set_color(label1, _color)
    
Oarsham
  • 1
  • 2