1

My code on trading view pine script is returning me "NaN" for strategy.position_avg_price when alert is triggered.

It works when I back test it. However when I test it live, it is giving me "NaN" value.

Alert message with "NaN" message

I am trying to place a stop loss using strategy.position_avg_price mins or plus nLoss However, strategy.position_avg_price keeps returning me "NaN" when alert is triggered after I enter the trade.

This is how I define my stop-loss value

//Define stop loss levels for long position
long_stop_level := strategy.position_avg_price - nLoss//close-nLoss

This is how I enter a trade.

//Enters long trade
if entry_long
    alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize) 
    alert(alert_string, alert.freq_once_per_bar_close)

I expect strategy.position_avg_price to return the correct value just as I had backtested it.

This is how my alert setting is. Alert setting on tradingview

I am willing to pay a small amount for the correct solution.

Sharing my entire code here so that u guys can backtest it yourself. Run this on 1 minute chart and set alert:

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
//@version=5
strategy('Testing Alert for NaN error', overlay=true, currency=currency.USD, initial_capital=10000, slippage=15)

//==============================================================================

//==============================================================================
//BACKTEST DATE RANGE - Select Dates
//==============================================================================
//Input for date window
startDay = input.int(defval=9, title='Start Day', minval=1, maxval=31)
startMonth = input.int(defval=1, title='Start Month', minval=1, maxval=12)
startYear = input.int(defval=2023, title='Start Year', minval=1970)
endDay = input.int(defval=1, title='End Day', minval=1, maxval=31)
endMonth = input.int(defval=1, title='End Month', minval=1, maxval=12)
endYear = input.int(defval=2025, title='End Year', minval=1970)

//Submit date window
startDate = timestamp(startYear, startMonth, startDay, 00, 00, 00)  // backtest start date
endDate = timestamp(endYear, endMonth, endDay, 23, 59, 59)  // backtest end date
dateRange() =>  // specify where date range is true
    time >= startDate and time <= endDate ? true : false



//==============================================================================

//==============================================================================
//MONEY MANAGEMENT - ATR (Take profit at 1.0 ATR and Stop Loss at 1.5 ATR)
//==============================================================================
//Enter intial capital and percentage risk inputs
percentRisk = input.float(title='Risk Per Trade', defval=0.1, minval=0.001, maxval=0.1)

//Enter ATR inputs

atrLength = input(title='atr' , defval=10)
atrMulti_Profit = input(title='Atr Profit Multiple', defval=1.0)
atrMulti_Loss = input(title='Atr Loss Multiple', defval=20)

//ATR function
truncate(number, decimals) =>
    factor = math.pow(10, decimals)
    int(number * factor) / factor
atr = truncate(ta.atr(atrLength), 5)

//Get position size
posSize = math.round(strategy.initial_capital * percentRisk / (atrMulti_Loss * atr))*0.01
//==============================================================================

//==============================================================================
//INDICATOR 1 - Trigger (C1 - Confirmation 1)
//==============================================================================
//Donchian Channel



basePeriods = input.int(5, minval=1, title='Base Line Length')

donchian(len) =>
    math.avg(ta.lowest(len), ta.highest(len))

IchimokubaseLine = donchian(basePeriods)

plot(IchimokubaseLine, color=color.new(color.white, 0), title='Ichimoku baseline')


Ind_1_L = close > IchimokubaseLine[1]
Ind_1_S = close < IchimokubaseLine[1]

//==============================================================================


//==============================================================================
//ENTRY CONDITIONS - Submit Orders
//==============================================================================
//Asks user if want to include Long/Short trigger condition
ShortSignal = input(false, 'Tick to include Short Trades?')


//Long and short strategy conditions
entry_long = strategy.position_size <= 0 and dateRange() and Ind_1_L 
entry_short = strategy.position_size >= 0 and dateRange() and Ind_1_S and ShortSignal
plotshape(entry_long, color=color.new(color.lime, 0), style=shape.arrowup, location=location.belowbar, text='Buy')
plotshape(entry_short, color=color.new(color.red, 0), style=shape.arrowdown, location=location.abovebar, text='Sell')

//Store ATR and Price upon entry of trade.
entry_atr = float(0.0)  //set float
entry_atr := strategy.position_size == 0 or entry_long or entry_short ? atr : entry_atr[1]

alertcondition(close >= open, title='Alert on Green Bar', message='Green Bar!')

//Submit long and short orders based on entry conditions
if entry_long
    strategy.entry(id='Long Entry 1', direction=strategy.long, qty=posSize, when=dateRange())
if entry_short
    strategy.entry(id='Short Entry 1', direction=strategy.short, qty=posSize, when=dateRange())
//==============================================================================

//==============================================================================
//TAKE PROFIT & STOP LOSS VALUES
//==============================================================================
//Calculate stop loss and take profit distance (in price)
nLoss = entry_atr * atrMulti_Loss

//Find long take profit and stop loss levels
long_stop_level = float(0.0)  //set float
long_stop_level := strategy.position_avg_price - nLoss//close-nLoss

//Find short take profit and stop loss levels
short_stop_level = float(0.0)  //set float
short_stop_level := strategy.position_avg_price + nLoss//close+nLoss

plotchar(strategy.position_avg_price , 'Strategy Position Avg_Price', '', location=location.top)
plotchar(strategy.position_avg_price[1] , 'Strategy Position Avg_Price[1]', '', location=location.top)
plotchar(strategy.opentrades , 'Strategy Open Trade', '', location=location.top)

//Plot stop loss and profit level on graph; hide levels when no trade
plot(strategy.position_size <= 0 or entry_long or entry_short ? na : long_stop_level, color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2)
plot(strategy.position_size >= 0 or entry_long or entry_short ? na : short_stop_level, color=color.new(color.red, 0), style=plot.style_linebr, linewidth=2)

//==============================================================================



//==============================================================================

//==============================================================================
//ALERT CONDITIONS - For Autotrading (pineconnector)
//==============================================================================
// PineConnector Settings
pc_id = input.string(title='License ID', defval='6608763584725', group='PineConnector Settings', tooltip='This is your PineConnector license ID')
pc_prefix = input.string(title='MetaTrader Prefix', defval='', group='PineConnector Settings', tooltip='This is your broker\'s MetaTrader symbol prefix')
pc_suffix = input.string(title='MetaTrader Suffix', defval='', group='PineConnector Settings', tooltip='This is your broker\'s MetaTrader symbol suffix')
pc_limit = input.bool(title='Use Limit Order?', defval=true, group='PineConnector Settings', tooltip='If true a limit order will be used, if false a market order will be used')
//pc_spread = input(title="Spread (Broker comm)", defval=1, type=input.float, group="PineConnector Settings", tooltip="This is your broker's spread where they earn commissions")

// Generate PineConnector alert string
plotchar(long_stop_level, 'Long_Stop_Level', '', location=location.top)
plotchar(short_stop_level, 'Short_Stop_Level', '', location=location.top)
plotchar(Ind_1_S, 'Donchain Short', '', location=location.top)
plotchar(Ind_1_L, 'Donchain Long', '', location=location.top)





//pc_entry_alert(direction, price, sl, tp) =>
    //pc_id + "," + direction + "," + symbol + "," + price + "sl=" + tostring(sl) + ",tp=" + tostring(tp) + ",risk=" + tostring(posSize)
    //pc_id + "," + direction + "," + symbol + "," + price + "sl=" + tostring(sl) + "risk=" + tostring(pc_risk)

//sl_inp = ta.sma(close,5)
//stop_level = (strategy.position_avg_price == "NaN") ? (close * (1 - sl_inp)) : (strategy.position_avg_price * (1 - sl_inp))


var symbol = pc_prefix + syminfo.ticker + pc_suffix

//Close short position once Ind_1_L is triggered
if Ind_1_L and strategy.position_size<0
    alert_stringCloseShort = pc_id + ',' + 'closeshort' + ',' + symbol
    alert(alert_stringCloseShort, alert.freq_once_per_bar_close)

//Enters long trade
if entry_long
    alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize) 
    alert(alert_string, alert.freq_once_per_bar_close)
 

//Close Long position once Ind_1_S is triggered
if Ind_1_S and strategy.position_size>0
    alert_stringCloseLong = pc_id + ',' + 'closelong' + ',' + symbol
    alert(alert_stringCloseLong, alert.freq_once_per_bar_close)

//Enters short trade
if entry_short
    alert_string = pc_id + ',' + 'sell' + ',' + symbol + ',' + 'sl=' + str.tostring(short_stop_level) + ',' + 'risk=' + str.tostring(posSize)
    alert(alert_string, alert.freq_once_per_bar_close)



//==============================================================================
//EXIT CONDITIONS - Submit Orders
//==============================================================================
//Submit exit orders on static profit and loss (Exits based on the stoploss set)
strategy.exit('TP/SL 1', 'Long Entry 1', stop=long_stop_level, limit=na)
strategy.exit('TP/SL 1', 'Short Entry 1', stop=short_stop_level, limit=na)

strategy.exit('TP/SL 2', 'Long Entry 2', stop=long_stop_level, limit=na)
strategy.exit('TP/SL 2', 'Short Entry 2', stop=short_stop_level, limit=na)

//Submit exit orders on exit indicator - Exit 1 & 2 (Exits based on our indicator)
strategy.close(id='Long Entry 1', comment='Exit 1 L1', when=Ind_1_S and dateRange())
strategy.close(id='Short Entry 1', comment='Exit 1 S1', when=Ind_1_L and dateRange())

//==============================================================================
Marcus
  • 11
  • 2

1 Answers1

1

The reason of the error is simple. When you call strategy.entry the position will not immediatelly opened. The script engine just send entry order and the position will be opened on next script update. Only on this update there are strategy.position_avg_price will be not NaN. You can try to use different condition for issue the alert:

//Enters long trade
if strategy.position_size[1] <= 0 and strategy.position_size > 0
    alert_string = pc_id + ',' + 'buy' + ',' + symbol + ',' + 'sl=' + str.tostring(long_stop_level) + ',' + 'risk=' + str.tostring(posSize) 
    strategy.entry(id='Long Entry 1', direction=strategy.long, qty=posSize, when=dateRange(), alert_message = alert_string)
Andrey D
  • 1,534
  • 1
  • 5
  • 7