绘制首先满足条件但不在连续蜡烛上的形状?

Plotting shapes where condition is met first, but not on consecutive candles?

我正在尝试编写一个指标,为绘制的形状生成多个真实条件。例如,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,因为我在脚本中使用它的方式会产生错误的结果。交叉仅在它实际交叉的蜡烛上为真,但条件以某种方式设置,即实际交叉不会是正确的触发蜡烛。我希望这是有道理的。

这是一个视觉示例:

这段代码可以满足您的需求。
我看到您正在计算 macd and dmi,它也作为内置函数存在。
您可以在 Pine Script Language Reference.
中找到更多信息 此外,您无需创建 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

您可能还想看一下 ternary conditional operator,这可能会为您进一步解决问题。