我如何在 Pine Script 策略中使用条件?

How can I use conditionals in Pine Script strategies?

我正在尝试学习 Pine Script,对于我的第一个项目,我想基于以下代码构建一个简单的 Fisher 指标策略(由用户 HPotter 在 TradingView 上公开提供):

Length = input(10, minval=1)
xHL2 = hl2
xMaxH = highest(xHL2, Length)
xMinL = lowest(xHL2,Length)
nValue1 = 0.33 * 2 * ((xHL2 - xMinL) / (xMaxH - xMinL) - 0.5) + 0.67 * nz(nValue1[1])
nValue2 = iff(nValue1 > .99,  .999,
            iff(nValue1 < -.99, -.999, nValue1))
nFish = 0.5 * log((1 + nValue2) / (1 - nValue2)) + 0.5 * nz(nFish[1])
plot(nFish, color=green, title="Fisher")
plot(nz(nFish[1]), color=red, title="Trigger")

据我了解转换,您对一个值执行操作,绘制该值 (nFish),然后得到您的渔线。取回 nz(nFish[1]) 一根柱的值,绘制它,然后您得到触发线。当您在费雪线和触发线之间交叉时,您可能有兴趣在附近交易。当时我的想法是,在制定策略时要实施以下内容:

"If the Fisher Line is above the Trigger Line now AND IF the Fisher Line was below the Trigger Line on the last bar, enter a long position"

我试图通过以下方式实现:

if (nFish > nz(nFish[1]))
    if (nz(nFish[1]) < nz(nFish[2]))
        strategy.entry("Long", strategy.long)

但是,此代码无法生成任何头寸条目,并且对 if 语句中的值进行的任何修改也无法生成任何输出。我怎样才能修正我的条件来实现我想测试的想法?

首先,我不建议使用那么旧的源代码来学习。您可以从任何版本开始,但我建议您不要使用任何版本,除非您在源代码顶部附近看到 //@version=4。刚开始的时候犯了这个错误,改编了一个老剧本,过程中学习了一个过时的版本。

所以我在这里修改了 V4 的脚本,注意更改。一些语法上,声明变量时用var关键字来初始化某些变量。在 V4 中,您不能在声明中使用变量的同时声明变量。此外,我用三元替换了 iff,您会看到它更常用。

//@version=4
study(title="Fisher Transform Indicator by Ehlers - modified for V4", shorttitle="Fisher Transform Indicator by Ehlers")
length = input(title='Length', type=input.integer, defval=10, minval=1)

MaxHL2 = highest(hl2, length)
MinHL2 = lowest(hl2,  length)
var float nValue1 = na
var float nValue2 = na
var float nFish = na
nValue1 := 0.33 * 2 * ((hl2 - MinHL2) / (MaxHL2 - MinHL2) - 0.5) + 0.67 * nz(nValue1[1])
nValue2 := nValue1 > 0.99 ? 0.999 : nValue1 < -0.99 ?  -0.999 : nValue1
nFish := 0.5 * log((1 + nValue2) / (1 - nValue2)) + 0.5 * nz(nFish[1])
plot(nFish, color=color.green, title="Fisher")
plot(nFish[1], color=color.red, title="Trigger")

接下来,您描述的逻辑称为 crossover。这意味着第一个参数越过第二个参数。还要熟悉 crosscrossunder。因此,为了简单起见,我们可以将其调整为一种策略,我们可以制作一个交叉变量:

//@version=4
strategy(title="Fisher Transform Indicator by Ehlers - modified for V4", shorttitle="Fisher Transform Indicator by Ehlers")
length = input(title='Length', type=input.integer, defval=10, minval=1)

MaxHL2 = highest(hl2, length)
MinHL2 = lowest(hl2,  length)
var float nValue1 = na
var float nValue2 = na
var float nFish = na
nValue1 := 0.33 * 2 * ((hl2 - MinHL2) / (MaxHL2 - MinHL2) - 0.5) + 0.67 * nz(nValue1[1])
nValue2 := nValue1 > 0.99 ? 0.999 : nValue1 < -0.99 ?  -0.999 : nValue1
nFish := 0.5 * log((1 + nValue2) / (1 - nValue2)) + 0.5 * nz(nFish[1])

longCross = crossover(nFish,nFish[1])
shortCross = crossunder(nFish, nFish[1])
plotshapePosition = longCross ? nFish : na

strategy.entry('long', strategy.long, when=longCross)
strategy.close('long', when=shortCross)

plotshape(plotshapePosition, style=shape.circle, color=color.green, size=size.small, location=location.absolute)
plot(nFish, color=color.green, title="Fisher")
plot(nFish[1], color=color.red, title="Trigger")

注意我也做了一个crossunder,只是为了策略的退出。

另外我做了一个变量来绘制一个形状,当不使用overlay=true时,这是定位所必需的。 Sp plotshapePosition returns na 或当 crossovers 发生时的 nFish 值。 location.absolute 参数使用此级别来定位形状,而如果您在主图表上绘图,则并非绝对必要。 plotshape 在测试您的条件是否有效时会很方便。

此外,如果您确实有条件需要手动构建而不是使用像 crossover 这样的函数,您可以使用布尔逻辑来构建它。

longCondition = nFish > nFish[1] and nFish[1] < nFish[2]
strategy.entry("Long", strategy.long, when = longCondition)