0

I thought I understood how to avoid repainting, but I'm still seeing trades on my chart not lining up with alerts, or vice versa.

My script takes data from the 60m chart to trade on the 15m chart. I'm accessing historical data on the 60m (at least 4 bars back), and I'm only entering trades on the 15m if barstate.isconfirmed. I see trades trigger alerts and then disappear, or trades that never triggered an alert show up retrospectively.

As far as I can tell, I wrote my script so future data should not affect historical decisions, but something is clearly going on. I'm at a loss

//@version=4
strategy(title="60-15 ETH/USD", precision=2, default_qty_type=strategy.cash, initial_capital=100.0, currency="USD", commission_type=strategy.commission.percent, commission_value=0.1)

// get input  
i_length        = input(group="Stochastic", title="Stochastic Length", minval=1, defval=15)                                     
i_k             = input(group="Stochastic", title="Stochastic %K", minval=1, defval=2)
i_d             = input(group="Stochastic", title="Stochastic %D", minval=1, defval=10)
i_trailingStop  = input(group="Trade Settings", title="Trailing Stop?", type=input.bool, defval=true)                           // should stop loss be dynamic, based on most recent high, or static, based on entry price?
i_stopPercent   = input(group="Trade Settings", title="Stop Percent", type=input.float, defval=0.05, maxval=1.0, minval=0.001)  // how much (percentage) can price fall before exiting the trade
i_takeProfit    = input(group="Trade Settings", title="Take Profit", type=input.float, defval=0.06, maxval=1.0, minval=0.001)   // how much (percentage) can price rise before exiting the trade
i_sellThreshold = input(group="Trade Settings", title="Sell Threshold", type=input.float, defval=75.0, maxval=100, minval=0.0)  // when stochastic %D crosses under this value, exit the trade
i_buyThreshold  = input(group="Trade Settings", title="Buy Threshold", type=input.float, defval=40.0, maxval=100, minval=0.0)   // stochastic %D must be below this value to enter a trade


// declare order variables
var recentHigh  = 0.0   // the highest high while in a trade
var stop        = 0.0   // the price that will trigger as stop loss
var entryPrice  = 0.0   // the price when the trade was entered

// build stochastic
sto = stoch(close, high, low, i_length)
K   = sma(sto, i_k)
D   = sma(K, i_d)

// get stochastic trend
stoch_upTrend = D > D[1]

// get stochastic trend for 60 minute
stoch_60         = security(syminfo.tickerid, "60", D)
stoch_60_upTrend = (stoch_60[4] >= stoch_60[8])

// entry
if (D < i_buyThreshold) and stoch_upTrend and stoch_60_upTrend and barstate.isconfirmed and strategy.position_size == 0
    recentHigh := close
    entryPrice := close
    stop       := (close * (1-i_stopPercent)) 
    strategy.entry(id="60-15-Long", long=strategy.long, comment='buy')

// update recent high, trailing stop
if close > recentHigh  
    recentHigh := close
    stop       := i_trailingStop ? (recentHigh * i_stopPercent) : stop

// exit
strategy.exit(id="60-15-Long", stop=stop, comment='sell-stop')
if close > (entryPrice * (1+i_takeProfit)) and barstate.isconfirmed
    strategy.close(id="60-15-Long", comment='sell-profit')
if crossunder(D, i_sellThreshold) and barstate.isconfirmed
    strategy.close(id="60-15-Long", comment='sell-trend')
    
// plot
plot(K, title="%K", color=color.blue, linewidth=1)
plot(D, title="%D", color=color.orange, linewidth=1)
plot(stoch_60, title="Hourly Stochastic (D)", color= stoch_60_upTrend ? color.green : color.red, style=plot.style_stepline)
upperBand  = hline(i_sellThreshold, title="Upper Limit", linestyle=hline.style_dashed)
middleBand = hline(50, title="Midline", linestyle=hline.style_dotted)
lowerBand  = hline(i_buyThreshold, title="Lower Limit", linestyle=hline.style_dashed)
fill(lowerBand, upperBand, color=color.purple, transp=75)
Bjorn Mistiaen
  • 6,459
  • 3
  • 18
  • 42
Ian
  • 85
  • 5
  • Here's a screen shot of an entry that didn't trigger an alert. All of the conditions are correct, but apparently this trade didn't show up in real time, which means the conditions weren't correct in real time, and changed retrospectively? (https://imgur.com/a/SUVthmc) – Ian Apr 30 '21 at 18:35
  • I m having the exact same issue. Seems like "barstate.isconfirmed" is not working reliably. – Slyper Sep 12 '21 at 06:28

1 Answers1

0

I realize this is pretty old now but I think the issue is that (D < i_buyThreshold) can repaint and stoch_upTrend = D > D[1] can also repaint. You could try adding if barstate.isconfirmed as the parent scope, then add the other if statements below that.

But if that doesn't work, then you need to change D < i_buyThreshold) to D[1] < i_buyThreshold) and change stoch_upTrend = D > D[1] to stoch_upTrend = D[1] > D[2]. That way you are looking back at the previous bar to check if condition was met, and this bar will have been closed already. Since the bar you are looking at has already closed, it will not change. It is either true or not true. As a result you also would not need the barstate.isconfirmed as part of the if statement.

Dharman
  • 30,962
  • 25
  • 85
  • 135
tommyf1001
  • 11
  • 1