Pinescript variable doesn't change its value - pine-script-v5

So I have a problem, thought a lot about it but not able to fix it so I would appreciate some help from you.
To make it simple, I'll give another piece of code.
currentRSI = ta.rsi(close,14)
var tradeExists = 0
if (currentRSI > 50 and tradeExists == 0)
tradeExists := 1
alert("Long trade")
In my case, if currentRSI crosses over 50, so it gets to 51, AND in the same candle of the timeframe it gets to 49.5, the tradeExists value will remain 0 but the alert has been sent
how could I fix to detect that and close the trade, any idea if I can do this?
I want to specify that I also tried using varip tradeExists = 0 but the variable still gets rollback at the close of the candle.

I just had that problem and I fixed it: use
the barstate.isconfirmed in your conditions, it's the only way to change a var in pinescript.
if (barstate.isconfirmed and first_time_signal == false)
if nT3Average >= ok_to_buy and nT3Average_2 <= oversold
last_signal := 1
label.new(bar_index,close,'Long',color=color.rgb(49, 161, 64),style = label.style_label_up,xloc=xloc.bar_index,yloc=yloc.belowbar)
first_time_signal := true
if nT3Average <= ok_to_sell and nT3Average_2 >= overbought
last_signal := -1
label.new(bar_index,close,'Short',color=color.rgb(175, 55, 95),style = label.style_label_down,xloc=xloc.bar_index,yloc=yloc.abovebar,textcolor=color.rgb(10,10,10))
first_time_signal := true

Related

Pine Script 5 - Unwanted alert messages

I receive unwanted alert messages. I would like to have only 1 "Go Long" alert when going long and then no other "Go Long" alerts until after the first "Go Short" alert. I'm having trouble getting this right.
//#version=5
strategy("Single Alert Strategy", overlay=true)
// Create flags to avoid multiple Long signals when already in Long and multiple Short signals when already in Short
isLong = false // We initialize a value and give it false (we are not in a Long position)
isLong := nz(isLong[1]) // We check the previous value and assign the previous value to this variable (when no previous value exist it will become false)
isShort = false // We initialize a value and give it false (we are not in a Short position)
isShort := nz(isShort[1]) // We check the previous value and assign the previous value to this variable (when no previous value exist it will become false)
// Long Short conditions
tot_rsi = ta.rsi(close, 14)
bullLevel = 30
bearLevel = 70
longCondition = ta.crossover(tot_rsi, bullLevel) and not isLong // Go Long only if we are not already Long
shortCondition = ta.crossunder(tot_rsi, bearLevel) and not isShort // Go Short only if we are not already Short
// Change the flags to avoid duplicate signals
if (longCondition)
isLong := true
isShort := false
if (shortCondition)
isLong := false
isShort := true
if longCondition
strategy.entry('Long', strategy.long, alert_message = "GoLong")
if shortCondition
strategy.entry('Short', strategy.short, alert_message = "GoShort")
// Plot the signals and compare them with the Alerts log
plotshape(series=longCondition, title="Long", text="Long", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(series=shortCondition, title="Short", text="Short", style=shape.triangledown, location=location.belowbar, color=color.red, size=size.small)
I followed the instructions in the answer provided here. While the signal indicators plot correctly (no additional signals), I do get an alert message when there was no signal plotted. This strategy is newly created with a new alert and is only added to 1 chart. The alert was created at 06:58, there were signals plotted before the alert was created but it triggered at 07:05 even though there was no signal plotted.
RSI level at 07:05 was 48.20
Any ideas what may have caused this alert to trigger and how to prevent additional alerts like these?
Link to screenshot
Edit: I'm testing an alternative approach. The unwanted alerts do not come frequently so I may have to run it for some time. If anyone knows of a different work around then I'm happy to give that a try.
//#version=5
strategy("Single Alert Strategy", overlay=true, calc_on_every_tick = true)
noOrder = strategy.closedtrades == 0 // There is no previous order
openLong = strategy.position_size > 0 // We are going Long
openShort = strategy.position_size < 0 // We are going Short
// Long Short conditions
tot_rsi = ta.rsi(close, 14)
bullLevel = 30
bearLevel = 70
longCondition = ta.crossover(tot_rsi, bullLevel) and (openShort[1] or noOrder) // Go Long only if the previous order was Short
shortCondition = ta.crossunder(tot_rsi, bearLevel) and (openLong[1] or noOrder) // Go Short only if the previous order was Long
if longCondition
strategy.entry('Long', strategy.long, alert_message = "GoLong")
if shortCondition
strategy.entry('Short', strategy.short, alert_message = "GoShort")
// Plot the signals and compare them with the Alerts log
plotshape(series=longCondition, title="Long", text="Long", style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small)
plotshape(series=shortCondition, title="Short", text="Short", style=shape.triangledown, location=location.belowbar, color=color.red, size=size.small)
Edit 2: The 2nd approach also created an alert despite there not being any signal plotted. Screenhot here
You should test also with strategy.opentrades which will return something !=0 if a trade (Long or Short) is currently open :
if longCondition and strategy.opentrades==0
strategy.close_all(comment="close", immediately=true)
strategy.entry('Long', strategy.long, alert_message = "GoLong")
if shortCondition and strategy.opentrades==0
strategy.close_all(comment="close", immediately=true)
strategy.entry('Short', strategy.short, alert_message = "GoShort")

OBV Calculation

obv = cum(change(src) > 0 ? volume : change(src) < 0 ? -volume : 0*volume)
obv2 = cum(sign(change(src)) * volume )
obv and obv2 return different results
ta.obv(df['close'], df['volume']) returns the same result as obv2
I will also need the return value of obv calculation with talib
OBV calculation
Thanks in advance for your help.
I've added an OBV indicator to TradingView, opened it's sources and found
obv = ta.cum(math.sign(ta.change(src)) * volume)
Then I cloned the indicator and replaced this line with
obv = ta.cum(ta.change(src) > 0 ? volume : ta.change(src) < 0 ? -volume : 0*volume)
And added it as a second indicator. I've got a different results. But also I've got a warning:
line 9: The function 'ta.change' should be called on each calculation
for consistency. It is recommended to extract the call from the
ternary operator or from the scope
So, I replaced the line with
c = ta.change(src)
obv = ta.cum(c > 0 ? volume : c < 0 ? -volume : 0*volume)
And got exactly the same results as original OBV!
So your code for obv is incorrect and you shall google for explanation of this warning. For example: The function should be called on each calculation for consistency, console output?

In Pine Script, how can you do something once per day, or keep track if something has been done yet that day?

I'm working on a TradingView script (Pine) and i'm trying to use my Daily-bar strategy on the 5-minute chart. To do this, I need to basically only check conditions once per day.
I can do this by having a boolean variable such as dailyCheck = false and set it to true when I run that code and then reset it on a new day.
Does anyone know how to go about doing this? From what I read in the pine manual it says you can get unix time...but I don't know how to work with this and I can't print anything except numbers in the form of plot, so I can't figure out how to tell when a new day has started. Thanks in advance!
Version 1
There are lots of ways to detect a change of day. The Session and time information User Manual page shows a few.
I like detecting a change in the dayofweek or dayofmonth built-in variables:
//#version=4
study("Once per Day")
var dailyTaskDone = false
newDay = change(dayofweek)
doOncePerDay = rising(close, 2) // Your condition here.
dailyTaskDone := doOncePerDay or (dailyTaskDone and not newDay)
plotchar(newDay, "newDay", "▼", location.top, transp = 60)
plotchar(doOncePerDay, "doOncePerDay", "•", location.top, transp = 0)
bgcolor(dailyTaskDone ? color.orange : na)
Version 2
Following Michel's comment, this uses a more robust detection of the day change:
//#version=4
study("Once per Day")
var dailyTaskDone = false
newDay = change(time("D"))
doOncePerDay = rising(close, 2) // Your condition here.
dailyTaskDone := doOncePerDay or (dailyTaskDone and not newDay)
plotchar(newDay, "newDay", "▼", location.top, transp = 60)
plotchar(doOncePerDay, "doOncePerDay", "•", location.top, transp = 0)
bgcolor(dailyTaskDone ? color.orange : na)
And for the OP, a v3 version:
//#version=3
study("Once per Day v3")
dailyTaskDone = false
newDay = change(time("D"))
doOncePerDay = rising(close, 2) // Your condition here.
dailyTaskDone := doOncePerDay or (dailyTaskDone[1] and not newDay)
plotchar(newDay, "newDay", "▼", location.top, transp = 60)
plotchar(doOncePerDay, "doOncePerDay", "•", location.top, transp = 0)
bgcolor(dailyTaskDone ? orange : na)

Script for indicating order history - Tradeview Pine

I want to indicate historical trades in tradingview charts via a script based on information on time and price for entry and close.
My best idea is to search through "time" to find matches for entry and close, and then change the background color according to short or long position or draw a horizontal line. However, this seems not optimal. Any suggestions?
I'd implement that in the next way:
//#version=3
strategy("Background changing", overlay=true)
NONE = 0
LONG = 1000
SHORT = -1000
position = NONE
position := nz(position[1], NONE)
longCondition = crossover(sma(close, 14), sma(close, 28))
if (longCondition)
strategy.entry("LongEntryId", strategy.long)
position := LONG
if (close < high[1])
strategy.close("LongEntryId")
position := NONE
getColor(state) =>
state == LONG ? green :
state == SHORT ? red :
white
bgcolor(color=getColor(position))
Or you can put arrows to the chart:
//#version=3
study("My Script", overlay=true)
order = 0
if time >= timestamp(2018, 1, 10, 0, 0)
order := 1
if time == timestamp(2018, 1, 17, 0, 0)
order := -1
plotarrow(order)

Creating a for-loop that stores values in a new variable

I'm quite new to Matlab so excuse me for the basic question.
I need to make a for-loop that repeats it's self 384 times.
So :
for i=1:384
I now need the for loop to check if 2 certain variables have the value 1 through 10, and then let them store this in a new variable with that value.
So:
if x==1
somevariable = 1
elseif x== 2
saomevariable = 2
..
..
..
elseif y = 1
someothervariable = 1
etc etc.
Is there a way to write this more efficient?
Thank you!
The first think you can do is:
if(x >= 1 && x <= 10)
somevariable=x;
end
if(y >= 1 && y <= 10)
someohtervariable=y;
end
If you could post more information about "x" and "y", perhaps your script can be further "improved".
Hope this helps.