用Pine Script代码开启策略交易
Pine Script交易策略的一项核心能力就是开仓下单。缺少了这个功能,脚本就无法根据交易信号进行回测,也无法模拟历史表现。
在Pine Script中,策略通过 strategy.entry() 函数来开仓。该函数可以生成市价单、限价单、止损单和止损限价单。下面我们逐一来看每一种订单怎么写。
市价单
要在Pine Script中生成一个市价入场订单,我们需要为 strategy.entry() 函数提供以下几个必要的参数:
- 订单ID(即订单的名称)
- 订单方向:
strategy.long代表多头入场,strategy.short代表空头入场。
通常我们不希望在每一根K线上都进行交易,所以会把 strategy.entry() 函数放在一个 if 条件语句中。这样,只有当 if 语句的条件成立时,市价单才会被触发。
下面是一个多头入场的例子:
// 当价格上穿20周期EMA时,
// 生成一个做多的市价单
if ta.crossover(close, ta.ema(close, 20))
strategy.entry("Enter Long", strategy.long)
这段 if 语句使用 ta.crossover() 函数来检查收盘价是否向上穿越了由 ta.ema() 计算的20周期指数移动平均线。如果发生了上穿,ta.crossover() 会返回 true,从而触发 if 语句内的代码。
此时,strategy.entry() 函数被执行。我们为它传入了两个参数:第一个是订单的ID(名称)"Enter Long",第二个 strategy.long 则指定了交易方向为做多。
如果要用市价单开一个空头仓位,可以这样做:
// 当价格下穿20周期EMA时,
// 生成一个做空的市价单
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short)
这段代码使用 ta.crossunder() 函数来判断收盘价是否向下穿越了20周期的EMA。如果条件满足,strategy.entry() 函数便会执行,并传入 "Enter Short" 作为订单ID,strategy.short 作为交易方向,从而建立一个空头头寸。
限价单
要通过Pine Script的限价单入场,我们需要为 strategy.entry() 函数提供以下这些必要参数:
- 订单ID(即订单名称)。
- 订单方向:多头入场为
strategy.long,空头入场为strategy.short。 - 通过
limit参数指定限价价格。这个价格必须是具体的价位。
这里有一点要特别注意:Pine Script的限价单一旦发出,就会保持激活状态直到成交。因此,如果交易信号失效,我们必须在代码中手动取消该订单,否则它仍有可能在我们不希望的时候成交。实盘里很多莫名其妙的开仓,就是忘了取消挂单造成的。
通常,我们会将 strategy.entry() 放在一个 if 语句中,以确保只在特定的交易时机下单。
下面是一个使用限价单做多的例子:
// 当价格上穿均线时,以当前K线的最低价
// 挂一个买入(多头)限价单
if ta.crossover(close, ta.ema(close, 20))
strategy.entry("Enter Long", strategy.long, limit=low)
这段代码监测价格是否上穿20周期EMA。一旦上穿,strategy.entry() 函数就会执行,并带有三个参数:订单ID "Enter Long",交易方向 strategy.long,以及通过 limit 参数设定的限价,这里我们将其设为当前K线的最低价。
如果要用限价单做空,可以像下面这样使用 strategy.entry() 函数:
// 当价格下穿均线时,以当前K线的最高价
// 挂一个卖出(空头)限价单
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short, limit=high)
这段代码在价格下穿20周期EMA时触发,通过 strategy.entry() 创建一个空头限价单,其限价(limit)被设定为当前K线的最高价。
止损单
要在Pine Script中创建一个止损入场订单,我们需要为 strategy.entry() 函数提供三个必要的参数:
- 订单ID(即订单名称)。
- 订单方向:多头入场为
strategy.long,空头入场为strategy.short。 - 通过
stop参数指定止损触发价格。这个价格必须是具体的价位。
同样要注意:Pine Script的止损单一旦发出,就会保持激活状态直到成交。如果策略的入场条件已不再满足,我们的代码必须负责取消该订单。
为了只在特定时机触发止损单,我们同样需要将 strategy.entry() 放入一个 if 语句中。
以下是如何生成一个多头入场止损单的例子:
// 当价格上穿20周期EMA时,生成一个止损入场单,
// 用于在未来价格突破时开立多头仓位
if ta.crossover(close, ta.ema(close, 20))
strategy.entry("Enter Long", strategy.long, stop=high +
10 * syminfo.mintick)
当收盘价上穿EMA时,strategy.entry() 函数被调用。它的 stop 参数定义了入场的触发价格,这里我们设为当前K线最高价再往上10个最小价格变动单位(syminfo.mintick)的位置。
要创建一个空头入场止损单,可以这样做:
// 当价格下穿20周期EMA时,生成一个止损入场单,
// 用于在未来价格跌破时开立空头仓位
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short, stop=low -
10 * syminfo.mintick)
当价格下穿EMA时,if 语句块内的代码执行。strategy.entry() 的 stop 参数将触发价设为当前K线最低价再往下10个最小价格变动单位的位置。
止损限价单
要通过Pine Script的止损限价单入场,我们需要为 strategy.entry() 函数提供四个必要的参数:
- 订单ID(即订单名称)。
- 订单方向(
strategy.long或strategy.short)。 - 通过
stop参数指定止损触发价格。这必须是一个具体的价位。 - 通过
limit参数指定限价。这也必须是一个具体的价位。
止损限价单也一样:一旦发出,就会保持激活状态直到成交。如果入场条件失效,我们需要在代码中手动取消该订单。
通常,我们会将 strategy.entry() 放入一个 if 语句中,以确保只在特定的交易时机下单。
要用止损限价单开立一个多头仓位,代码如下:
// 当价格上穿20周期EMA时,
// 生成一个做多的止损限价入场订单
if ta.crossover(close, ta.ema(close, 20))
strategy.entry("Enter Long", strategy.long, stop=high[1],
limit=close)
当价格上穿EMA时,strategy.entry() 函数被调用。stop 参数将触发价设为前一根K线的最高价(high[1])。当市场价格触及这个止损价时,一个限价单会被激活。limit 参数则设定了这个限价单的价格,这里是当前K线的收盘价。这意味着策略将以该限价或更优(更低)的价格买入。
要用止损限价单开立一个空头仓位,可以像这样使用 strategy.entry():
// 当价格下穿20周期EMA时,
// 生成一个做空的止损限价订单
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short, stop=low[1], limit=close)
当价格下穿EMA时,strategy.entry() 函数被执行。stop 参数将触发价设为前一根K线的最低价(low[1])。当市场价格触及该价位,一个限价单将被激活。limit 参数则设定了该限价单的价格为当前K线的收盘价。因此,策略将以该限价或更优(更高)的价格卖出。
总结
- Pine Script策略使用
strategy.entry()函数来开立多头和空头仓位。 - 该函数可以生成市价单、限价单、止损单和止损限价单。
- 我们总是需要为
strategy.entry()提供一个订单ID和交易方向(strategy.long或strategy.short)。 limit和stop参数用于配置限价单、止损单或止损限价单的价格。- 这些挂单会一直保持激活状态直到成交。如果不再需要它们执行,我们需要使用
strategy.cancel()或strategy.cancel_all()函数来取消订单。
用市价单开仓交易
在TradingView策略代码中,我们使用 strategy.entry() 函数来通过市价单开仓交易。
要编写这样一个订单,我们需要完成三个步骤:
- 为
strategy.entry()提供一个订单ID。这是我们为市价单指定的、独一无二的名称。 - 配置交易方向。我们需要为
strategy.entry()指定以下两个值之一:strategy.long用于做多入场。strategy.short用于做空入场。
- 将
strategy.entry()函数放置在一个if语句中。该if语句的条件应该描述我们想要进场的具体时机。这样可以确保策略只在满足特定条件时才下单,而不是在每根K线上都尝试下单。
接下来,让我们分别看看如何实现多头和空头交易。
多头入场
要使用 strategy.entry() 函数开一个多头仓位,我们需要提供两个参数。第一个是订单ID(即订单名称),第二个是 strategy.long。这个值会告诉函数去执行一个做多操作。
代码如下所示:
strategy.entry("Enter Long", strategy.long)
这里的 strategy.entry() 会提交一个名为 “Enter Long” 的订单。strategy.long 参数指明了这是一个做多订单。
当然,我们还必须告诉策略何时发送这个订单,否则它会在每根K线上都执行,这显然不是我们想要的。为了控制下单时机,我们使用 if 语句。
当我们将 strategy.entry() 放入 if 语句后,它只会在 if 的条件判断为 true 时才会被执行。这样,我们就能精确控制做多交易的触发时机。
例如:
// 当相对强弱指数(RSI)上穿30时,提交一个市价单开多仓
if ta.crossover(ta.rsi(close, 12), 30)
strategy.entry("Enter Long", strategy.long)
这个 if 语句使用 ta.crossover() 函数来判断12周期的RSI是否上穿了30。如果条件成立,代码就会执行 strategy.entry() 函数来开启一个多头仓位。
如果交叉没有发生,那么 if 条件不满足,strategy.entry() 就不会被调用,也就不会有任何交易发生。
空头入场
要使用 strategy.entry() 函数生成一个做空的市价单,我们同样需要提供两个参数。第一个是订单ID,第二个是 strategy.short,它会告诉函数去执行一个做空操作。
代码如下:
strategy.entry("Enter Short", strategy.short)
这里的 strategy.entry() 会提交一个名为 “Enter Short” 的市价单。strategy.short 参数指明了这是一个做空入场交易。
同样,我们也必须将它包裹在 if 语句中,否则策略会在每根K线上都尝试下单。将订单函数放入 if 语句后,订单就只会在满足特定条件时生成。
示例如下:
// 当相对强弱指数(RSI)下穿70时,用市价单开空仓
if ta.crossunder(ta.rsi(close, 9), 70)
strategy.entry("Enter Short", strategy.short)
这个 if 语句评估 ta.crossunder() 函数的返回值,判断9周期的RSI是否下穿了70。如果条件满足,strategy.entry() 函数就会提交一个市价单来做空。
如果RSI交叉并未发生,那么 if 语句内的代码不会执行,strategy.entry() 也不会有任何动作。
示例策略
让我们来看一个完整的策略,演示如何使用市价单进行多头和空头开仓。下方的脚本基于三条指数移动平均线(EMA)进行交易。
当快线上穿中线,并且慢线作为趋势过滤器确认时,我们就入场做多或做空。我们使用 strategy.entry() 函数来生成这些交易的市价单。
策略的完整代码如下:
//@version=5
strategy(title="市价单入场示例", overlay=true)
// 计算并绘制指数移动平均线
fastEMA = ta.ema(close, 10)
medEMA = ta.ema(close, 30)
slowEMA = ta.ema(close, 80)
plot(fastEMA, color=color.orange, title="快线 EMA")
plot(medEMA, color=color.blue, title="中线 EMA")
plot(slowEMA, color=color.purple, title="慢线 EMA")
// 生成交易
// 当快线上穿中线,并且收盘价高于慢线时,提交一个多头入场订单
if ta.crossover(fastEMA, medEMA) and close > slowEMA
strategy.entry("Enter Long", strategy.long)
// 当快线下穿中线,并且收盘价低于慢线时,提交一个空头入场订单
if ta.crossunder(fastEMA, medEMA) and close < slowEMA
strategy.entry("Enter Short", strategy.short)
我们从 strategy() 函数开始,它为脚本命名并设置其在图表主图上叠加显示。
接着,我们用 ta.ema() 函数计算三条不同周期的EMA,周期分别为10、30和80。
然后,plot() 函数将这三条均线绘制在图表上,颜色分别为橙色、蓝色和紫色。
下面是做多开仓的逻辑:
// 当快线上穿中线,并且收盘价高于慢线时,提交一个多头入场订单
if ta.crossover(fastEMA, medEMA) and close > slowEMA
strategy.entry("Enter Long", strategy.long)
这个 if 语句检查两个条件:第一,使用 ta.crossover() 判断快线是否上穿了中线;第二,当前的收盘价是否高于慢线。当这两个条件同时满足时(and),if 语句内部的代码才会被执行。
内部代码调用了 strategy.entry(),并传入两个值:"Enter Long" 作为订单ID,strategy.long 则告诉Pine Script生成一个做多(买入)订单。
做空开仓的逻辑与此类似:
// 当快线下穿中线,并且收盘价低于慢线时,提交一个空头入场订单
if ta.crossunder(fastEMA, medEMA) and close < slowEMA
strategy.entry("Enter Short", strategy.short)
这个 if 语句使用 ta.crossunder() 判断快线是否下穿了中线,并且要求当前收盘价低于慢线。当两个条件都满足时,内部代码被执行。
我们调用 strategy.entry(),"Enter Short" 是订单ID,strategy.short 则使其生成一个做空入场交易。
当我们在图表上运行此策略时,它会根据移动平均线的交叉信号,通过多头和空头市价单进行交易:
总结
strategy.entry()函数允许TradingView策略通过市价单开仓。- 要实现此功能,该函数需要两个基本参数:订单的ID(即名称)和交易方向。
- 做多订单使用
strategy.long作为方向。做空入场则需要strategy.short值。 - 我们必须将
strategy.entry()放置在if语句内部,这样它才能在满足特定条件时触发,而不是持续下单。
用限价单开仓交易
TradingView策略通过 strategy.entry() 函数来使用限价单开仓交易。
要在我们的Pine Script策略中通过限价单入场,需要遵循三个步骤:
- 配置下单函数:配置
strategy.entry()函数以发送一个限价单。这需要我们提供三个关键信息:- 订单ID:为我们的限价单指定一个必需的名称。
- 交易方向:
strategy.long用于多头入场,strategy.short用于空头入场。 - 限价价格:通过函数的
limit参数来明确告知strategy.entry()在哪个价位挂单。
- 条件触发:将
strategy.entry()函数放置在一个if语句块中。通过if语句的条件来控制下单的时机,确保限价单只在特定的市场条件下生成,而不是在每根K线上都挂单。 - 订单管理:当入场信号失效,挂单不应再执行时,及时取消它。否则,这个待处理的订单可能会在很久之后(当市场情况已完全不同时)才成交。要删除订单,我们使用
strategy.cancel()函数。
下面,我们来看看这套流程在多头和空头交易中的具体应用。
多头入场
要通过限价单建立一个多头仓位,我们需要为 strategy.entry() 函数提供三项数据:订单ID、代表做多的 strategy.long,以及通过 limit 参数设定的限价。
代码看起来是这样的:
strategy.entry("Enter Long", strategy.long, limit=low)
在这里,strategy.entry() 会生成一个名为 "Enter Long" 的订单。strategy.long 参数告诉函数这是一个多头开仓操作。limit 参数则指定了挂单的价格,这里我们设为当前K线的最低价(low)。
虽然这段代码本身能够正确生成限价单,但如果策略只是这样简单地调用 strategy.entry(),那么它会在每一根K线上都尝试挂单,这通常不是我们想要的。我们还需要一个条件来决定何时发送这个订单。
我们可以用 if 语句来设定下单的条件。将 strategy.entry() 放在 if 语句块内,函数就只会在条件成立时才执行。
示例如下:
// 当价格上穿移动平均线时,以当前K线的最低价
// 挂一个买入(多头)限价单
if ta.crossover(close, ta.ema(close, 30))
strategy.entry("Enter Long", strategy.long, limit=low)
这个 if 语句的条件是 ta.crossover() 函数的返回值。该函数用于判断收盘价是否向上穿越了指数移动平均线。如果穿越发生,函数返回 true,否则返回 false。
只有当穿越确实发生时,if 语句内的 strategy.entry() 才会执行,从而确保限价单只在符合我们预设的特定时机生成。
值得注意的是,我们设定的限价(当前K线的最低价),是 if 条件最后一次成立时的那个价格。挂单的价格不会自动随着每一根新K线的最低价而更新。相反,它在生成时会记住当时的那个价格,并一直保持不变,直到成交或被取消。这一点新手很容易想当然,以为挂单价会跟着行情走,结果回测出来的成交价和预期对不上。
接下来需要考虑的是,何时取消这个待处理的限价单。我们通常不希望一个挂单永远有效。在某个时间点之后,最初的做多信号可能已经不再成立。
因此,我们需要再写一个 if 语句,用于在特定情况下取消这个多头限价单:
// 如果多头挂单在穿越信号出现后的5根K线内仍未成交,
// 则取消这个待处理的多头入场订单
if ta.barssince(ta.crossover(close, ta.ema(close, 30))) == 5
strategy.cancel("Enter Long")
这个 if 语句的条件使用了 ta.barssince() 函数,它会计算距离上一次 ta.crossover()(价格上穿EMA)为 true 以来,已经过去了多少根K线。
当这个时间间隔正好等于5根K线时,if 条件成立,strategy.cancel() 函数便会执行,取消名为 "Enter Long" 的订单。这样,如果我们的挂单在5根K线内没有被触发,脚本就会主动将其撤销。
(如果多头限价单在5根K线内已经成交,那么就不再存在待处理的订单,strategy.cancel() 自然也无事可做。这没关系,函数在这种情况下不会产生任何影响。)
回顾一下,生成和管理一个多头限价单的两个关键步骤如下:
// 当价格上穿移动平均线时,以当前K线的最低价
// 挂一个买入(多头)限价单
if ta.crossover(close, ta.ema(close, 30))
strategy.entry("Enter Long", strategy.long, limit=low)
// 如果多头挂单在穿越信号出现后的5根K线内仍未成交,
// 则取消这个待处理的多头入场订单
if ta.barssince(ta.crossover(close, ta.ema(close, 30))) == 5
strategy.cancel("Enter Long")
空头入场
要通过限价单建立一个空头仓位,我们需要告诉 strategy.entry() 函数三件事:订单ID、代表做空的 strategy.short,以及通过 limit 参数设定的限价。
它看起来是这样的:
strategy.entry("Enter Short", strategy.short, limit=high)
这里,strategy.entry() 生成了名为 "Enter Short" 的订单,strategy.short 参数指明了这是一个空头开仓操作,而 limit 参数则将挂单价格设为当前K线的最高价。
和多头入场一样,如果只是这样简单调用,限价单会在每根K线上都生成。我们同样需要一个条件来控制下单的时机。
我们使用 if 语句来实现这个条件。将 strategy.entry() 放入 if 语句块内,它就只会在条件成立时执行。
示例如下:
// 当价格下穿移动平均线时,以当前K线的最高价
// 挂一个卖出(空头)限价单
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short, limit=high)
这个 if 语句通过 ta.crossunder() 函数来判断收盘价是否向下穿越了指数移动平均线。只有当穿越发生时,if 块内的代码才会被执行,从而确保限价单只在特定时机生成。
同样需要注意,挂单的限价(当前K线的最高价)是在 if 条件成立那一刻被确定的,之后不会自动更新。
剩下的任务就是决定何时取消这个空头限价单。我们不希望订单永远挂着,因为空头信号迟早会失效。
所以我们再写一个 if 语句,用于在特定场景下取消这个挂单:
// 如果空头挂单在下穿信号出现后的7根K线内仍未成交,
// 则取消这个待处理的空头订单
if ta.barssince(ta.crossunder(close, ta.ema(close, 20))) == 7
strategy.cancel("Enter Short")
这个 if 语句的条件通过 ta.barssince() 函数检查,自上一次价格下穿EMA以来是否已经过去了7根K线。如果答案是肯定的,strategy.cancel() 函数就会执行,取消名为 "Enter Short" 的订单。这样,如果挂单在7根K线内没有成交,我们就不再对这个机会感兴趣,并将其撤销。
(如果空头订单在这7根K线内已经成交,那么就不再有待处理的订单,strategy.cancel() 也无事可做,不会产生任何影响。)
回顾一下,生成和管理一个空头限价单的两个关键步骤如下:
// 当价格下穿移动平均线时,以当前K线的最高价
// 挂一个卖出(空头)限价单
if ta.crossunder(close, ta.ema(close, 20))
strategy.entry("Enter Short", strategy.short, limit=high)
// 如果空头挂单在下穿信号出现后的7根K线内仍未成交,
// 则取消这个待处理的空头订单
if ta.barssince(ta.crossunder(close, ta.ema(close, 20))) == 7
strategy.cancel("Enter Short")
完整策略示例
让我们看一个使用限价单进行多空双向交易的完整策略。下面的脚本基于随机指标(Stochastic)的%K和%D线的交叉来进行交易。
当%K线上穿%D线时,strategy.entry() 函数提交一个多头限价入场订单。如果发生下穿,则提交一个空头入场限价订单。
策略的完整代码如下:
//@version=5
strategy(title="Limit order entries")
// 计算随机指标的 %K 和 %D 值
kValue = ta.sma(ta.stoch(close, high, low, 9), 3)
dValue = ta.sma(kValue, 3)
// 绘制 %K 和 %D 线,以及超买超卖线
plot(kValue, color=color.blue, title="%K")
plot(dValue, color=color.orange, title="%D")
hline(20, title="Oversold")
hline(80, title="Overbought")
// 多头入场逻辑
// 当 %K 上穿 %D,且 %K 低于20时,在低点挂买单
if ta.crossover(kValue, dValue) and kValue < 20
strategy.entry("Enter Long", strategy.long, limit=low)
// 当 %K 上穿40时,取消多头挂单
if ta.crossover(kValue, 40)
strategy.cancel("Enter Long")
// 空头入场逻辑
// 当 %K 下穿 %D,且 %K 高于80时,在高点挂卖单
if ta.crossunder(kValue, dValue) and kValue > 80
strategy.entry("Enter Short", strategy.short, limit=high)
// 当 %K 下穿60时,取消空头挂单
if ta.crossunder(kValue, 60)
strategy.cancel("Enter Short")
我们首先用 strategy() 函数命名脚本。然后计算随机指标的%K和%D值,并通过 plot() 和 hline() 将它们及超买超卖区(80/20)绘制在图表上。
接着是多头入场的逻辑:
// 当 %K 上穿 %D,且 %K 低于20时,在低点挂买单
if ta.crossover(kValue, dValue) and kValue < 20
strategy.entry("Enter Long", strategy.long, limit=low)
这个 if 语句检查两个条件:一是%K线上穿%D线,二是%K值小于20(处于超卖区)。当两个条件同时满足时,strategy.entry() 函数会挂一个名为 "Enter Long" 的多头限价单,价格为当前K线的最低价。
当然,这个挂单不能永远有效。策略使用以下代码来取消订单:
// 当 %K 上穿40时,取消多头挂单
if ta.crossover(kValue, 40)
strategy.cancel("Enter Long")
这个 if 语句判断%K线是否已经上穿了40。一旦发生,意味着入场的最佳时机可能已经过去,于是 strategy.cancel() 函数会取消那个尚未成交的挂单。
策略的另一部分是处理空头交易:
// 当 %K 下穿 %D,且 %K 高于80时,在高点挂卖单
if ta.crossunder(kValue, dValue) and kValue > 80
strategy.entry("Enter Short", strategy.short, limit=high)
这个 if 语句同样检查两个条件:一是%K线下穿%D线,二是%K值高于80(处于超买区)。条件满足时,strategy.entry() 会挂一个名为 "Enter Short" 的空头限价单,价格为当前K线的最高价。
最后,以下代码负责在订单未成交时将其取消:
// 当 %K 下穿60时,取消空头挂单
if ta.crossunder(kValue, 60)
strategy.cancel("Enter Short")
这个 if 语句判断%K是否已经跌破了60。一旦发生,strategy.cancel() 会执行,删除名为 "Enter Short" 的挂单,避免订单在信号失效后仍被执行。
当我们在图表上运行这个策略时,它会根据随机指标的交叉信号进行交易,效果如下:
总结
- TradingView策略使用
strategy.entry()函数通过限价单进行开仓。 - 该函数需要三个关键信息:订单ID(名称)、交易方向和限价。
- 多头入场使用
strategy.long作为方向;空头入场则使用strategy.short。 strategy.entry()的limit参数定义了挂单的价格。每次调用函数时,都会设定当时的那个价格。- 将
strategy.entry()放入if语句中,可以确保限价单只在特定条件下生成。 - 当挂单不再需要执行时,我们应使用
strategy.cancel()函数将其取消。




