Search code examples
pine-scriptpine-script-v5

Why does the "on-chart" close work in Mansfield but request.security() does not?


I got a script to calculate the Mansfield Relative Strength (MRS) and it works like a charm. However, I am trying to build a more complex indicator that uses the MRS in conjunction with other indicators to limit the number of times it prints. Using the script below with AAPL loaded in the chart, the MRS is properly displayed. (using "OnScreen" as the source of the close values)

However, if you follow the instructions "// Comment out lines above and uncomment lines below" the MRS is just flat wrong. All this does is switch the source of the close values from what is on the chart to AAPL retrieved using "request.security()".

Have tried as many different approaches to fixing this as I can think of. Either I am doing something wrong (likely) or there is something inherent in pinescript that prevents using the values obtained through request.security() in the way I am trying to use them. (less likely)

//@version=5
// Use this indicator to compare how security is performing in compare with prefered index (SPX by default). 
// > 0 outperforming,   < 0 underperforming
// Works best for weekly, but can be applied to monthly and daily charts. It will be rather useless to use it in smaller timeframes
// Apply it to SPX, industry index, sector index or other security in similar sector

indicator('Mansfield - Why wrong')
OnScreen = close
BehindScenes = request.security(symbol = "AAPL", timeframe = timeframe.period, expression = close)

index = input.symbol(title='Index', defval='SPY')

len_daily = input(title='MA length for Daily', defval=150)
len = len_daily

ma_func(val3, length) =>
    ta.sma(val3, length)

calc_mrs_func(ind, length, symbol) =>
    ( symbol / request.security(ind, timeframe.period, symbol) / ma_func((symbol / request.security(ind, timeframe.period, symbol)), length) - 1) * 10

mrs_index = calc_mrs_func(index, len, OnScreen)
c = math.sign(mrs_index)

mrs_index2 = calc_mrs_func(index, len, BehindScenes)
c2 = math.sign(mrs_index2)


color_3 = color.new(color.green, 70)
color_4 = color.new(color.red, 70)
color_7 = color.new(color.gray, 90)
bgcolor(c == 1 ? color_3 : c == -1 ? color_4 : color_7)
plot(mrs_index, linewidth=3, title='MRS index')
// Comment out lines above and uncomment lines below
//bgcolor(c2 == 1 ? color_3 : c2 == -1 ? color_4 : color_7)
//plot(mrs_index2, linewidth=3, title='MRS index')
hline(price=0, linestyle=hline.style_dashed, title='Zero baseline')

plot(OnScreen, color=color.green, linewidth = 8)
plot(BehindScenes, color=color.red, linewidth = 3)

By the way, the last two lines plot the two separately obtained sets of close values and you can see that they are a perfect match


Solution

  • When you pass BehindScenes here as a symbol, you ask for a close price from AAPL, and so in your expression you want to divide the close price of AAPL by the close price of AAPL requested through another symbol (SPY).

    calc_mrs_func(ind, length, symbol) =>
        ( symbol / request.security(ind, timeframe.period, symbol) / ma_func((symbol / request.security(ind, timeframe.period, symbol)), length) - 1) * 10
    

    That is, in this case, the close price from AAPL will always be requested, and when you use the second security context, you do not get the SPY price, but again you get the AAPL price only by going additionally to the SPY context.

    Try this with BehindScenes as a symbol

    calc_mrs_func(ind, length, symbol) =>
        ( symbol / request.security(ind, timeframe.period, close) / ma_func((symbol / request.security(ind, timeframe.period, close)), length) - 1) * 10