出场与持仓规模
给策略添加止损和目标价出场,并检查以 tick 表示的距离。
第一个策略只在反向交叉时平仓。现在再加入相对入场价的亏损和盈利距离,同时保留原来的交叉平仓。
三种不同出场原因
本例多头持仓可能由三个事件关闭:
- 价格达到止损单的价位;
- 价格达到止盈限价单的价位;
- 快线下穿慢线,且市价平仓单成交。
止损和限价单带价格条件,strategy.close 发出市价平仓单。成交规则可能不同,所以交易表中的价格和时间都要检查。
距离还是具体价格?
strategy.exit 支持两类设置方式:
| 实参 | 指定什么? |
|---|---|
loss | 亏损距离,单位 tick |
profit | 盈利距离,单位 tick |
stop | 具体止损价 |
limit | 具体限价 |
loss=100 不是 100%,也不一定是 100 单位货币,而是相对入场价相距一百 tick。
DEMO 的 tick 大小为 0.01,因此一百 tick 是 1 价格单位,二百是 2。假设多头入场价为 200,不计滑点和其他成交影响,对应止损 199、目标 202。
完整程序
创建 protected_strategy.py:
"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta
@script.strategy(
"Crossing Strategy with Exits",
overlay=True,
initial_capital=10000,
default_qty_type=strategy.fixed,
default_qty_value=1,
pyramiding=1,
commission_type=strategy.commission.percent,
commission_value=0.1,
slippage=2,
)
def main(
fast_length: int = input.int(5, title="Fast length", minval=1, maxval=200),
slow_length: int = input.int(20, title="Slow length", minval=1, maxval=200),
stop_ticks: int = input.int(100, title="Stop distance (ticks)", minval=1),
target_ticks: int = input.int(200, title="Target distance (ticks)", minval=1),
):
fast_average = ta.sma(close, fast_length)
slow_average = ta.sma(close, slow_length)
crosses_up = ta.crossover(fast_average, slow_average)
crosses_down = ta.crossunder(fast_average, slow_average)
if crosses_up:
strategy.entry("Long", strategy.long)
if crosses_down:
strategy.close("Long")
strategy.exit("Bracket", "Long", loss=stop_ticks, profit=target_ticks)
plot(fast_average, "Fast average", color=color.blue, linewidth=2)
plot(slow_average, "Slow average", color=color.orange, linewidth=2)Bracket 是出场订单组标识,第二个实参 Long 指定关联哪次入场。loss 和 profit 使用上面两个输入。
每根 K 线都用相同标识执行出场调用,管理指定出场规则,不是每次都建立一份独立的新持仓。
在演示数据运行。Trades 中除了交叉触发的市价平仓,也可能出现 Bracket 出场。

保护性出场何时出现?
程序可以在同一次执行中发出入场及其关联出场指令。执行器能把 tick 距离关联到入场实际成交价。
如果反而根据信号收盘价计算具体 stop,这个价位就以信号价为起点。下一开盘价不同,实际入场到止损的距离也就不同。
应按想表达的规则选择。loss 是相对入场的 tick 距离,stop 是具体价位。
一根 K 线没有记录所有价格步骤
OHLCV 提供开盘、最高、最低、收盘,但不会自动告诉我们内部所有价格的先后顺序。
如果同根最高价达到目标、最低价达到止损,仅这四个数无法判断哪一个先发生。模拟器此时采用执行模型的规则。更低周期的数据可支持更细的检查。
这种情况要单独核查,不要手动总选有利结果。模型假设属于结果的一部分。
止损价也不保证精确成交。如果下一根跳空开在止损另一侧,成交可能比被跳过的价位更差。滑点还可能造成额外偏差。
距离与亏损金额
一单位、点值为 1 的多头持仓,在 tick 为 0.01 时,一百 tick 对应 1 单位货币的价差。数量为十时,金额结果也扩大十倍。
数量、tick 大小和点值共同决定到止损的变动对应多少钱,还要考虑手续费与实际成交条件。
在订单中直接指定 qty,就是这张订单自己的数量。本例使用默认数量,也可在 Properties → Order size 中覆盖。
DEMO 练习的 100、200 tick 只用于示范。在其他品种中,同样数字可能代表不同价格距离和金额。
自己试一试
保持快慢长度、数量和成本不变,分别运行止损/目标为 100/200 与 200/400 的版本。检查同一入场信号最终发生什么。
参考答案
只修改 Inputs 中的 Stop distance (ticks) 和 Target distance (ticks)。距离增大可能让持仓在另一根 K 线、或因另一原因平仓。
交叉平仓在两个版本中都保留,所以目标更远不代表一定持有到目标。出场规则共同起作用。
保存输入后要等待重算结束,再读取新结果。若想以后比较,将两份导出保存为不同名称。
找到出场原因
选择一笔已平仓交易,检查入场价、tick 距离和出场 K 线的 OHLC。根据出场价格与时间,判断哪项规则解释该交易。如果同根触及多个价位,还要考虑执行模型。