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?
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.