Search code examples
pine-scriptpine-script-v5

It is recommended to extract the call from this scope in Pine Script


I'm trying to write a multi-asset indicator as a proof of example for myself. For this purpose I've chosen a very simplistic indicator that is supposed to display in a table the moving average cross status of 3 symbols in a table. Naturally, I'm running into an issue trying to extract ta.ema, for example, from the for loop below.

//@version=5
indicator("Multi Symbol EMA Cross", overlay=true)

// Define symbols and resolutions
symbols = input.string("BINANCE:BTCUSDT,BINANCE:ETHUSDT,BINANCE:LTCUSDT", "Symbols", inline="symbols")
res = input.string("D", "Resolution", inline="symbols")

// Split symbols into an array
symbolList = str.split(symbols, ",")

// Create a table with two columns and three rows
t = table.new(position.top_right, 2, 3)

// Loop through symbols and plot arrows
for i = 0 to array.size(symbolList) - 1
    // Get symbol name
    sym = array.get(symbolList, i)
    // Get close price of symbol
    price = request.security(sym, res, close)
    // Calculate EMAs
    ema1 = ta.ema(price, 9)
    ema2 = ta.ema(price, 21)
    // Update table cells
    table.cell(t, 0, i, sym)
    table.cell(t, 1, i, ta.crossup(ema1, ema2) ? "+" : ta.crossdown(ema1, ema2) ? "-" : "", ta.crossup(ema1, ema2) ? color.green : ta.crossdown(ema1, ema2) ? color.red : na)

Normally I'd try to do something with := to get it out of the for loop, but this means the price variable also has to be extracted. Writing a function also doesn't work, because then the warning says it should be called on each calculation for consistency. Since, in this example, I can't call requrest.security on the main scope because of the for loop, I have no idea how I'd solve this – other than just hardcoding everything.

What am I misunderstanding here about the way Pine Script works, and what can I do to resolve the issues?


Solution

  • Calling functions like ta.ema in local scopes is not a good idea. You might lose some history andm get not correct results. That is what the error message is telling you.

    The way I would do is: Create user inputs for each symbol.

    sym1 = input.symbol("BINANCE:BTCUSDT")
    sym2 = input.symbol("BINANCE:ETHUSDT")
    

    Then create a function to get the ema values

    get_ema(p_sym) =>
        ema1 = ta.ema(close, 9)
        ema2 = ta.ema(close, 21)
        [htf_ema1, htf_ema2] = request.security(p_sym, res, [ema1, ema2]
    

    And then you would call this function n times for each symbol.

    [sym1_ema1, sym1_ema2] = get_ema(sym1)
    [sym2_ema1, sym2_ema2] = get_ema(sym2)
    

    Now, ta.ema will be called in the global scope. Then handle the table maybe in another function.