上一篇我们聊了 strategy.entry()
是如何因为生成 vs 执行的机制,在特定情况下绕过加仓限制的。今天我们来聊一个更直接、更霸道的原因——strategy.order()
函数。
strategy.entry()
和 strategy.order()
是PineScript中两个核心的下单函数,但它们之间有一个至关重要的区别,你可以这样理解:
strategy.entry()
像是自动挡汽车: 它内置了一些安全功能,比如会自动检查你的pyramiding
设置,帮你管理加仓次数。虽然在某些极端情况下(如并发下单)可能出问题,但总体上更省心。strategy.order()
像是手动挡汽车: 它更底层,给了你更大的自由度和控制权,但它完全不会帮你检查pyramiding
或其他风险管理设置。它只会忠实地执行你发出的每一条指令。这意味着,如果你不自己踩刹车,它就会一直往前冲。
所以当你的策略使用 strategy.order()
来开仓时,无论你在 strategy()
函数里把 pyramiding
设置成多少,它都会被彻底无视。接下来我们就通过一个实例,看看这个手动挡以及如何为它装上我们自己的安全带。
当 strategy.order()
遇上加仓信号
我们来看一个策略:
- 开仓条件: 5MA上穿10MA,且RSI大于50。
- 加仓条件: 已经持有多仓,且RSI上穿70。
- 平仓条件: 均线死叉,且RSI小于50。
- 加仓设置:
pyramiding=1
,即在初始仓位之上,只允许额外加仓一次(总持仓最多2笔)。
策略代码如下:
//@version=6
strategy(title="加仓与 strategy.order()", pyramiding=1)
quickMALen = input.int(5, title="快线 MA")
slowMALen = input.int(10, title="慢线 MA")
rsiLen = input.int(9, title="RSI")
//计算
quickMA = ta.sma(close, quickMALen)
slowMA = ta.sma(close, slowMALen)
rsiValue = ta.rsi(close, rsiLen)
plot(rsiValue, color=color.blue)
hline(50, color=#87CEEB)
hline(80, color=#87CEEB)
hline(20, color=#87CEEB)
//条件
enterLong = ta.crossover(quickMA, slowMA) and
rsiValue > 50
addToLong = strategy.position_size > 0 and
ta.crossover(rsiValue, 70)
exitLong = ta.crossunder(quickMA, slowMA)
and rsiValue < 50
//订单
if enterLong
strategy.order("Enter Long", strategy.long)
if addToLong
strategy.order("Additional Long", strategy.long)
//平仓
if exitLong
strategy.close_all()
我们的设置是 pyramiding=1
,意味着总持仓笔数不应超过2。但实际运行中,策略在一次开仓后会进行多次加仓,而不是我们设定的1次。原因无他,就是因为 strategy.order()
这个“手动挡”函数,直接忽略了我们在 strategy()
中设定的 pyramiding=1
这个自动安全辅助。
既然 strategy.order()
不帮我们管,那我们就得自己动手,我们需要在下单前,手动检查当前的持仓状态,自己来决定是否应该继续下单。
这里我们需要用到两个非常重要的内置变量:
strategy.position_size
:返回当前持仓的总数量。多头为正,空头为负,空仓为0
,我们可以用它来判断是否空仓。strategy.opentrades
:返回构成当前持仓的开仓订单笔数,这个是手动控制加仓次数的关键。- 初始开仓: 只有在当前完全空仓(
strategy.position_size == 0
)时,才允许执行。 - 加仓: 只有在当前持仓笔数正好为1(
strategy.opentrades == 1
)时,才允许执行。
修改后的代码如下:
//@version=6
strategy(title="加仓与 strategy.order()", pyramiding=1)
// 计算
quickMALen = input.int(5, title="快线 MA")
slowMALen = input.int(10, title="慢线 MA")
rsiLen = input.int(9, title="RSI")
quickMA = ta.sma(close, quickMALen)
slowMA = ta.sma(close, slowMALen)
rsiValue = ta.rsi(close, rsiLen)
plot(rsiValue, color=color.blue)
hline(50, color=#87CEEB)
hline(80, color=#87CEEB)
hline(20, color=#87CEEB)
// 必须空仓,才允许下单
enterLong = strategy.position_size == 0 and
ta.crossover(quickMA, slowMA) and
rsiValue > 50
// 必须只有1笔开仓,才加仓
addToLong = strategy.opentrades == 1 and
ta.crossover(rsiValue, 70)
exitLong = ta.crossunder(quickMA, slowMA) and
rsiValue < 50
// 订单
if enterLong
strategy.order("Enter Long", strategy.long)
if addToLong
strategy.order("Additional Long", strategy.long)
if exitLong
strategy.close_all()
我们只修改了 enterLong
和 addToLong
这两个变量的定义,为它们加上了严格的安全带。一旦你决定使用 strategy.order()
并手动管理仓位,strategy()
函数里的 pyramiding
参数就成了一个摆设,对 strategy.order()
的行为没有任何影响了。
总结
strategy.order()
是一个强大而灵活的下单函数,但它的代价是放弃了内置的 pyramiding
检查。
- 当你需要对订单有更精细的控制,但又想限制加仓次数时,必须自己写代码来管理仓位状态。
strategy.position_size
用于检查是否空仓,是控制初始订单的关键。strategy.opentrades
用于检查已开仓笔数,是控制加仓订单的关键。
掌握了这种手动管理仓位的方法,你就能驾驭 strategy.order()
的强大功能,同时又不必担心策略会像脱缰的野马一样失控。