How to draw a horizontal line on high and low of candle visible across at least 2 timeframes ?
Here is the code written:
i_startTime_27dec22 = input.time(timestamp("27 dec 2022 15:25 +0530"), title = "Start Time")
i_endTime_27dec22 = input.time(timestamp("27 dec 2022 15:30 +0530"), title = "End Time")
inDateRange_27dec22 = time > i_startTime_27dec22 and time < i_endTime_27dec22 and time == not(timeframe.isweekly or timeframe.ismonthly)
l1h = inDateRange_27dec22 ? line.new(bar_index -5, high, bar_index, high, xloc=xloc.bar_index, extend=extend.both, style=line.style_solid, width=1, color=color.blue) : na
l1l = inDateRange_27dec22 ? line.new(bar_index -5, low, bar_index, low, xloc=xloc.bar_index, extend=extend.both, style=line.style_solid, width=1, color=color.blue) : na
2 H-lines are displayed (drawn) on 5 min timeframe. How can I extend the H-lines drawn to be visible across multiple time frames , intraday and daily ? ( Weekly, monthly not required)
i_startTime_27dec22 = input.time(timestamp("27 dec 2022 15:25 +0530"), title = "Start Time")
i_endTime_27dec22 = input.time(timestamp("27 dec 2022 15:30 +0530"), title = "End Time")
inDateRange_27dec22 = time > i_startTime_27dec22 and time < i_endTime_27dec22 and time == not(timeframe.isweekly or timeframe.ismonthly)
l1h = inDateRange_27dec22 ? line.new(bar_index -5, high, bar_index, high, xloc=xloc.bar_index, extend=extend.both, style=line.style_solid, width=1, color=color.blue) : na
l1l = inDateRange_27dec22 ? line.new(bar_index -5, low, bar_index, low, xloc=xloc.bar_index, extend=extend.both, style=line.style_solid, width=1, color=color.blue) : na
How do I extend the logic to include multiple timeframes ?
Related
Assume lrcopen, lrchigh, lrclow, lrcclose are the open, high, low, close of Linear Regression Candle which is plotted using plotcandle(). I want to check and compare the lrcopen < lrcclose value for last two closed Linear Regression Candle to see whether it changes from false to true or vice versa after plotting
//#version=4
study(title="Humble LinReg Candles", shorttitle="LinReg Candles", format=format.price, precision=4, overlay=true)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 200, defval =7)
sma_signal = input(title="Simple MA (Signal Line)", type=input.bool, defval=true)
lin_reg = input(title="Lin Reg", type=input.bool, defval=true)
linreg_length = input(title="Linear Regression Length", type=input.integer, minval = 1, maxval = 200, defval = 11)
bopen = lin_reg ? linreg(open, linreg_length, 0) : open
bhigh = lin_reg ? linreg(high, linreg_length, 0) : high
blow = lin_reg ? linreg(low, linreg_length, 0) : low
bclose = lin_reg ? linreg(close, linreg_length, 0) : close
r = bopen < bclose
signal = sma_signal ? sma(bclose, signal_length) : ema(bclose, signal_length)
plotcandle(r ? bopen : na, r ? bhigh : na, r ? blow: na, r ? bclose : na, title="LinReg Candles", color= color.green, wickcolor=color.green, bordercolor=color.green, editable= true)
plotcandle(r ? na : bopen, r ? na : bhigh, r ? na : blow, r ? na : bclose, title="LinReg Candles", color=color.red, wickcolor=color.red, bordercolor=color.red, editable= true)
// I want to detect the change of color of just plotted Linear Regression Candle here
I have an indicator which indicate me round numbers on a specific chart in tradingview. For exemple, on US30 or NAS100 chart, the indicator draw horizontal line on round numbers ending by xx000 or xx500. Like 34 000, 34 500, 35 000, etc. My only problem is that the price of the line is not labled in the price scale. first picture is the actual indicator. Second is how I want it to look with the label at the right scale highlighted + the number ending in xx500 in blue + number ending by xx000 in pink.
image #1
image #2
I anybody able to make me the code line to make it work please?
Here is the code in the actual version:
//#version=5
indicator('LVL', overlay=true)
var levels = input(5, title='Number of levels')
var lineColor = input(color.rgb(255, 00, 255), 'Line color')
var lineWidth = input(1, title='Line width')
var spacing = if syminfo.ticker == 'XAUUSD'
25000
else if syminfo.ticker == 'XAGUSD'
250000
else if syminfo.ticker == 'SPX500USD'
500
else if syminfo.ticker == 'NAS100USD'
5000
else if syminfo.ticker == 'US30USD'
5000
else if syminfo.ticker == 'US30'
500
else if syminfo.ticker == 'BTCUSDT'
50000
else if syminfo.ticker == 'ETHUSDT'
25000
else if syminfo.type == 'crypto'
500
else if syminfo.type == 'forex'
500
else if syminfo.ticker == 'USOIL'
1000
else
2500
var step = syminfo.mintick * spacing
if barstate.islast
//label.new(bar_index, low, text=syminfo.type, yloc=yloc.abovebar)
for counter = 0 to levels - 1 by 1
price = if syminfo.type == 'index'
math.ceil(close / 4) * 4
else
close
stepUp = math.ceil(price / step) * step + counter * step
stepDown = math.floor(price / step) * step - counter * step
line.new(bar_index, stepUp, bar_index - 1, stepUp, xloc=xloc.bar_index, extend=extend.both, color=lineColor, width=lineWidth, style=line.style_solid)
line.new(bar_index, stepDown, bar_index - 1, stepDown, xloc=xloc.bar_index, extend=extend.both, color=lineColor, width=lineWidth, style=line.style_solid)
label.new(chart.right_visible_bar_time, levels, str.tostring(levels), xloc=xloc.bar_time)
label.new(chart.right_visible_bar_time, levels, str.tostring(levels), xloc=xloc.bar_time)
I tried with different line like, label for exemple
label.new(chart.right_visible_bar_time, levels, str.tostring(levels), xloc=xloc.bar_time)
label.new(chart.right_visible_bar_time, levels, str.tostring(levels), xloc=xloc.bar_time)
That is unfortunately not possible with lines.
If you can draw your lines with the plot() function, you can do it from your chart settings:
What I have tried so far ...
start_hour = 7
start_minute = 0 * 0.01
end_hour = 17
end_minute = 45 * 0.01
step_time = 25
start_time = start_hour + start_minute
end_time = end_hour + end_minute
if step_time > 59
step_time = 1 if step_time == 60
step_time = 1.3 if step_time == 90
step_time = 2 if step_time == 120
else
step_time *= 0.01
end
hours = []
(start_time..end_time).step(step_time).map do |x|
next if (x-x.to_i) > 0.55
hours << '%0.2f' % x.round(2).to_s
end
puts hours
If I enter the step interval 0, 5, 10, 20, I can get the time interval I want. But if I enter 15, 25, 90, I can't get the right range.
You currently have:
end_hour = 17
end_minute = 45 * 0.01
end_time = end_hour + end_minute
#=> 17.45
Although 17.45 looks like the correct value, it isn't. 45 minutes is 3 quarters (or 75%) of an hour, so the correct decimal value is 17.75.
You could change your code accordingly, but working with decimal hours is a bit strange. It's much easier to just work with minutes. Instead of turning the minutes into hours, you turn the hours into minutes:
start_hour = 7
start_minute = 0
start_time = start_hour * 60 + start_minute
#=> 420
end_hour = 17
end_minute = 45
end_time = end_hour * 60 + end_minute
#=> 1065
The total amount of minutes can easily be converted back to hour-minute pairs via divmod:
420.divmod(60) #=> [7, 0]
1065.divmod(60) #=> [17, 45]
Using the above, we can traverse the range without having to convert the step interval:
def hours(start_time, end_time, step_time)
(start_time..end_time).step(step_time).map do |x|
'%02d:%02d' % x.divmod(60)
end
end
hours(start_time, end_time, 25)
#=> ["07:00", "07:25", "07:50", "08:15", "08:40", "09:05", "09:30", "09:55",
# "10:20", "10:45", "11:10", "11:35", "12:00", "12:25", "12:50", "13:15",
# "13:40", "14:05", "14:30", "14:55", "15:20", "15:45", "16:10", "16:35",
# "17:00", "17:25"]
hours(start_time, end_time, 90)
#=> ["07:00", "08:30", "10:00", "11:30", "13:00", "14:30", "16:00", "17:30"]
I'd like to plot an indicator only for the last x periods.
How do I do that?
If I could do time operations (substract x * period from plotStartDate), maybe I could use this code:
period = timeframe.ismonthly or timeframe.isweekly ? "12M" : "M"
plotStartDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow), 00, 00)
isPlotDate = time >= plotStartDate
plot(isPlotDate ? mydata : na, color=mydata != mydata[1]:na, style=plot.style_line, linewidth=2)
Version 1
Not sure this is what you're looking for. It uses plot()'s show_last= parameter to restrict the number of last bars plotted after your isPlotDate constraint has been satisfied:
//#version=4
study("", "", true)
xPeriods = input(10)
plotStartDate = timestamp(year(timenow), month(timenow), dayofmonth(timenow), 00, 00)
isPlotDate = time >= plotStartDate
plot(isPlotDate ? close : na, show_last = xPeriods)
Version 2
//#version=4
study("Plot starting n months back", "", true)
monthsBack = input(3, minval = 0)
monthsExtra = monthsBack % 12
monthsExcedent = month(timenow) - monthsExtra
yearsBack = floor(monthsBack / 12) + (monthsExcedent <= 0 ? 1 : 0)
targetMonth = monthsExcedent <= 0 ? 12 + monthsExcedent : monthsExcedent
targetYearMonth = year == year(timenow) - yearsBack and month == targetMonth
beginMonth = not targetYearMonth[1] and targetYearMonth
var float valueToPlot = na
if beginMonth
valueToPlot := high
plot(valueToPlot)
bgcolor(beginMonth ? color.green : na)
Version 3
Simpler:
//#version=4
study("Plot starting n months back", "", true)
monthsBack = input(3, minval = 0)
targetDate = time >= timestamp(year(timenow), month(timenow) - monthsBack, 1, 0, 0, 0)
beginMonth = not targetDate[1] and targetDate
var float valueToPlot = na
if beginMonth
valueToPlot := high
plot(valueToPlot)
bgcolor(beginMonth ? color.green : na)
Version 4
At v4 you can set the variable show_last in the plot() function.
In "PineScript language reference manual" says:
show_last (input integer) If set, defines the number of bars (from the
last bar back to the past) to plot on chart.
https://www.tradingview.com/pine-script-reference/#fun_plot
When trying to find a close approximate of the square root of a number bisection algorithms seems to perform extremely well.
In fact bisection search gives a result in just a second for the square root of 10^45
start_time = time.time()
x = 10**45
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
elapsed_time = time.time() - start_time
print(elapsed_time)
But when it comes to finding 10**46 it calculates for so long I eventually terminate it...
start_time = time.time()
x = 10**46
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
elapsed_time = time.time() - start_time
print(elapsed_time)
Is there any explanation?
Can anyone run it?
#Lecagy is correct. The problem is that there are a finite number of floating point numbers. Therefore when you average two that are next to each other, the average is one of the two.
You just need to add a condition to check for this.
import time
start_time = time.time()
x = 10**46
epsilon = 0.01
numGuesses = 0
low = 0.0
high = max(1.0, x)
ans = (high + low)/2.0
while abs(ans**2 - x) >= epsilon and ans != low and ans != high:
print('low =', low, 'high =', high, 'ans =', ans)
numGuesses += 1
if ans**2 < x:
low = ans
else:
high = ans
ans = (high + low)/2.0
print('numGuesses =', numGuesses)
print(ans, 'is close to square root of', x)
elapsed_time = time.time() - start_time
print(elapsed_time)
And now it runs instantly but is not guaranteed to be within epsilon.