david
david

Reputation: 1

PineScript v6 - is there a way to capture & freeze a price within a bar?

I am currently trying out a strategy based on Parabolic SAR & 1h bars. I have written a simple alert which triggers when SAR flips over/below the price and prints a label with the price it flipped at. However, it seems impossible to capture and freeze the exact price within a bar which triggers the alert.

I managed to capture the price at the moment the alert triggers, but then it gets updated throughout the entire bar and I always end up with a close price. I tried both 'close' and 'requestsecurity' options and both actually capture the price the moment the alert triggers, but then the price keeps updating. Even adding a simple flag 'priceis' didn't help.

Below is my code:

//@version=6
indicator("SAR Jump Alert", overlay=true)

// Define SAR parameters
start = 0.02
inc = 0.02
max = 0.2
sarValue = ta.sar(start, inc, max)

// Detect SAR flipping below price (BUY) or above price (SELL)
sarWasAbove = sarValue[1] > close[1]  // Was SAR above in the previous candle?
sarWasBelow = sarValue[1] < close[1]  // Was SAR below in the previous candle?

sarNowBelow = sarValue < close  // SAR just moved below price (BUY condition)
sarNowAbove = sarValue > close  // SAR just moved above price (SELL condition)

buySignal = sarWasAbove and sarNowBelow
sellSignal = sarWasBelow and sarNowAbove

// Store the exact price when the signal triggers, but reset at each new bar
var float buyTriggerPrice = na
var float sellTriggerPrice = na
var int priceis = 0

// Reset priceis flag at the start of each new bar
if bar_index != bar_index[1]  // New bar detected
    priceis := 0

// Alerts
alertcondition(buySignal, title="BUY Alert", message="SAR jumped below price! BUY Signal")
alertcondition(sellSignal, title="SELL Alert", message="SAR jumped above price! SELL Signal")

// Ensure the label is created immediately when the signal triggers and add flag priceis=1 so that it doesn't keep updating until next bar
if buySignal and priceis == 0
    priceis:=1
    buyTriggerPrice := close //request.security(syminfo.tickerid, "1", close)
    label.new(x=bar_index, y=high, text= str.tostring(buyTriggerPrice), color=color.green, style=label.style_label_down, textcolor=color.white, size=size.normal)

if sellSignal and priceis ==0
    priceis:=1
    sellTriggerPrice := request.security(syminfo.tickerid, "1", close)
    label.new(x=bar_index, y=low, text= str.tostring(sellTriggerPrice), color=color.red, style=label.style_label_up, textcolor=color.white, size=size.normal)

Upvotes: 0

Views: 79

Answers (1)

sbtnc
sbtnc

Reputation: 178

That's a great question. We must use varip to lock the close price when the condition is first met and escape the rollback process on subsequent intrabar updates.

varip float triggerPrice = na
varip bool isPriceSaved = false 

//
// Runs once on the first bar update.
//
if barstate.isnew
    isPriceSaved := false

//
// Runs once on the first intrabar update when the condition is met.
//
if (buySignal or sellSignal) and not isPriceSaved
    triggerPrice := close
    isPriceSaved := true

//
// Runs on every intrabar update when the condition is met.
//
if buySignal
    label.new(x = bar_index, y = high, text = str.tostring(triggerPrice), color = color.green, style = label.style_label_down, textcolor = color.white, size = size.normal)
else if sellSignal
    label.new(x = bar_index, y = low, text = str.tostring(triggerPrice), color = color.red, style = label.style_label_up, textcolor = color.white, size = size.normal)

Upvotes: 0

Related Questions