Reputation: 3
I am trying to draw horizontal lines where it's -8%, -15%, -21%, and -35% of the previous high.
I managed to get the highest plot, but I can't seem to get the horizontal lines drawn with the new complexity of pinescript-v5
Instead of V5, I've changed it to V3. I roughly got the idea but I would like to base the highest as float instead of a series
This is my current script:
//@version=3
study(title="The Adam Khoo Magic", overlay=true)
//Input options
highlength = input(title="High Length", defval=20, type=integer)
//calculate values
highhighs = highest(high, length=highlength)
minuseight = highhighs*0.92
minusfifteen = highhighs*0.85
minustwentyone = highhighs*0.79
minusthirtyfive = highhighs*0.65
p8 = plot(minuseight, title="-8%", color=olive, linewidth=2, style=line)
p15 = plot(minusfifteen, title="-15%", color=purple, linewidth=2, style=line)
p21 = plot(minustwentyone, title="-21%", color=navy, linewidth=2, style=line)
p35 = plot(minusthirtyfive, title="-35%", color=black, linewidth=2, style=line)
fill(p8, p15, color=red)
fill(p15, p21, color=blue)
fill(p21, p35, color=green)
//plot values on the chart
plot(series=highhighs, color=green, linewidth=1)
plot(minuseight, title="-8%", color=olive, linewidth=2, style=line)
plot(minusfifteen, title="-15%", color=purple, linewidth=2, style=line)
plot(minustwentyone, title="-21%", color=navy, linewidth=2, style=line)
plot(minusthirtyfive, title="-35%", color=black, linewidth=2, style=line)
Upvotes: 0
Views: 4459
Reputation: 381
The issue is simply the nature of the hline function. It cannot draw from a series of data. The second issue is that you cannot convert a series into a single data point in such a way to resolve the issue as far as the hline function goes.
There is however a solution to this, and it's to instead use custom line
s.
Note I am using pinescript v5 because I am more familiar with it.
First, we draw the fill color, since this function is able to use a series of data.
//@version=5
indicator(title="The Adam Khoo Magic", overlay=true)
//Input options
highlength = input.int(20, "High Length")
//color fill
highhighs = ta.highest(high, highlength)
p8 = plot(highhighs*0.92, display=display.none, editable=false)
p15 = plot(highhighs*0.85, display=display.none, editable=false)
p21 = plot(highhighs*0.79, display=display.none, editable=false)
p35 = plot(highhighs*0.65, display=display.none, editable=false)
fill(p8, p15, color=color.new(color.red, 90))
fill(p15, p21, color=color.new(color.blue, 90))
fill(p21, p35, color=color.new(color.green, 90))
This will draw the fill colors for you but will avoid drawing the series because of the display=display.none
parameter. Now the more complex part; drawing the horizontal lines between them.
To do this, we start by creating empty line variables, importantly using the var
keyword before the line
keyword.
//horizontal lines
var line minuseight = na
var line minusfifteen = na
var line minustwentyone = na
var line minusthirtyfive = na
Without the var
keyword, every update of the chart data will mess with our line
variables in ways we don't want.
Next, we check for the specific conditions in which we want to update the line variables with the appropriate position data, using if statements.
if not barstate.isconfirmed or (barstate.isrealtime and barstate.islast and not barstate.isconfirmed)
minuseight := line.new(x1=bar_index[1], y1=highhighs*0.92, x2=bar_index, y2=highhighs*0.92, width=1, extend=extend.both)
minusfifteen := line.new(x1=bar_index[1], y1=highhighs*0.85, x2=bar_index, y2=highhighs*0.85, width=1, extend=extend.both)
minustwentyone := line.new(x1=bar_index[1], y1=highhighs*0.79, x2=bar_index, y2=highhighs*0.79, width=1, extend=extend.both)
minusthirtyfive := line.new(x1=bar_index[1], y1=highhighs*0.65, x2=bar_index, y2=highhighs*0.65, width=1, extend=extend.both)
line.set_color(id=minuseight, color=color.white)
line.set_style(id=minuseight, style=line.style_solid)
line.set_color(id=minusfifteen, color=color.white)
line.set_style(id=minusfifteen, style=line.style_solid)
line.set_color(id=minustwentyone, color=color.white)
line.set_style(id=minustwentyone, style=line.style_solid)
line.set_color(id=minusthirtyfive, color=color.white)
line.set_style(id=minusthirtyfive, style=line.style_solid)
Lastly, we delete the lines every time a bar closes:
if barstate.isconfirmed
line.delete(id=minuseight)
line.delete(id=minusfifteen)
line.delete(id=minustwentyone)
line.delete(id=minusthirtyfive)
// end of script here
Put all that together in that order and the code you presented will work and will include the dynamic horizontal lines you wanted!
Note, the reason we use the series to draw the fill colors instead of the dynamic horizontal lines is because of similar technical reasons to your original issue; the fill function cannot use line variables as input.
Upvotes: 1