1.8 触发方式与盘前盘后

适用版本 V2V3

本篇重点:本篇讲五种触发方式怎么按策略类型选,以及日内多次触发和盘前、盘后回调怎么设。

1 在哪里设置触发方式

主界面分左、中、右三栏。中间一栏最上面是「触发方式设置」分组:

  1. 点「触发类型」下拉框,可以看到五个选项:Tick触发、1分钟K线触发、5分钟K线触发、日K线触发、自定义定时触发。
  2. 选中一项后,下拉框下面会换成这一项的说明或参数。Tick、1 分钟、5 分钟、日线四种不需要填参数,只显示一行说明;自定义定时触发会显示时间点列表和时间点生成器。
  3. 把鼠标停在下拉框上,会弹出各周期数据的来源说明(V2)。
「触发类型」下拉框展开,五个选项:Tick触发、1分钟K线触发、5分钟K线触发、日K线触发、自定义定时触发
「触发类型」下拉框展开,五个选项:Tick触发、1分钟K线触发、5分钟K线触发、日K线触发、自定义定时触发
提示

触发方式和其他回测参数一起保存在 .kh 配置文件里。点工具栏「保存配置」后,下次「加载配置」会原样恢复。

2 五种触发方式各自怎么工作

2.1 Tick 触发

  • 规则:回测时每一条 tick 数据都会运行一次 khHandlebar。界面说明为「Tick触发无需额外配置,每个Tick都会触发策略」。
  • 需要的数据:tick 数据。V2 里 BaoStock 和 Tushare 都不提供 tick,需要自己把 tick 数据导入 DuckDB 才能用。
  • 特点:触发次数最多,数据量最大,回测最慢。策略里通常要自己加一层过滤条件,条件满足时才下单。
  • 适合:需要逐笔判断价格变化的日内策略。

2.2 1 分钟 K 线触发

  • 规则:每根 1 分钟 K 线运行一次。
  • 需要的数据:1 分钟线。V2 里用 Tushare 下载,需要在 Tushare 开通 stk_mins 权限;BaoStock 没有 1 分钟线。
  • 适合:看分钟级信号的日内策略。

2.3 5 分钟 K 线触发

  • 规则:每根 5 分钟 K 线运行一次。
  • 需要的数据:5 分钟线,可用 BaoStock(免费)或 Tushare 下载。
  • 适合:信号节奏比 1 分钟慢一些的日内策略,回测速度比 1 分钟快。

2.4 日 K 线触发

  • 规则:每个交易日按一根日 K 线运行一次。界面上的说明文字是「每个交易日开盘后触发一次策略」,实际含义是:运行时当天这根日线已经完整,开盘、最高、最低、收盘都是全天的数据;日线时间显示的 09:30 只是日期标记。这一轮生成的买卖信号,按当天收盘价或策略给出的价格成交。
  • 需要的数据:日线,可用 BaoStock 或 Tushare 下载。
  • 特点:数据量最小,回测最快。选中后下方会多出「日内触发上限」,用法见第 5 节。
  • 适合:按日线信号操作的波段、趋势策略。

2.5 自定义定时触发

  • 规则:只在你指定的时间点运行,每个交易日每个时间点只运行一次,运行时刻就是你设定的时间点。
  • 适合:定时调仓,或者只在开盘后、收盘前某个固定时刻操作的策略;也可以用来实现 10 分钟、30 分钟这类没有现成选项的间隔。

操作步骤:

  1. 在「时间点列表(每行一个时间点,格式:HH:MM:SS)」文本框里,每行写一个时间,例如 09:35:00、14:50:00。刚切换到这一项时文本框是空的,只有灰色的格式提示;加载的配置里写好的时间点会显示在这里。
  2. 时间点多的时候,用下面的「时间点生成器」:
    – 「生成器类型」选「均匀分布」「整点分布」或「自定义间隔」,默认是均匀分布。均匀分布和自定义间隔都是从开始时间起每隔 N 秒生成一个点;整点分布只生成整点(如 10:00:00、11:00:00)。
    – 设置「开始时间」(默认 09:30:00)、「结束时间」(默认 15:00:00)、「时间间隔(秒)」(默认 300,即 5 分钟)。
    – 点「生成时间点」。
  3. 生成时软件会做三件事:先清空文本框里原有的时间点;把间隔调整为 3 的整数倍(范围 3~3600 秒,不是 3 的倍数时向下取整);去掉不在交易时段(9:30–11:30、13:00–15:00)内的点,并弹窗告诉你生成了几个、过滤掉几个。
  4. 生成后仍可以在文本框里手动增删。
「生成器类型」下拉框展开,三个选项:均匀分布、整点分布、自定义间隔
「生成器类型」下拉框展开,三个选项:均匀分布、整点分布、自定义间隔

举个例子:开始时间 09:30:00、结束时间 15:00:00、间隔填 1800(30 分钟),点「生成时间点」。从 09:30 到 15:00 每 30 分钟一个点,一共 12 个;其中 12:00、12:30 在午休时间,被过滤掉。弹窗显示「共生成12个时间点,其中10个在交易时段内,已自动过滤掉2个非交易时段的时间点」。

点「生成时间点」后弹出的「生成完成」对话框
点「生成时间点」后弹出的「生成完成」对话框

点「确定」后,文本框里是 10 个时间点:09:30、10:00、10:30、11:00、11:30、13:00、13:30、14:00、14:30、15:00。

生成后的时间点列表,下方生成器的间隔为 1800 秒
生成后的时间点列表,下方生成器的间隔为 1800 秒

自定义定时触发用哪种数据,由时间点自动决定:

  • 所有时间点都是整分钟(秒数为 00):使用 1 分钟线。
  • 只要有一个时间点不是整分钟:改用 tick 数据。

用 tick 数据时,每只股票取设定时间点之前 5 秒内(含这一刻)最新的一笔 tick 作为这次的行情;这 5 秒内没有 tick 的股票,这一次就没有数据。设定时间点之后的 tick 不会被用到,不会有未来数据。

带秒的时间点尽量避开开盘第一秒。例如写 09:30:00 时,有的股票开盘第一笔 tick 在 09:30:03 之后才出现,那一次就取不到数据。

无论用 1 分钟线还是 tick,「全量加载」和「省内存(分段)」两种加载模式下,触发的时间点和取到的数据都相同。

注意

在 V2 里,1 分钟线要用 Tushare(需要 stk_mins 权限)下载,tick 数据要自己导入。使用自定义定时触发前,先确认对应的数据已经在本地。建议时间点都写成整分钟,这样只需要 1 分钟线。另外建议把股票池的日线也一起下载好:自定义定时触发时,每天收盘后的持仓市值和基准都按当天日线的收盘价估值(tick 时按不复权价格),本地没有日线时,才退回用当天最后一个时间点的价格估值。

3 按策略类型选择触发周期

触发周期不能随便选,要先看策略本身按什么节奏做判断,再决定触发方式,最后去下载对应周期的数据。

策略类型 触发方式 需要的数据
日内策略,要逐笔判断 Tick 触发 tick
日内策略,看分钟级信号 1 分钟或 5 分钟 K 线触发 1m 或 5m
波段、趋势策略,按日线信号操作 日 K 线触发 1d
定时调仓、在固定时刻操作 自定义定时触发 整分钟时间点用 1m;有非整分钟时间点用 tick

周期越短,要准备的数据越多,回测也越慢。策略只在收盘价上做判断时,用日线就够了;用分钟线跑同一个日线策略,结果不会更准确,只会更慢。

4 数据周期要和触发方式对应

左侧「数据设置」分组里有「周期类型」下拉框(tick、1m、5m、1d),它决定回测加载哪个周期的行情。对应关系如下:

触发方式 周期类型应选
Tick 触发 tick
1 分钟 K 线触发 1m
5 分钟 K 线触发 5m
日 K 线触发 1d
自定义定时触发 不做检查,按上一节规则自动选数据

点「开始运行」时,如果两者不对应,会弹出「周期不匹配警告」。例如周期类型选 1m、触发类型选日K线触发时,弹窗内容是:

  • 当前配置:数据设置周期为 1 分钟K线,触发类型为日K线触发;
  • 建议配置:数据设置周期为日K线,触发类型为日K线触发;
  • 不匹配可能导致:性能问题(数据精度过高或过低)、触发精度问题(错过关键时间点)、策略执行异常;
  • 最后问「是否继续运行回测?」。
「周期不匹配警告」弹窗,底部是「继续运行」和「停止运行」两个按钮
「周期不匹配警告」弹窗,底部是「继续运行」和「停止运行」两个按钮
  • 点「继续运行」:照当前配置继续回测,运行日志里记一条 WARNING。
  • 点「停止运行」:取消这次运行,回到界面修改。
提示

用自定义定时触发时,建议把「周期类型」也设成实际会用到的周期(时间点都是整分钟就选 1m),这样回测前的数据检查会检查对的周期。

5 日线模式的「日内触发上限」

选中「日K线触发」后,下拉框下面会出现「日内触发上限」,范围 1~100,默认 1。其他触发方式下这一项隐藏、不生效。

选中「日K线触发」时,下拉框下方多出「日内触发上限」,默认 1;再下面是这种触发方式的说明文字
选中「日K线触发」时,下拉框下方多出「日内触发上限」,默认 1;再下面是这种触发方式的说明文字

默认值 1 表示每天只运行一次 khHandlebar。要在同一天运行多次,做两件事:

  1. 把「日内触发上限」设为需要的最大次数,例如 2。
  2. 在策略的 khHandlebar 里调用 khRequestNextDailyTrigger()。

规则:

  • khRequestNextDailyTrigger() 返回 True 表示申请成功。框架先处理本轮返回的交易信号,再用同一天的行情数据立即再调用一次 khHandlebar,这时账户资金和持仓已经是本轮成交后的状态。
  • 当天的总运行次数不会超过「日内触发上限」。已经到上限,或者当前不是日 K 线触发时,函数返回 False,不会再运行。
  • 第二天重新计数。
  • 同一天运行多轮时,回测报告的「日收益」和每日统计每天仍然只记一行,在当天最后一轮之后记录;当天收益相对上一个交易日收盘后的总资产计算。

典型用法是「先卖后买」:第 1 轮只处理卖出,释放资金;第 2 轮用卖出后的资金处理买入。下面是结构示意,交易条件需要自己补充:

from khQuantImport import *

STATE = {"date": None, "round": 0}

def khHandlebar(data):
    signals = []
    date_str = khGet(data, "date")

    # 换了新的一天,轮次从 1 开始;同一天再次进入,轮次加 1
    if STATE["date"] != date_str:
        STATE["date"] = date_str
        STATE["round"] = 1
    else:
        STATE["round"] += 1

    if STATE["round"] == 1:
        # 第 1 轮:检查持仓,生成卖出信号
        # signals.extend(generate_signal(data, code, price, 1.0, "sell", "卖出原因"))
        khRequestNextDailyTrigger()   # 申请当天再运行一次
    elif STATE["round"] == 2:
        # 第 2 轮:用卖出后的可用资金生成买入信号
        pass

    return signals
注意

「日内触发上限」保持 1 时,调用 khRequestNextDailyTrigger() 会返回 False,第 2 轮不会发生。写了多轮逻辑的策略,记得把上限调到对应的次数。

6 盘前、盘后回调

中间一栏的「盘前盘后触发设置」分组有两行:

  • 「触发盘前回调」+「运行时间」,默认 08:30:00;
  • 「触发盘后回调」+「运行时间」,默认 15:30:00。

两项默认都不勾选。勾选后:

  1. 每个交易日开始、当天第一次触发之前,框架调用策略里的 khPreMarket(data)。盘前回调里只能看到盘前已经知道的行情:每只股票上一个交易日最后一根 K 线的数据(日线模式就是上一天的日线),看不到当天开盘后的价格。回测第一天没有上一个交易日的数据,这天盘前回调里取不到个股行情,策略里要做好判断。
  2. 每个交易日最后一次触发之后,框架调用策略里的 khPostMarket(data)。回测最后一天也会调用。
  3. 「运行时间」里填的时间会作为这次调用的当前时间传给策略,用 khGet(data, "time") 之类的函数取到的就是这个时间。
  4. 策略文件里要有同名函数。勾选了但策略里没有写,运行日志会给出警告,回调不执行。

回调里也可以返回交易信号,但不会立即成交,框架会把它们转成限价挂单:

  • 盘前回调的信号:当日有效,当天行情满足限价时成交。
  • 盘后回调的信号:一律转为下一个交易日的挂单,有效到下一个交易日收盘。回测最后一天的盘后信号没有后续行情可以成交,按未成交(过期)处理,不改变资金和持仓。

常见用途:

  • 盘前:确定当天要关注的股票、重置当天的状态变量。
  • 盘后:统计当天的交易、记录持仓和资产,为第二天准备数据。
中间一栏下半部分:「账户信息」分组,以及「盘前盘后触发设置」分组(已勾选「触发盘前回调」,运行时间 08:30:00)
中间一栏下半部分:「账户信息」分组,以及「盘前盘后触发设置」分组(已勾选「触发盘前回调」,运行时间 08:30:00)

7 账户信息

中间一栏的「账户信息」分组有两项:

  • 初始资金:回测开始时账户里的现金,默认 1000000。回测报告里的「初始资金」、收益率都以它为基准。
  • 最小交易量:默认 100,会随配置一起保存,并写进回测记录。

这两个输入框见上一节的截图。

提示

策略里计算买入数量时,可以用 calculate_max_buy_volume 按可用资金算出最多能买多少股,结果按 A 股 100 股一手取整。

V3 差异V3 的触发方式与 V2 相同,另有现成案例

V3 的触发方式、日内触发上限、盘前盘后回调和账户信息与 V2 完全相同。不同的是 V3 自带相关案例可以直接照着学:「日内多次触发」案例演示了 khRequestNextDailyTrigger() 先卖后买的写法;T+0 ETF 网格案例演示了分钟级的日内交易。V3 的数据来源也更多(见 1.4 的 V3 亮点)。
※ 策略案例股票池只是示例(请换成你自己选的标的),关键参数含随机数,只用来演示写法,不构成任何策略或投资建议。

常见问题

问:选了 1 分钟 K 线触发,开始运行后提示周期不匹配,怎么办?
答:把左侧「数据设置」里的「周期类型」改成 1m,并确认本地已经有这些股票的 1 分钟线。V2 的 1 分钟线要用 Tushare 下载。

问:日线策略能不能改用 5 分钟触发,让结果更准?
答:不能提高准确性。策略按日线数据判断时,用日 K 线触发就够了。换成 5 分钟触发,策略每天会运行 48 次,还需要准备 5 分钟线,回测变慢,信号也可能因为日内价格变化而和原意不同。

问:自定义定时触发写了 09:30:15 这样的时间,回测报数据缺失?
答:只要有一个时间点不是整分钟,软件就改用 tick 数据。V2 里 tick 需要自行导入。把时间点都改成整分钟,就只需要 1 分钟线。

问:自定义定时触发用了 tick 数据,09:30:00 这个时间点有的股票没有数据?
答:tick 模式下,每个时间点只取前 5 秒内的最新一笔 tick。开盘第一笔 tick 可能在 09:30:03 之后才出现,这时 09:30:00 就取不到。把时间点往后挪几秒(例如 09:30:05)即可。

问:调用了 khRequestNextDailyTrigger(),但每天还是只运行一次?
答:检查两处:触发方式必须是「日K线触发」;「日内触发上限」要大于 1。

问:盘前回调里下的单为什么没有马上成交?
答:盘前、盘后回调返回的信号会转成限价挂单,要等后面的行情满足限价才成交。盘前单当日有效;盘后单转为下一个交易日的挂单,有效到下一个交易日收盘。回测最后一天的盘后单没有后续行情,不会成交。

V3

V3 带了现成的案例可以照着学
  • 「日内多次触发」案例:演示 khRequestNextDailyTrigger 的用法
  • T+0 ETF 网格案例 4 个
  • 数据库指标读写案例 4 个

※ 策略案例股票池只是示例(请换成你自己选的标的),关键参数含随机数,只用来演示写法,不构成任何策略或投资建议。

本篇基于开源 V2 和 V3.4.1.10 编写。

×
没有账号?注册  忘记密码?

风险提示

投资有风险,开户需谨慎。本系统仅为投资者提供量化交易相关的数据处理与分析工具,不构成任何投资建议。 请您在审慎思考后作出选择。特别声明:本系统对您与券商之间的交易、合作不承担任何法律责任。 市场有风险,投资需谨慎。

© 2024 khQuant看海量化回测平台 版权所有

官网:www.khsci.com/khQuant