我们已经学会了用if
语句来做“如果…就…”的判断。但这只能解决单层逻辑。在真实的交易策略里,我们的决策过程往往是多层次的,就像一个“决策树”。
比如,“如果成交量放大了,我们再去看价格有没有突破”。这种“如果A成立,再去看B是否成立”的逻辑,就需要用到if
语句的进阶技巧——嵌套if
语句。
嵌套if
的两种基本模式
你可以把嵌套if
理解为在if
语句的“管辖范围”内,再放一个if
语句,从而形成逻辑上的层级关系。
模式一:“层层深入”的if
这就像一个多重安检,只有通过了第一道安检(外层if
为true
),你才有资格接受第二道安检(内层if
)。
// 代码结构
if 外部条件
// ...外部条件为true时执行的代码...
if 内部条件
// 仅当“外部条件”和“内部条件”都为true时,这里的代码才会被执行
模式二:“非此即彼,再判断”的else
嵌套
这就像一个岔路口,你先判断一个大方向(外层if
)。如果走左边的路(if
为true
),就执行一套动作;如果走右边的路(else
),你会发现右边的路上还有第二个岔路口(内层if
),需要你再做一次判断。
// 代码结构
if 外部条件
// “外部条件”为true时执行的代码
else
// “外部条件”为false时执行的代码
if 内部条件
// 仅当“外部条件”为false,且“内部条件”为true时,这里的代码才会被执行
特别提醒:
缩进是嵌套if
的灵魂!内层的if
必须比外层的if
或else
再往右缩进一层(通常是4个空格)。缩进的层级关系,就是代码的逻辑关系。错一个空格,逻辑就全乱了。
案例一:给信号增加时间过滤器
假设我们想在一个均线交叉信号的指标里,增加一个“时间过滤器”:我们只关心周一到周四的交叉信号,而忽略周五的信号,因为我们不希望在周末前进场。嵌套if
就完美地实现了这个“信号+过滤器”的逻辑。
//@version=6
indicator(title="嵌套if - 案例1", overlay=true)
// 1. 计算双重平滑EMA并绘制
emaValue = ta.ema(ta.ema(close, 10), 20)
plot(emaValue, color=color.teal, linewidth=2, title="EMA")
// 2. 使用嵌套if
highlightColour = if ta.cross(close, emaValue)
if dayofweek != dayofweek.friday
color.orange // 两个条件都满足“返回值”就是橙色
// 3. 背景
bgcolor(highlightColour)
这段代码的执行逻辑是:首先,判断价格是否与均线发生交叉。只有当交叉确实发生时,程序才会“走进”第一个if
的内部,去执行第二个if
判断——今天是不是周五。只有当两个条件都满足时,highlightColour
变量才会被赋予橙色。
其效果如下,我们可以看到周五(26号)发生的交叉点,并没有被高亮出来:
案例二:构建策略开平仓逻辑
这个例子非常重要,它展示了嵌套if
在构建专业交易策略时的核心应用:将入场逻辑和出场逻辑完全分开,并设置不同的前提条件。
我们的策略逻辑是:
- 入场:只在当前没有任何持仓(空仓)的时候,才根据信号去开仓。
- 出场:只在当前持有仓位的时候,才根据信号去平仓。
这种结构可以有效避免策略在已有仓位时胡乱加仓,或者在空仓时发送无效的平仓指令。
//@version=6
strategy(title="嵌套if - 策略案例", overlay=true)
// 1. 计算并绘制参考均线
smaValue = ta.sma(close, 75)
plot(smaValue, color=color.teal, linewidth=2, title="SMA")
// 2. 动态计算止盈目标价位
highestHigh = ta.highest(high, 20)[1]
lowestLow = ta.lowest(low, 20)[1]
priceTarget = if close > smaValue
highestHigh * 1.005
else
lowestLow * 0.995
// --- 入场逻辑 ---
// 外层if,作为总开关
if strategy.position_size == 0
// 内层if,判断具体的做多信号
if close > close[10]
strategy.entry("Enter Long", strategy.long)
// 内层if,判断具体的做空信号
if close < close[10]
strategy.entry("Enter Short", strategy.short)
// --- 平仓逻辑 ---
// 外层if,作为总开关
if strategy.position_size != 0
// 内层if,判断是否为多头持仓,并执行平仓
if strategy.position_size > 0
strategy.exit("Exit Long", limit=priceTarget)
// 内层if,判断是否为空头持仓,并执行平仓
if strategy.position_size < 0
strategy.exit("Exit Short", limit=priceTarget)
这些嵌套if
语句使得策略在图表上的行为如下:
优化技巧:何时用and
替代嵌套if
?
嵌套if
虽然强大,但不是所有情况下的最优解。有时候,它会让代码看起来层层叠叠,有点复杂。一个重要的优化技巧是:如果外层if
和内层if
之间没有其他独立的操作,你通常可以用一个and
运算符来简化它。
比如下面这段可以优化的代码:
// 原始嵌套代码
if close > open
if close > close[1]
strategy.close("Enter Long") // 平掉多头仓位
else
strategy.close("Enter Short") // 平掉空头仓位
这里的内层if
仅仅是给外层if
增加了一个额外条件。我们可以用and
把它合并成一行,代码会更扁平、更易读:
// 优化后的代码
if close > open and close > close[1]
strategy.close("Enter Long")
else
strategy.close("Enter Short")
修改后的代码在功能上完全相同,但显然更简洁。
总结
嵌套if
语句是指将一个if
语句放置在另一个if
或if/else
语句的代码块内部。它使得我们能够处理更复杂的、多层次的条件逻辑,是构建“决策树”的关键。嵌套有两种主要结构:一种是“层层深入”的if
内嵌if
;另一种是“非此即彼”后,在else
分支里再做判断。不正确的缩进会导致代码逻辑错误,必须严格遵守,最后并非所有嵌套if
都是必需的,如果只是单纯地增加判断条件,通常可以用逻辑and
运算符来简化代码,使其更易读。