保持敬畏之心
交易是一场持久战

Pine Script(233):判断策略是多头、空头还是非多非空

#Pine Script入门教学

判断策略当前是做多还是做空

当一个策略在图表上分析并进行交易时,它的市场持仓会发生变化。我们常常想知道策略当前是做多还是做空。

但在其他一些场景下,我们需要的恰恰是知道策略不是多头或不是空头。例如,我们可能只希望在尚未持有多仓时才提交一笔做多订单。要实现这一点,我们需要使用 strategy.position_size 变量。

判断非多头状态(即空仓或持有空仓)

这个辅助函数可以告诉我们策略当前是否没有持有多头仓位:

// IsNotLong() 函数:当策略处于空仓或持有空仓状态时,返回 `true`。
// 当策略持有多仓时,返回 `false`。
IsNotLong() =>
    strategy.position_size <= 0

在这个 IsNotLong() 函数内部,我们检查 strategy.position_size 变量是否小于或等于零。如果是,就意味着策略当前持有空仓或处于空仓状态,但肯定没有多头仓位,因此函数返回 true。当策略确实持有多头仓位时,strategy.position_size 的值会是一个正数,这时 IsNotLong() 函数就会返回 false

在我们的策略脚本中加入以上函数后,就可以在多处使用它了。例如,我们可以使用 bgcolor() 函数,将所有非多头状态下的K线背景涂上颜色:

// 每当策略不持有多仓时,就将背景色设为紫红色
bgcolor(IsNotLong() ? color.new(color.fuchsia, 90) : na)

当我们知道策略不持有多仓时,我们就可以利用这个信息来控制订单的生成。假设我们只希望在没有多仓的情况下才开立新的多头仓位。也就是说,策略可以从空仓变多仓,或从空头反手做多,但不能对已有的多仓进行加仓。

要实现这一点,我们可以在调用 strategy.entry() 函数之前,先检查 IsNotLong() 的返回值:

// 只有在当前不持有多仓时才做多
if IsNotLong() and close > ta.sma(close, 10)
	strategy.entry("Enter Long", strategy.long)

判断非空头状态(即持有多仓或空仓)

另一个选项是检查策略是否没有持有空头仓位。下面是相应的辅助函数:

// IsNotShort() 函数:当策略持有多仓或处于空仓状态时,返回 `true`。
// 当策略持有空仓时,返回 `false`。
IsNotShort() =>
    strategy.position_size >= 0

在这个 IsNotShort() 函数内部,我们判断 strategy.position_size 变量是否大于或等于零。如果是,就说明策略当前要么持有多仓,要么处于空仓状态,因此函数返回 true。如果策略确实持有空仓,strategy.position_size 的值会是负数,这时 IsNotShort() 函数就会返回 false

特别要注意:IsNotLong()IsNotShort() 这两个函数并非完全的非此即彼。因为当策略处于空仓状态时(strategy.position_size == 0),两个函数都会返回 true

同样,在策略代码中加入 IsNotShort() 函数后,我们也可以灵活运用它。例如,我们可以将所有非空头状态下的K线背景涂上颜色:

// 当策略不持有空仓时,将背景设为深色
bgcolor(IsNotShort() ? color.new(color.black, 85) : na)

我们更常将 IsNotShort() 用于订单生成逻辑。假设我们不希望在已持有空仓时再提交做空交易。这意味着,脚本可以从空仓做空,或从多头反手做空,但不能对已有的空仓进行加仓。所以,在提交做空入场订单前,我们先检查 IsNotShort()

// 只有在当前不持有空仓时才开空仓
if IsNotShort() and close < ta.ema(close, 20)
	strategy.entry("Enter Short", strategy.short)

应用场景

了解策略是否处于非多头或非空头状态,在很多方面都非常有用。比如在尚未持有空仓时,我们可以提交一个空头停止入场单,这个订单要么会开立一个新仓位,要么会将多仓反手做空,但它不会对已有的空仓进行加仓。结合这一点,我们还可以在尚未持有多仓时,在图表上绘制出多头停止入场单的价格水平,并在策略做多后停止绘制。

如果我们只在策略非多头或非空头时才执行相应的开仓交易,我们就不必关闭策略的 pyramiding(金字塔加仓)功能。这意味着,我们仍然可以通过其他入场逻辑对仓位进行加仓。

此外,当我们知道策略不持有多仓时,可以提交一个做空入场交易。这样,我们要么开立一个新的空仓,要么对已有的空仓进行加仓,但它不会将一个多头仓位反手做空。我们还可以为初始入场和加仓设置不同的条件,例如初始入场条件可以非常严格,而一旦持有多仓,后续的加仓条件就可以设置得更灵活一些。

示例策略

让我们通过一个完整的策略来看看如何使用 IsNotLong()IsNotShort() 函数。下方的脚本基于相对强弱指数(RSI)进行交易。当RSI进入超卖区(30)时做多,进入超买区(70)时做空。

当脚本不持有多仓时,我们将图表背景设为蓝色。当脚本不持有空仓时,我们将K线设为橙色。

策略的完整代码如下:

//@version=5
strategy(title="非多头或非空头示例")

// 辅助函数:判断是否“非多头”
IsNotLong() => strategy.position_size <= 0
// 辅助函数:判断是否“非空头”
IsNotShort() => strategy.position_size >= 0

// 计算RSI
rsiValue = ta.rsi(close, 7)
// 绘制RSI及超买超卖线
plot(rsiValue, color=color.fuchsia, title="RSI")
hline(30, title="超卖线")
hline(70, title="超买线")

// 当RSI进入超买超卖区时生成交易
if ta.crossunder(rsiValue, 30)
    strategy.entry("Enter Long", strategy.long)
if ta.crossover(rsiValue, 70)
    strategy.entry("Enter Short", strategy.short)

// 当策略不持有多仓时,背景为蓝色;持有多仓时,背景为绿色
bgcolor(color=IsNotLong() ? color.new(color.blue, 85) : 
     color.new(color.green, 70))

// 当策略不持有空仓时,K线为橙色;持有空仓时,K线为红色
barcolor(color=IsNotShort() ? color.orange : color.red)

我们首先定义了 IsNotLong()IsNotShort() 这两个辅助函数。然后,我们计算并绘制了RSI指标及其超买超卖线。入场逻辑是在RSI进入相应区域时开仓。

接着,我们通过 bgcolor() 函数来设定背景颜色:

// 当策略不持有多仓时,背景为蓝色;持有多仓时,背景为绿色
bgcolor(color=IsNotLong() ? color.new(color.blue, 85) : color.new(color.green, 70))

这里我们使用条件运算符(?:)。当 IsNotLong() 返回 true 时(即策略处于空仓或持有空仓),背景色设为蓝色。当它返回 false 时(即策略持有多仓),背景色设为绿色。

然后,我们通过 barcolor() 函数来设定K线的颜色:

// 当策略不持有空仓时,K线为橙色;持有空仓时,K线为红色
barcolor(color=IsNotShort() ? color.orange : color.red)

同样,当 IsNotShort() 返回 true 时(即策略持有多仓或空仓),K线颜色设为橙色。当它返回 false 时(即策略持有空仓),K线颜色设为红色。

在图表上,当没有多头仓位时,策略会创建蓝色的背景。当我们没有空头仓位时,我们会看到橙色的K线:

你可以亲自试试这个策略,以便更好地理解非多头和非空头的含义。

简单总结一下:策略通过 strategy.position_size 变量来检查其当前持仓状态。当这个变量的值为零或负数时,策略没有持有多头仓位;当这个变量的值为零或正数时,策略没有持有空头仓位。

判断策略是否持有多仓或空仓

当一个策略在图表上进行回测时,它会根据我们编写的规则建立多头和空头仓位。对于策略脚本来说,了解其自身的市场持仓状态通常非常有用。这样,我们就可以基于这些信息来编写决策逻辑。

我们使用 strategy.position_size 这个内置变量来获取策略的市场持仓状态。下面,就让我们来看看如何通过这个变量来判断策略当前是持有多仓还是空仓。

判断是否持有多头仓位

我们可以创建一个简洁的自定义函数,来判断策略当前是否持有多头仓位:

// IsLong() 函数在策略持有多头仓位时返回 'true',
// 当策略持有空仓或空头仓位时返回 'false'。
IsLong() =>
    strategy.position_size > 0

在这个 IsLong() 函数内部,我们判断了 strategy.position_size 变量的值是否大于零。当这个变量返回一个正数时,就意味着策略当前持有多头仓位,此时该函数返回 true。当策略没有多头仓位时(即持有空仓或空头仓位),IsLong() 函数则返回 false

在我们的策略代码中加入以上函数后,就可以在多处调用 IsLong() 了。例如,我们可以通过 barcolor() 函数,将所有持有多头仓位的K线都标记为绿色:

// 当策略持有多仓时,将K线颜色设为绿色
barcolor(IsLong() ? color.green : na)

更常见的用法是将持仓状态与订单逻辑相结合。比如说,我们想在价格跌破20周期EMA时平掉所有多头交易。为此,我们可以将 IsLong()strategy.close_all() 函数结合起来:

// 如果当前持有多仓,并且价格跌破20周期EMA,则平掉所有仓位
if IsLong() and close < ta.ema(close, 20)
	strategy.close_all()

判断是否持有空头仓位

我们也可以用同样的方法来判断策略当前是否持有空仓。相应的自定义函数如下:

// IsShort() 函数在策略持有空头仓位时返回 'true',
// 当策略持有空仓或多头仓位时返回 'false'。
IsShort() =>
    strategy.position_size < 0

在这个 IsShort() 函数内部,我们判断 strategy.position_size 变量的值是否小于零。当这个变量为负数时,就代表策略持有一个空头仓位,此时函数返回 true,否则返回 false

同样,将这个函数加入策略代码后,我们就可以灵活运用了。例如,我们可以用 bgcolor() 函数将所有持有空头仓位期间的图表背景都染成红色:

// 每当策略持有空仓时,将背景色设为红色
bgcolor(IsShort() ? color.new(color.red, 80) : na)

在订单管理方面,假设我们想在价格突破近期高点时平掉所有空头交易。我们可以将 IsShort()strategy.close_all() 结合:

// 如果当前持有空仓,并且价格突破了20周期内的最高价,则平仓
if IsShort() and high > ta.highest(high, 20)[1]
	strategy.close_all()

持仓状态信息的多种应用方式

当一个交易策略能够知道自己是持有多仓还是空仓时,它就可以利用这个信息做很多事情。比如根据市场状况,动态调整多头或空头的止盈目标;更新多头或空头的止损价格(这也是实现移动止损的基础);在与当前持仓相同的方向上寻找加仓的机会;或者基于当前持仓状态使用不同的入场规则,例如在持有多仓时寻找空头信号来反转仓位。

它还能用于防止金字塔式加仓(即在已有仓位时,不再开立同向的新仓位)、为多头或空头持仓期间的图表背景上色以便直观地观察持仓状态、防止反向开仓(即在已有仓位时不生成反方向的开仓信号)、在图表上只绘制当前持仓方向的止损和止盈线并在平仓后停止绘制。

此外,我们还可以判断策略在某个特定时间点(如收盘前)是否仍有持仓,并据此执行相应的平仓操作;或者计算多头或空头仓位的持仓时间或K线数,以实现时间止损,或在持仓一段时间后进行加仓。

示例策略

让我们看一个在完整策略中同时使用 IsLong()IsShort() 函数的例子。下面的脚本在价格突破近期高点时做多,在跌破近期低点时做空。

我们通过 IsLong()IsShort() 函数来为图表的K线上色,从而可以轻松地识别策略的持仓方向。策略的完整代码如下:

//@version=5
strategy(title="Long or short position example", overlay=true)

// IsLong() 函数在策略持有多头仓位时返回 'true',
// 当脚本做空或空仓时返回 'false'。
IsLong() =>
    strategy.position_size > 0

// IsShort() 函数在策略持有空头仓位时返回 'true',
// 当脚本做多或空仓时返回 'false'。
IsShort() =>
    strategy.position_size < 0

// 计算并绘制近期高点和低点
highestHigh = ta.highest(high, 20)[1]
lowestLow   = ta.lowest(low, 20)[1]
plot(highestHigh, color=color.green, title="Highest High")
plot(lowestLow, color=color.red, title="Lowest Low")

// 交易高低点的突破
if high > highestHigh
    strategy.entry("Enter Long", strategy.long)
if low < lowestLow
    strategy.entry("Enter Short", strategy.short)

// 根据多头、空头和空仓状态为K线上色
barcolor(IsLong() ? color.green : 
     IsShort() ? color.red : 
         color.blue)

我们首先用 strategy() 函数配置脚本属性。然后,我们定义了前面讨论过的 IsLong()IsShort() 函数。

接着,代码计算并绘制了20周期的最高价和最低价。然后是两个 if 语句,分别在价格突破近期高点和跌破近期低点时,通过 strategy.entry() 开立多头和空头仓位。

最后,也是最关键的部分,我们根据策略的持仓状态为K线上色:

// 根据多头、空头和空仓状态为K线上色
barcolor(IsLong() ? color.green : 
     IsShort() ? color.red : 
         color.blue)

这里 barcolor() 函数根据一个嵌套的条件来决定K线的颜色。首先,它检查 IsLong() 是否为 true。如果是,说明持有多仓,K线被设为绿色。如果不是,它接着检查 IsShort() 是否为 true。如果是,说明持有空仓,K线被设为红色。如果两者都不是,说明策略当前空仓,K线则被设为蓝色。

当这个策略在图表上运行时,它会在价格突破近期高点时做多,在跌破近期低点时做空。绿色和红色的K线清晰地标示出了脚本的持仓状态:

简单总结一下:一个策略通过 strategy.position_size 这个内置变量来判断其是持有多仓还是空仓。当这个变量的值大于零时,策略持有多仓;当它的值小于零时,策略持有空仓。

赞(0)
未经允许不得转载:图道交易 » Pine Script(233):判断策略是多头、空头还是非多非空
分享到

评论 抢沙发

登录

找回密码

注册