user11956479
user11956479

Reputation: 11

How to plotshape only on first candle where condition is true?

I am just starting out learning PineScript and have hit a wall already...

To learn, I am trying to set up a simple strategy whereby if the candle closes above or below an EMA 2 times in a row, then it will print a buy or sell arrow, but only on the first candle on which this is true.

As you can see from the snippet below I have got as far as plotting the shapes, but the shapes now display on all candles in which the condition is true.

I am also not sure how to write the condition where this will only display the shape once the second candle above or below the EMA has printed.

I would really appreciate some pointers on the syntax and logic behind what I am trying to achieve (as a noob, just showing the code will probably just confuse me!)

// @version=4
study("EMA Close Strat", shorttitle="EMA Close Strat", overlay=true)

// EMA
EMA_Checkbox = input(title="EMA", type=input.bool, defval=true)
EMA_Length = input(title="EMA Length", type=input.integer, defval=13, minval=1)
EMA_Out = ema(close, EMA_Length)
plot(EMA_Out, title="EMA", color=#fc4c2a, linewidth=2, transp=0)
Buy = close >= EMA_Out
plotshape(Buy, style=shape.triangleup)
Sell = close < EMA_Out
plotshape(Sell, style=shape.triangledown, location=location.belowbar)

Upvotes: 1

Views: 5651

Answers (2)

Braconnot_P
Braconnot_P

Reputation: 179

You need to add an AND to compare previous bar. This way, plotshape will be true only the first bar condition change.

cns_up := close >= EMA_Out and close[1] < EMA_Out ? cns_up + 1 : 0     // Only increment the counter, if the condition is TRUE. Reset it otherwise
cns_dwn := close < EMA_Out and close[1] >= EMA_Out ? cns_dwn + 1 : 0    // Only increment the counter, if the condition is TRUE. Reset it otherwise

Upvotes: 0

vitruvius
vitruvius

Reputation: 21179

the shapes now display on all candles in which the condition is true.

I have a detailed answer for this problem here .

I am also not sure how to write the condition where this will only display the shape once the second candle above or below the EMA has printed.

You should use a counter with the history reference operator []. Such that, if your condition is true, increment the counter by 1. However, you should use the history reference operator to access the previous value of the counter.

cns_up = 0                  // Declare the up counter
cns_up := nz(cns_up[1])     // Get the previous value of it

cns_dwn = 0                 // Declare the up counter
cns_dwn := nz(cns_dwn[1])   // Get the previous value of it

cns_up := close >= EMA_Out ? cns_up + 1 : 0     // Only increment the counter, if the condition is TRUE. Reset it otherwise
cns_dwn := close < EMA_Out ? cns_dwn + 1 : 0    // Only increment the counter, if the condition is TRUE. Reset it otherwise

Full code:

// @version=4
study("EMA Close Strat", shorttitle="EMA Close Strat", overlay=true)

EMA_Checkbox = input(title="EMA", type=input.bool, defval=true)
EMA_Length = input(title="EMA Length", type=input.integer, defval=13, minval=1)
cns_len = input(title="Consecutive up/down length", type=input.integer, defval=2, minval=1)

cns_up = 0                  // Declare the up counter
cns_up := nz(cns_up[1])     // Get the previous value of it

cns_dwn = 0                 // Declare the up counter
cns_dwn := nz(cns_dwn[1])   // Get the previous value of it

isLong = false              // A flag for going LONG
isLong := nz(isLong[1])     // Get the previous value of it

isShort = false             // A flag for going SHORT
isShort := nz(isShort[1])   // Get the previous value of it

// EMA
EMA_Out = ema(close, EMA_Length)
plot(EMA_Out, title="EMA", color=#fc4c2a, linewidth=2, transp=0)

cns_up := close >= EMA_Out ? cns_up + 1 : 0     // Only increment the counter, if the condition is TRUE. Reset it otherwise
cns_dwn := close < EMA_Out ? cns_dwn + 1 : 0    // Only increment the counter, if the condition is TRUE. Reset it otherwise

buySignal = not isLong and (cns_up >= cns_len)      // Check the BUY condition
sellSignal = not isShort and (cns_dwn >= cns_len)   // Check the SELL condition

if (buySignal)
    isLong := true
    isShort := false

if (sellSignal)
    isLong := false
    isShort := true

plotshape(buySignal, style=shape.triangleup, color=color.green, transp=40, text="BUY", editable=false, location=location.belowbar, size=size.small)
plotshape(sellSignal, style=shape.triangledown, color=color.red, transp=40, text="SELL", editable=false, location=location.abovebar, size=size.small)

enter image description here

Upvotes: 2

Related Questions