Итератор в цикле считается последовательной формой?

#pine-script

#сосновый сценарий

Вопрос:

Похоже, в скрипте pine есть ошибка, из-за которой сломался индикатор, который я написал. Ранее (до ~ октября 2020 года) у меня был индикатор, который выполнял некоторые вычисления внутри цикла for с использованием функции ema. Теперь Pine Script выдает ошибку, когда я пытаюсь добавить свой скрипт:

Сбой операции добавления в график, причина: строка 21: не удается вызвать ’ema’ с аргументами (series [float], series[integer]); доступные перегрузки: ema(series [float], integer) => series[float]

Вот пример того, что я пытаюсь запустить:

 //@version=4
study("My Script")
emastep = 5
emashort = 5
thisema = 0.0
emanum = 10
lastema = ema(close, emashort)
for i = 1 to emanum
    thisema := ema(close, round(i*emastep))
plot(thisema)
 

Проблема, по-видимому, заключается в «я» в этой ema(close, round(i*emastep)) части. Что интересно, так это образец скрипта из руководства pine script (https://www.tradingview.com/pine-script-docs/en/v4/language/Expressions_declarations_and_statements.html#for-statement ) также выдает ту же ошибку сейчас. Следующий пример из приведенной выше ссылки не работает:

 //@version=4
study("RMA in for loop")
sum = 0.0
for i = 1 to 2
    sum := sum   rma(close, i)
plot(sum)
 

Есть мысли о том, как обойти это? i в цикле for не должен быть формой серии, верно?

Ответ №1:

Ошибка, вызвавшая ошибку, как я и подозревал, связана с i итератором в for цикле. Если я создам свой собственный итератор и использую его, все работает нормально. Это мое решение, которое я придумал:

 //@version=4
study("My Script")
emastep = 5
emashort = 5
thisema = 0.0
emanum = 10
lastema = ema(close, emashort)
iter = 1
for i = 1 to emanum
    thisema := ema(close, round(iter*emastep))
    iter := iter   1 
plot(thisema)
 

Надеюсь, это поможет другим.

Комментарии:

1. Хорошее решение! Я удивлен, что это работает, потому что ваша переменная iter также является изменяемой переменной. Хорошая находка 🙂 Я поддержал ваше решение.

Ответ №2:

Несколько функций pine поддерживают аргументы динамической длины.
Однако rma() это не один из них.

Эта функция никогда не принимала динамическую длину аргумента, также не в v3 Pine.
То, что он не выдает ошибку в v3, не означает, что вычисление правильное.
Этот пример вычисляет rma в v3 один раз в цикле и один раз с фиксированным значением, но оба должны привести к rma(close, 15) .

 //@version=3
study("RMA fixed length vs variable length")

sum = 0.0
i = 0

for i = 1 to 15
    sum := rma(close, i)

plot(rma(close, 15), color=green)
plot(sum, color=red)
 

Оба должны возвращать значение rma длиной 15, но результаты сильно отличаются (= неверны) из-за использования неподдерживаемого ввода переменной длины.

переменная rma против фиксированной длины

В справочном руководстве по rma() показан пример вычисления rma в функции.
Вы можете использовать это в своем коде в качестве обходного пути.

 //@version=4
study("RMA in for loop")

// Built-in RMA
plot(rma(close, 15), color=color.green)

// The same on pine
pine_rma(src, length) =>
    alpha = 1/length
    sum = 0.0
    sum := na(sum[1]) ? sma(src, length) : alpha * src   (1 - alpha) * nz(sum[1])

plot(pine_rma(close, 15), color=color.red)


// Your code with built-in rma(), this will NOT work
// sum = 0.0
// for i = 1 to 2
//     sum := sum   rma(close, i)

// plot(sum, color.blue)


// Your code with pine_rma(), this will work
sum = 0.0
for i = 1 to 2
    sum := sum   pine_rma(close, i)

plot(sum, color.blue)
 

Обратите внимание, как красная и зеленая строки в этом коде идентичны (перекрываются).
Это доказывает, что результат pine_rma() идентичен встроенному rma() , но с дополнительным преимуществом принятия изменяемых переменных в качестве входных данных, что приводит к синей линии, как вы и предполагали.

Работает

Комментарии:

1. Спасибо за советы. Я предполагаю, что что-то изменилось, потому i что итератор в цикле должен быть не динамическим, а статическим. На самом деле я придумал обходной путь, подробно описанный ниже.