How can I detect any change in Linear Regression Candle color from red to green or green to red after plotting them using plotcandle() - algorithmic-trading

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

Related

Add line to matrix in pine script

Why is a row not added to the line matrix but to int matrix?
//#version=5
indicator("Matrix test", overlay = true)
if barstate.islast
mInt = matrix.new<int>(1, 1, na)
matrix.add_row(mInt)
mLine = matrix.new<line>(1, 1, na)
matrix.add_row(mLine)
t = table.new(position.middle_right, 1, 2)
table.cell(t, 0, 0, str.tostring(matrix.rows(mInt)))
table.cell(t, 0, 1, str.tostring(matrix.rows(mLine)))
Looks like a bug. I think Tradingview will handle this.
You can add array with na lines as a workaround:
//#version=5
indicator("Matrixtest")
if barstate.islast
mLine2 = matrix.new<line>(1, 1, na)
line l = na
a = array.new<line>()
array.push(a, l)
matrix.add_row(mLine2, 0, a)
label.new(bar_index, low, "LINE matrix: " + str.tostring(matrix.rows(mLine2)) + "x" + str.tostring(matrix.columns(mLine2)))

What approach to be followed to code this in Pinescript

Buy signal to be generated if any candle closes above a line (let's say EMA20)
Stoploss should get triggered only if any subsequent candle closes below it (buy signal candle).
All candles formed prior to the "buy signal" candle should have a closing below EMA20.
Inversely for sell signal also.
I do not wish to know the code, only the logic would suffice for backtesting.
Thanks
You can use ta.crossover(close, ema20) to check that
Store entry price in a var, and check if the price closes below it when you are in a trade
Use a counter to count when the price is below ema20
Below code should do it or at least give you an idea
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © vitruvius
//#version=5
indicator("My script", overlay=true)
ema_len = input.int(20)
below_ema_no = input.int(4)
_ema = ta.ema(close, ema_len)
ema_co = ta.crossover(close, _ema)
var below_ema_cnt = 0
below_ema_cnt := close < _ema ? below_ema_cnt + 1 : 0 // Increase the counter if it closed below EMA20, reset oterwise
var is_long = false
var float buy_price = na
is_buy = not is_long and ema_co and (below_ema_cnt[1] >= below_ema_no) // Buy when we are not already long, ema crossover takes place, last n candles below ema20
is_long := not is_long ? is_buy ? true : false : is_long // Update is_long flag
buy_price := not is_long[1] and is_long ? close : buy_price // New position: Store buy price (close price)
is_sl = is_long ? close < buy_price : false // SL is hit if price closes below entry price
is_long := is_sl ? false : is_long // Update is_long flag in case SL is hit
buy_price := is_sl ? na : buy_price // Reset buy_price in case SL is hit
plot(_ema, "EMA", color.yellow, 2)
plotshape(is_buy, "Buy", shape.triangleup, location.belowbar, color.green, 0, "Buy", size=size.small)
plotshape(is_sl, "SL", shape.triangledown, location.abovebar, color.red, 0, "SL", size=size.small)
plot(buy_price, "Buy Price", color.white, 1, plot.style_circles)

How to draw a fan in Pine v5? Lines connecting open/close in a range?

Hello I'm new to pine and i have a question.
I would like to write a script that helps me drawing lines connecting the close of the first candle in a selected range and the close of every other candle in the range.
I think I have some problem understanding pine runtime because using for loops or conditional structures seems bad but I can't find a solution around this.
I tried with if but had no succes, the idea was that
after i select the start/end point, the code should be something like this:
if bar_index > bar_index[barStart] and bar_index < bar_index[barEnd]
line.new(bar_index[barStart], close[barStart], bar_index, close)
else na
After this I tried with a for loop, again with no success:
for i = bar_index[barStart]+1 to bar_index[barEnd]
line.new(bar_index[barStart], close[barStart], bar_index[i], close[i])
The code I use to select the range and count the candles inside it is this one:
//#version=5
indicator("Close", overlay=true)
// Range Start
t0 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
p0 = input.price(defval = 0, confirm = true)
// Range End
t1 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
p1 = input.price(defval = 0, confirm = true)
///////////////////////////////////////////////////////////////////////////////////
// Bar counting
t_bar(_t) =>
var int _bar = na
if time_close[1] <= _t and time >= _t
_bar := bar_index
_bar
start = int(t_bar(t0))
end = int(t_bar(t1))
//Counting bars in the selected range
barStart = bar_index - start
barEnd = bar_index - end
barDelta = end - start
//Print results
plot(barStart, "Range start")
plot(barEnd, "Range end")
plot(barDelta, "Candles in range")
But from here on I don't know how to proceed. This should be pretty easy but I'm stuck.
What I'm trying to draw
Thank you to anyone willing to help!!
You don't need the loop or the input price variables. The lines can be drawn bar by bar as the script's execution enters your time range and the price variables can also be obtained at the same time.
//#version=5
indicator("Close", overlay=true)
// Range Start
t0 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
// Range End
t1 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
///////////////////////////////////////////////////////////////////////////////////
first_bar = time >= t0 and time[1] < t0
in_range = time > t0 and time <= t1
post_bar = time > t1 and time[1] <= t1
var float start_close = na
var int start_index = na
if first_bar
start_close := close
start_index := bar_index
if in_range and not first_bar
line.new(x1 = start_index, y1 = start_close, x2 = bar_index, y2 = close)
if post_bar
num_bars = bar_index[1] - start_index
delta = close[1] - start_close
info_text = "Start Bar : " + str.tostring(start_index) + "\nEnd Bar : " + str.tostring(bar_index[1]) + "\nNumber of bars : " + str.tostring(num_bars) + "\nPrice delta : " + str.tostring(delta)
label.new(x = bar_index[1], y = high[1], style = label.style_label_lower_left, size = size.small, text = info_text)
Follow up question :
To draw the lines on a higher timeframe and have them "persist" once you move to a lower timeframe is a bit trickier. You will have to use an input to manually set the higher timeframe as the script has no way to determine the previous timeframe that it was applied to.
When you set t0 and t1 on the higher timeframe, the timestamp values will correspond to the opening time for those higher time frame bars. This isn't ideal as the lower timeframe candle that starts at this same time isn't the close value we are after.
By using request.security() we can then get the actual closing time of the higher timeframe bar which has the closing value we do want.
So we can use time to determine when we've started the correct higher time frame bars and then use time_close to determine when we are on the lower time frame bar that coincides with the higher timeframe close.
//#version=5
indicator("MTF Close", overlay=true)
// Range Start
t0 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
// Range End
t1 = input.time(timestamp("20 Jul 2021 00:00 +0300"), confirm = true)
///////////////////////////////////////////////////////////////////////////////////
tf = input.timeframe("240", title = "higher timeframe")
htf_close = request.security(syminfo.tickerid, tf, time_close)
is_htf_closing_bar = time_close == htf_close
new_htf = ta.change(time(tf)) != 0
var bool started_first_htf_bar = false
var float start_close = na
var int start_index = na
var bool started_last_htf_bar = false
if time >= t0 and time[1] < t0 and new_htf
started_first_htf_bar := true
else if new_htf
started_first_htf_bar := false
if started_first_htf_bar and is_htf_closing_bar and na(start_close)
start_close := close
start_index := bar_index
else if not started_first_htf_bar and is_htf_closing_bar and time > t0 and time < t1
line.new(x1 = start_index, y1 = start_close, x2 = bar_index, y2 = close)
if time >= t1 and time[1] < t1 and new_htf
started_last_htf_bar := true
else if new_htf
started_last_htf_bar := false
if started_last_htf_bar and is_htf_closing_bar
line.new(x1 = start_index, y1 = start_close, x2 = bar_index, y2 = close)
post_bar = new_htf and started_last_htf_bar[1]
if post_bar
num_bars = bar_index[1] - start_index
delta = close[1] - start_close
info_text = "Start Bar : " + str.tostring(start_index) + "\nEnd Bar : " + str.tostring(bar_index[1]) + "\nNumber of bars : " + str.tostring(num_bars) + "\nPrice delta : " + str.tostring(delta)
label.new(x = bar_index[1], y = high[1], style = label.style_label_lower_left, size = size.small, text = info_text)

Only last week value pine script

I am trying to get only last week high/low values,NOT all weeks values
t = input(title = "study", defval="W", options=["D","W"])
shigh = security(tickerid, t, high[1], barmerge.gaps_off, barmerge.lookahead_on)
slow = security(tickerid, t, low[1], barmerge.gaps_off, barmerge.lookahead_on)
r = shigh-slow
center=(sclose)
h1=sclose + r*(1.1/12)
c5=sopen != sopen[1] ? na : red
plot(h5, title="H5",color=c5, linewidth=2)
As you can see in the chart are displayed all weeks since creation...I want only last week!not to show all of them into the chart.
Can someone show me how its done?
//#version=4
study("My Script", overlay=true)
t = input(title = "study", defval="W", options=["D","W"])
[sopen, shigh, slow, sclose] = security(syminfo.tickerid, t, [open[1], high[1],low[1],close[1]], barmerge.gaps_off, barmerge.lookahead_on)
r = shigh-slow
center = (sclose)
h5 = sclose + r*(1.1/12)
c5 = sopen != sopen[1] ? na : color.red
plot(h5, title="H5",color=c5, linewidth=2)
Update: only show current week.
//#version=4
study("My Script", overlay=true)
t = input(title = "study", defval="W", options=["D","W"])
thisweek = year(timenow) == year(time) and weekofyear(timenow) == weekofyear(time)
[sopen, shigh, slow, sclose] = security(syminfo.tickerid, t, [open[1], high[1],low[1],close[1]], barmerge.gaps_off, barmerge.lookahead_on)
r = shigh-slow
center = (sclose)
h5 = sclose + r*(1.1/12)
c5 = sopen != sopen[1] ? na : color.red
plot(thisweek ? h5 : na, title="H5",color=c5, linewidth=2)

Tradingview Pine-Script: How to plot only the last x periods

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

Resources