交叉章节的指标会在均线交叉时画标记。现在用同一个事件触发模拟订单。上穿时开立买入持仓,下穿时关闭。

策略会做什么?

指标负责计算和显示,策略还会向回测模拟器发订单。模拟器根据历史 K 线和指定规则,跟踪订单、持仓和结果。

这类历史测试称为回测。本章所有订单都是模拟的,点击 Run Pyne code 不会在真实交易账户中发单。

持仓是入场已成交后持有的头寸;订单是指令;成交则是创建或改变持仓的事件。这三个词不混用。

先用文字写出规则

当前策略的规则:

  • 每根 K 线计算五期和二十期 SMA。
  • 上穿时,为一单位多头持仓发送入场订单。
  • 下穿时,关闭入场标识为 Long 的持仓。
  • 计算使用已收盘历史 K 线的数据。

多头持仓在价格上涨时增值,下跌时减值。本例不建立空头。

这些规则并不意味着每次上穿都会赚钱。回测正是要检查在指定数据上,这些操作本来会发生什么。

完整程序

创建 crossover_strategy.py:

"""
@pyne edge
"""
from pynecore.lib import close, color, input, plot, script, strategy, ta


@script.strategy(
    "Average Crossing Strategy",
    overlay=True,
    initial_capital=10000,
    default_qty_type=strategy.fixed,
    default_qty_value=1,
    pyramiding=1,
)
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),
):
    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")
    plot(fast_average, "Fast average", color=color.blue, linewidth=2)
    plot(slow_average, "Slow average", color=color.orange, linewidth=2)

@script.strategy 标记 main() 是策略。原来的计算与两条线仍可沿用。新增的 strategy 命名空间包含订单操作和策略数据。

装饰器是多行调用,其中设置控制策略运行;main() 参数则是自定义计算的输入。

初始资金与数量

initial_capital=10000 指定模拟初始余额。演示数据自己的市场元数据决定这次运行对应的单位和价格水平。

default_qty_type=strategy.fixed 表示固定数量。default_qty_value=1 要求一单位订单,不是资金的百分之一,也不一定是一单位货币。

pyramiding=1 最多允许一个同方向入场。本例不会通过后续多头入场扩大已有持仓。

学习时用较小的固定数量跟踪操作。结果变化时,需要同时检查的仓位规模因素就更少。

入场与平仓的名称

strategy.entry("Long", strategy.long) 第一个实参是订单标识。Long 文本由程序自定,第二个实参指定方向。

strategy.close("Long") 引用同一个标识,名称必须一致。如果用 "Buy" 入场,关闭 "Long" 并不针对这次入场。

这里下穿用于平仓,不是开空。如果该名称下没有开放持仓,就没有可关闭的头寸。

在 PyneIDE 中运行

  1. 保存完整程序。
  2. 选择 Run Pyne code 和 demo 数据。
  3. 检查图表上的两条 SMA 和交易标记。
  4. 打开图表下方面板,选择 Trades。
crossover_strategy.py 旁显示两条 SMA 线和策略的入场、出场成交标记。
SMA 交叉触发订单,已成交交易也会显示在图表中。

如果没有交易,检查运行的是否确实是策略文件,以及 @script.strategy 是否保留。也检查两个输入的实际值。同源、同长度 SMA 不会彼此交叉。

信号与成交的时间

按这里的默认设置,程序根据 K 线收盘数据发出市价单,通常在下一根开盘价成交。因此信号 K 线和入场 K 线可能不同。

市价平仓也是如此。下穿时生成的平仓单,可能到下一根开盘才关闭持仓。

如果最后一根发出新订单,文件已没有下一根,订单就不一定成交。更早开立的持仓也可能在数据结束时仍开放。

成交模式是一项设置,下一章会在 Properties 中查看。解读结果时,始终要结合生成该结果的成交模式。

自己试一试

打开策略输入,把快慢长度都设为 20。预测两件事:两条线会怎样排列,又能由多少次交叉产生交易?

参考答案

两条 SMA 对相同价格使用相同窗口,因此完全一致。不会出现其中一条越到另一条上方或下方的 K 线,因此该规则不产生开仓。

只有修改后保存输入,并等待重算结束,已有图表才会显示新结果。检查后恢复 5 和 20。

选择一次入场

找一次已成交入场,查看前一根 K 线的两条均线。上穿应在信号 K 线上成立。把成交价与入场 K 线的开盘价比较,不要自动拿信号收盘价比较。