#pine-script
#сценарий сосны
Вопрос:
Я пытаюсь написать индикатор, который выдает несколько истинных условий для построенных фигур. Например, пересечение MACD в сочетании с условием ADX, которое выглядит примерно так:
study("MACD on chart", shorttitle="MACD on Chart", overlay=true)
// MACD
// Inputs
fast_length = input(title="Fast Length", type=input.integer, defval=6)
slow_length = input(title="Slow Length", type=input.integer, defval=13)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 4)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false)
// Calculation
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
// hist = macd - signal
// DMI
// Inputs
lensig = input(14, title="ADX Smoothing", minval=1, maxval=50)
len = input(14, minval=1, title="DI Length")
// Calculation
up = change(high)
down = -change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = rma(tr, len)
plus = fixnan(100 * rma(plusDM, len) / trur)
minus = fixnan(100 * rma(minusDM, len) / trur)
sum = plus minus
adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), lensig)
longCondition = macd >= signal and adx >= 20
plotshape(longCondition, style=shape.labelup, size=size.tiny, color=color.new(color.green, 60), location=location.belowbar)
shortCondition = signal <= macd and adx >= 20
plotshape(shortCondition, style=shape.labeldown, size=size.tiny, color=color.new(color.red, 60), location=location.abovebar)
К сожалению, это приводит к появлению нескольких фигур на графике, потому что условие выполняется для, ну, нескольких свечей. Вместо этого хотелось бы, чтобы только первое вхождение, в котором новое условие выполняется заново, имело форму.
Чтобы предотвратить один вопрос: нет, я не могу использовать crossover
в этом случае, потому что то, как я использую его в скрипте, приводит к неправильным результатам. Пересечение выполняется только для свечи, которую оно фактически пересекает, но условие настроено таким образом, что фактическое пересечение не будет правильной триггерной свечой. Надеюсь, это имеет смысл.
Вот наглядный пример:
Комментарии:
1. Ваш вопрос не совсем ясен. Вы имеете в виду, что хотите иметь ровно одну фигуру на всем графике? То есть, фигура рисуется только при первом выполнении условия, но никогда больше после этого первого случая? Даже если условие снова станет истинным после этого первого появления? Не могли бы вы обновить свой вопрос аннотированным скриншотом того, что вы ищете? И, если возможно, также весь сценарий, который у вас есть на данный момент, чтобы мы могли его оценить? Спасибо.
2. Конечно, нет. Только в первый раз условие выполняется снова последовательно. Я просто не хочу, чтобы это повторялось несколько раз подряд, а затем, когда условие выполняется снова, снова только один график.
3. Не могли бы вы опубликовать сценарий, который показывает, что вы имеете в виду? А также тикер таймфрейм, на котором это происходит. Я уверен, что смогу решить это за вас.
4. Спасибо за редактирование. Я пытаюсь подготовить для вас минимальный пример. Ценю вашу помощь здесь.
5. Я изменил вопрос, чтобы сделать его более понятным, и добавил также диаграмму, которая должна помочь объяснить проблему.
Ответ №1:
Этот код сделает то, что вы ищете.
Я вижу, что вы вычисляете macd и dmi, которые также существуют как встроенные функции.
Вы можете найти еще много в справочнике по языку сценариев Pine.
Кроме того, вам не нужно создавать a color.new()
, чтобы получить прозрачность plotshape()
, потому что она доступна в качестве параметра.
//@version=4
study("MACD on chart", shorttitle="MACD on Chart", overlay=true)
var bool longCondition = na
var bool shortCondition = na
var bool showLong = na
var bool showShort = na
var bool showOnlyFirstSignal = input(true, "Show only first signal", input.bool)
// MACD
// Inputs
fast_length = input(title="Fast Length", type=input.integer, defval=6)
slow_length = input(title="Slow Length", type=input.integer, defval=13)
src = input(title="Source", type=input.source, defval=close)
signal_length = input(title="Signal Smoothing", type=input.integer, defval= 4, minval = 1, maxval = 50)
sma_source = input(title="Simple MA(Oscillator)", type=input.bool, defval=false)
sma_signal = input(title="Simple MA(Signal Line)", type=input.bool, defval=false)
// Calculation
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
// hist = macd - signal
// DMI
// Inputs
lensig = input(14, title="ADX Smoothing", minval=1, maxval=50)
len = input(14, minval=1, title="DI Length")
// Calculation
up = change(high)
down = -change(low)
plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
trur = rma(tr, len)
plus = fixnan(100 * rma(plusDM, len) / trur)
minus = fixnan(100 * rma(minusDM, len) / trur)
sum = plus minus
adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), lensig)
longCondition := macd >= signal and adx >= 20
shortCondition := signal <= macd and adx >= 20
showLong := showOnlyFirstSignal ? longCondition and not longCondition[1] : longCondition
showShort := showOnlyFirstSignal ? shortCondition and not shortCondition[1] : shortCondition
plotshape(showLong, style=shape.labelup, size=size.tiny, color=color.green, transp=60, location=location.belowbar)
plotshape(showShort, style=shape.labeldown, size=size.tiny, color=color.red, transp=60, location=location.abovebar)
Редактировать: дополнительное объяснение, запрошенное в комментариях.
Краткая версия
showLong := showOnlyFirstSignal ? longCondition and not longCondition[1] : longCondition
Длинная версия
if showOnlyFirstSignal
// To show Long on the chart, the longCondition on the current bar must be true, but the longCondition on the previous bar must be false.
// So, as long as the longCondition on the previous bar stays true, showLong will be false, resulting in it not showing on the chart.
// The reverse is also true: showLong can only become true, if the longCondition on the previous bar was false.
showLong := longCondition and not longCondition[1]
else
showLong := longCondition
Возможно, вы также захотите взглянуть на троичный условный оператор, который может прояснить ситуацию для вас.
Комментарии:
1. Ого. На самом деле это имеет большой смысл. Спасибо, Бьорн. Можете ли вы объяснить мне, что
longCondition and not longCondition[1] : longCondition
это значит? Я понимаю это как короткую форму условия if. Итак, showLong имеет значение true, если longCondition имеет значение true, но не на 1 бар назад, иначе это просто longCondition . Это правильно?2. Правильно. Обновил мой ответ, чтобы объяснить, что вы спросили. На предыдущие значения в Pine ссылаются с
[n]
помощью гдеn
обозначает количество баров назад от текущего бара.3. Бьорн, это чудовищный ответ. Я не ожидал такой большой помощи. Большое вам спасибо. 🙂