#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
в функции.
Вы можете использовать это в своем коде в качестве обходного пути.
//@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
что итератор в цикле должен быть не динамическим, а статическим. На самом деле я придумал обходной путь, подробно описанный ниже.