用止损单开仓交易
在TradingView策略中,我们可以使用 strategy.entry() 函数来提交停止单(stop order)以开立仓位。
要在我们的Pine Script策略中通过停止单入场,需要完成三个关键步骤:
- 创建一个
if语句。入场的停止单通常不应在每根K线上都生成。if语句的条件用于指定在何种情况下才应该挂出订单(并过滤掉其他所有情况)。 - 在
if语句中放置strategy.entry()函数,并将其配置为发送一个停止入场单。为此,该函数需要三个关键信息:- 一个订单ID。这是订单的唯一名称,必不可少。
- 交易方向。
strategy.long用于多头入场,strategy.short用于空头入场。 - 要使用的停止价格。我们通过函数的
stop参数来设置这个具体的触发价格(注意:是绝对价格,而非价格点数)。
- 在不再需要时取消停止单。这一点至关重要。否则,挂单可能会在很久之后(当我们早已不再想进行这笔交易时)才被触发成交。我们使用
strategy.cancel()函数来删除尚未成交的挂单。
接下来,让我们看看实现这些步骤的具体代码。
多头入场
要通过停止单入场做多,我们需要为 strategy.entry() 函数提供三个信息:订单ID、代表做多方向的 strategy.long,以及通过 stop 参数设定的触发价格。
代码看起来是这样的:
strategy.entry("Enter Long", strategy.long, stop=high + ta.tr)
这里的 strategy.entry() 会生成一个名为 “Enter Long” 的订单。strategy.long 参数告诉函数这是一个多头交易。而 stop 参数则指定了入场订单的触发价格。在这里,触发价格被设定为当前K线的最高价(high)加上一个真实波幅(ta.tr)的距离。
虽然上面的代码能正确生成一个停止入场单,但问题是它会在每根K线上都执行。这通常不是我们想要的。我们缺少一个条件来判断何时才应该挂出这个停止单。
我们可以使用 if 语句来编写这样的条件。当我们将 strategy.entry() 放置在 if 语句内部时,它只有在 if 的条件判断为 true 时才会被执行。
例如:
// 当相对强弱指数(RSI)上穿70时,提交一个
// 多头买入停止单,触发价为K线最高价加上真实波幅
if ta.crossover(ta.rsi(close, 9), 70)
strategy.entry("Enter Long", strategy.long, stop=high + ta.tr)
这个 if 语句的条件是 ta.crossover(ta.rsi(close, 9), 70),它判断9周期的RSI是否上穿了70。只有当这个条件成立时,strategy.entry() 函数才会被调用,从而挂出一个多头停止单。这样,订单就只会在我们期望的特定时机生成。
请注意:停止单的触发价格是在 if 条件成立的那一刻确定的。它会记住当时的 high 和 ta.tr 值。之后,即使新的K线有不同的最高价,这个已挂出的停止单价格不会自动更新。
剩下的关键一步是管理这个已挂出的停止单。我们很可能不希望这个订单无限期地挂在市场上。当入场理由不再成立时,我们就应该主动将其撤销。
我们可以用另一个 if 语句来实现这一点,这次的条件是用来判断何时应该删除这个挂单:
// 当RSI跌破60时,我们认为入场时机已过,
// 不再希望该订单成交,因此将其撤销
if ta.crossunder(ta.rsi(close, 9), 60)
strategy.cancel("Enter Long")
这个 if 语句的条件是判断RSI是否下穿了60。如果条件满足,代码就会调用 strategy.cancel() 函数。我们向它传入要撤销的订单ID,即 "Enter Long"。
如果此时 "Enter Long" 订单已经被触发成交了,那么市场上就不存在这个挂单了。这种情况下调用 strategy.cancel() 不会产生任何错误,函数会直接忽略该指令。
总结一下,挂出停止单和在必要时撤销它的两个步骤,组合起来是这样的:
// 当RSI上穿70时,挂出多头买入停止单
if ta.crossover(ta.rsi(close, 9), 70)
strategy.entry("Enter Long", strategy.long, stop=high + ta.tr)
// 当RSI下穿60时,撤销这个尚未成交的多头挂单
if ta.crossunder(ta.rsi(close, 9), 60)
strategy.cancel("Enter Long")
空头入场
要通过停止单入场做空,我们同样需要为 strategy.entry() 提供三个信息:订单ID、代表做空方向的 strategy.short,以及通过 stop 参数设定的触发价格。
代码看起来是这样的:
strategy.entry("Enter Short", strategy.short, stop=low - ta.tr)
这段代码会生成一个名为 “Enter Short” 的做空停止单,其触发价格设定在当前K线最低价(low)下方一个真实波幅(ta.tr)的位置。
同样地,我们也需要用 if 语句来控制它的生成时机。
我们用一个 if 语句来设定挂单条件。当条件满足时,strategy.entry() 才会被执行。
// 当RSI下穿30时,提交一个
// 空头卖出停止单,触发价为K线最低价减去真实波幅
if ta.crossunder(ta.rsi(close, 7), 30)
strategy.entry("Enter Short", strategy.short, stop=low - ta.tr)
这个 if 语句判断7周期的RSI是否下穿了30。只有当条件成立时,才会挂出做空停止单。其触发价格是在条件成立那一刻的 low 和 ta.tr 计算得出的,并且不会自动更新。
接下来,我们需要确定在何种情况下应该撤销这个挂单。当做空的理由不再充分时,就应该移除它。
// 但是,当RSI回升并上穿40时,我们认为入场时机已过,
// 不再希望该订单成交,因此将其撤销
if ta.crossover(ta.rsi(close, 7), 40)
strategy.cancel("Enter Short")
这个 if 语句判断RSI是否回升并上穿了40。如果条件满足,我们便调用 strategy.cancel() 并传入 "Enter Short" 这个ID来撤销相应的挂单。
回顾一下,挂出做空停止单和在必要时撤销它的逻辑组合如下:
// 当RSI下穿30时,挂出空头卖出停止单
if ta.crossunder(ta.rsi(close, 7), 30)
strategy.entry("Enter Short", strategy.short, stop=low - ta.tr)
// 当RSI回升并上穿40时,撤销这个尚未成交的空头挂单
if ta.crossover(ta.rsi(close, 7), 40)
strategy.cancel("Enter Short")
示例策略
让我们通过一个完整的策略来看看如何使用停止单进行多头和空头交易。下面的脚本基于钱德动量摆动指标(Chande Momentum Oscillator, CMO)进行交易。
当CMO指标上穿或下穿零轴时,我们生成一个多头或空头的停止入场单。如果这个挂单在一段时间后仍未成交,我们就将其撤销。
策略的完整代码如下:
//@version=5
strategy(title="停止单入场")
// 计算钱德动量摆动指标 (CMO)
cmoValue = ta.cmo(close, 9)
plot(cmoValue, color=color.blue, title="CMO")
hline(0, linestyle=hline.style_dashed, title="零轴")
// --- 多头入场逻辑 ---
// 当CMO上穿0时,挂出一个多头停止单,触发价为K线最高价上方15个最小变动单位。
// 同时,因为我们现在准备做多,所以撤销任何可能存在的空头挂单。
if ta.crossover(cmoValue, 0)
strategy.entry("Enter Long", strategy.long,
stop=high + 15 * syminfo.mintick)
strategy.cancel("Enter Short")
// 如果最近3根K线的CMO最低值已经高于0,说明价格可能已经上涨了一段,
// 若此时多头挂单仍未成交,则撤销该订单。
if ta.lowest(cmoValue, 3) > 0
strategy.cancel("Enter Long")
// --- 空头入场逻辑 ---
// 当CMO下穿0时,挂出一个空头停止单,触发价为K线最低价下方15个最小变动单位。
// 同时,因为我们现在准备做空,所以撤销任何可能存在的多头挂单。
if ta.crossunder(cmoValue, 0)
strategy.entry("Enter Short", strategy.short,
stop=low - 15 * syminfo.mintick)
strategy.cancel("Enter Long")
// 如果最近3根K线的CMO最高值已经低于0,说明价格可能已经下跌了一段,
// 若此时空头挂单仍未成交,则撤销该订单。
if ta.highest(cmoValue, 3) < 0
strategy.cancel("Enter Short")
我们先计算并绘制9周期的CMO指标及其零轴。
多头逻辑分两步:
- 挂单:当CMO上穿零轴时(
ta.crossover(cmoValue, 0)),我们调用strategy.entry()挂出一个名为"Enter Long"的多头停止单,触发价格为当时K线最高价上浮15个最小变动价位(syminfo.mintick)。与此同时,我们调用strategy.cancel("Enter Short")来确保任何未成交的空头挂单被立即撤销,避免策略意图混乱。 - 撤单:我们用另一个
if语句来设定撤单条件。如果最近3根K线的CMO最低值都大于0(ta.lowest(cmoValue, 3) > 0),表明上涨动能可能已经释放了一部分,此时再追高入场的性价比降低。因此,如果我们的"Enter Long"挂单还未成交,就通过strategy.cancel("Enter Long")将其撤销。
空头逻辑与多头逻辑完全相反:
- 挂单:当CMO下穿零轴时,挂出
"Enter Short"空头停止单,并撤销任何多头挂单。 - 撤单:如果最近3根K线的CMO最高值都小于0(
ta.highest(cmoValue, 3) < 0),说明下跌动能已释放,若空头挂单未成交,则将其撤销。
在图表上,该策略会根据CMO指标的变化,通过多头和空头停止单进行交易,如下所示:
总结
- 策略使用
strategy.entry()函数通过停止单来开仓。 - 为此,该函数需要三个关键参数:订单ID(即名称)、交易方向和停止价格。
- 多头入场订单使用
strategy.long作为方向;空头入场则需要strategy.short。 stop参数指定了停止单的触发价格。这个价格在订单提交时被确定,之后不会自动更新。- 我们必须将
strategy.entry()放置在if语句中,以确保停止单只在满足我们设定的条件时才生成。 - 如果挂单的入场条件不再成立,我们应该使用
strategy.cancel()函数来主动撤销这个尚未成交的订单。
用止损限价单开仓交易
在Pine Script策略中,我们使用 strategy.entry() 函数来通过止损限价单(Stop-Limit Order)开仓交易。
要通过止损限价单入场,我们的TradingView策略需要遵循三个步骤:
- 创建
if条件语句:止损限价单通常不应在每根K线上都生成。因此,我们需要使用if语句来设定一个特定的触发条件,只有在满足这个条件时才挂单。 - 在
if语句中调用strategy.entry():将下单函数放入条件语句中,可以确保只在特定情况下生成订单。我们需要为strategy.entry()配置四个核心参数:- 订单ID:为这个止损限价单命名。
- 交易方向:多头入场使用
strategy.long,空头入场使用strategy.short。 - 止损触发价(
stop):当市场价格触及这个价位时,限价单才会被激活并提交到市场。 - 限价(
limit):这是订单最终成交的限制价格,成交价必须等于或优于这个价格。
- 取消挂单:当入场信号失效时,应及时取消待处理的止损限价单,否则它可能会在很久之后(当市场情况已完全不同时)才意外成交。我们可以使用
strategy.cancel()函数来删除指定的挂单。
下面我们来看看如何将这些步骤转化为具体的Pine Script代码。
多头入场
要通过止损限价单做多,我们需要告诉 strategy.entry() 四件事:订单ID、strategy.long 方向、stop 止损触发价和 limit 限价。
代码看起来是这样的:
strategy.entry("Enter Long", strategy.long, stop=high[1], limit=close)
这里 strategy.entry() 生成了一个名为 "Enter Long" 的订单。strategy.long 指明了这是一个多头开仓操作。它的 stop 价格(触发价)被设为前一根K线的最高价(high[1])。当市场价格触及这个价位后,一个限价单会被激活,并期望在当前K线的收盘价(close)或更优(更低)的价格成交,这个价格由 limit 参数定义。
虽然这段代码本身能够正确生成止损限价单,但它会在每一根K线上都尝试挂单,这通常不是我们想要的。我们还需要一个条件来决定何时发送这个订单。
我们可以用 if 语句来设定下单的条件。将 strategy.entry() 放入 if 语句块内,函数就只会在条件成立时才执行。
示例如下:
// 当资金流量指标(MFI)上穿50时,生成一个买入(多头)的止损限价单。
// 该订单在价格触及前一根K线的最高价时触发,
// 并期望在当前K线的收盘价或更优价格成交。
if ta.crossover(ta.mfi(hlc3, 12), 50)
strategy.entry("Enter Long", strategy.long, stop=high[1], limit=close)
这个 if 语句通过 ta.crossover() 函数判断12周期的资金流量指标(MFI)是否向上穿越了50。只有当穿越确实发生时,if 语句内的 strategy.entry() 才会执行,从而确保止损限价单只在符合我们预设的特定时机生成。
值得注意的是,订单的 stop 和 limit 价格,是 if 条件最后一次成立时的那个价格。挂单的价格不会自动随着每一根新K线而更新。相反,它在生成时会记住当时的那个价格,并一直保持不变,直到成交或被取消。
接下来需要考虑的是,何时取消这个待处理的止损限价单。我们通常不希望一个挂单永远有效,因为最初的看涨理由可能已经不复存在。
因此,我们需要再写一个 if 语句,用于在特定情况下取消这个挂单:
// 如果MFI上穿80,说明市场可能过热,多头设置失效,
// 此时取消待处理的订单。
if ta.crossover(ta.mfi(hlc3, 12), 80)
strategy.cancel("Enter Long")
这个 if 语句使用 ta.crossover() 来判断MFI是否上穿了80。如果条件成立,strategy.cancel() 函数就会执行,取消名为 "Enter Long" 的订单。
如果当MFI上穿80时,这个止损限价单已经成交了,那么就不再存在待处理的订单,strategy.cancel() 也无事可做,不会产生任何影响。
回顾一下,生成和管理一个多头止损限价单的两个关键步骤如下:
// 当MFI上穿50时,生成一个多头止损限价单
if ta.crossover(ta.mfi(hlc3, 12), 50)
strategy.entry("Enter Long", strategy.long, stop=high[1], limit=close)
// 当MFI上穿80时,取消多头挂单
if ta.crossover(ta.mfi(hlc3, 12), 80)
strategy.cancel("Enter Long")
空头入场
要通过止损限价单建立一个空头仓位,我们同样需要为 strategy.entry() 函数提供四个参数:订单ID、strategy.short 方向、stop 止损触发价和 limit 限价。
它看起来是这样的:
strategy.entry("Enter Short", strategy.short, stop=low[1], limit=close)
这里,strategy.entry() 生成了名为 "Enter Short" 的订单,strategy.short 指明了这是一个空头开仓操作。订单的 stop 价格是前一根K线的最低价(low[1]),而 limit 价格是当前K线的收盘价(close)。
同样地,我们需要一个 if 条件来控制下单的时机。
示例如下:
// 当MFI下穿50时,生成一个卖出(空头)的止损限价单。
// 该订单在价格触及前一根K线的最低价时触发,
// 并期望在当前K线的收盘价或更优价格成交。
if ta.crossunder(ta.mfi(hlc3, 12), 50)
strategy.entry("Enter Short", strategy.short, stop=low[1], limit=close)
这个 if 语句通过 ta.crossunder() 函数判断MFI是否向下穿越了50。只有当穿越发生时,strategy.entry() 才会执行,确保了下单的精确性。
我们也需要一个逻辑来取消过时的空头挂单:
// 如果MFI下穿20,说明市场可能超卖,空头设置失效,
// 此时取消待处理的订单。
if ta.crossunder(ta.mfi(hlc3, 12), 20)
strategy.cancel("Enter Short")
这个 if 语句判断MFI是否下穿了20。如果条件成立,strategy.cancel() 就会执行,删除名为 "Enter Short" 的挂单。
回顾一下,生成和管理一个空头止损限价单的两个关键步骤如下:
// 当MFI下穿50时,生成一个空头止损限价单
if ta.crossunder(ta.mfi(hlc3, 12), 50)
strategy.entry("Enter Short", strategy.short, stop=low[1], limit=close)
// 当MFI下穿20时,取消空头挂单
if ta.crossunder(ta.mfi(hlc3, 12), 20)
strategy.cancel("Enter Short")
完整策略示例
让我们看一个使用止损限价单进行多空双向交易的完整策略。下面的脚本基于布林带进行交易。
当价格下穿布林带下轨时,策略生成一个做多的止损限价单。反之,当价格上穿上轨时,则生成一个做空的止损限价单。这些订单的逻辑是,当价格回归到布林带内部时执行入场。
策略的完整代码如下:
//@version=5
strategy(title="Stop-limit entry orders", overlay=true)
// 计算并绘制布林带
[middleLine, upperBand, lowerBand] = ta.bb(close, 20, 2.0)
plot(upperBand, color=color.teal, title="Upper Band")
plot(middleLine, color=color.gray, title="Middle line")
plot(lowerBand, color=color.teal, title="Lower Band")
// 当价格跌破下轨时,创建多头止损限价单
if ta.crossunder(close, lowerBand)
strategy.entry("Enter Long", strategy.long, stop=lowerBand,
limit=lowerBand + 10 * syminfo.mintick)
// 当价格升破上轨时,创建空头止损限价单
if ta.crossover(close, upperBand)
strategy.entry("Enter Short", strategy.short, stop=upperBand,
limit=upperBand - 10 * syminfo.mintick)
// 如果价格穿越中线,取消所有未成交订单,
// 并且如果存在仓位,则以市价单平仓
if ta.cross(close, middleLine)
strategy.cancel_all()
strategy.close_all(comment="Exit Position")
我们首先用 strategy() 函数命名脚本,然后计算并绘制布林带。
多头入场逻辑:当 ta.crossunder() 检测到价格下穿下轨时,strategy.entry() 生成一个多头止损限价单。stop 价格设为下轨本身,而 limit 价格设为下轨向上10个最小变动单位。这意味着当价格从下轨下方反弹回下轨时,订单被触发,并期望在下轨上方一点的位置成交。
空头入场逻辑:当 ta.crossover() 检测到价格上穿上轨时,strategy.entry() 生成一个空头止损限价单。stop 价格设为上轨,limit 价格设为上轨向下10个最小变动单位,捕捉价格从上轨外回落的动作。
订单管理逻辑:最后,我们使用 ta.cross() 来判断价格是否穿越了布林带中线。一旦发生穿越,我们认为原始的极端行情(超买或超卖)已经结束,因此:
strategy.cancel_all()会取消所有待处理的挂单。strategy.close_all()会以市价单平掉所有已有的仓位。
在图表上,该策略的交易效果如下:
总结
- Pine Script策略使用
strategy.entry()函数通过止损限价单开仓。 - 此类订单需要四个关键信息:订单ID、交易方向、止损触发价和限价。
- 交易方向由
strategy.long(多头)或strategy.short(空头)指定。 stop参数设置订单的激活价格。limit参数定义订单的最终成交价格限制。- 当挂单不再需要执行时,我们应使用
strategy.cancel()或strategy.cancel_all()函数将其取消。




