Python 期货策略怎么判断一根新 K 线已经生成
前言用 Python 写 K 线策略时最容易踩的坑是把还在跳动的当前根当成已收盘一根 bar 里信号闪好几次。判断“新 K 线来了”要同时理解DataFrame 里哪一行是正在形成的 bar以及哪一帧该做决策。天勤get_kline_serial返回的 K 线与is_changing配合是团队里很常用的写法。下面说明iloc[-1]与iloc[-2]的含义、如何用datetime变化触发、以及和指标计算怎么对齐。一、K 线 DataFrame 里两行最关键索引含义是否还在变iloc[-1]当前这根随行情更新是high/low/close 都会变iloc[-2]上一根在下一根未出现前已定格否对已走完的那根因此趋势类信号若定义在收盘价上应在iloc[-2]上判断触发计算的时机是“新一根开始出现”即iloc[-1]的datetime相对上一帧发生变化。二、官方对 is_changing 的 K 线说明TqApi.is_changing文档写明当生成新 K 线时其所有字段都算作有更新此时对klines.iloc[-1]做is_changing一定返回 True。实战里更稳的是盯最后一根的datetime字段fromtqsdkimportTqApi,TqAuth,TqSim,tafunc apiTqApi(TqSim(),authTqAuth(账户,密码))klapi.get_kline_serial(SHFE.rb2510,300,data_length200)whileTrue:api.wait_update()ifnotapi.is_changing(kl.iloc[-1],datetime):continue# 走到这里新 K 线刚生成上一根刚收盘ma20tafunc.ma(kl.close,20)close_donekl.close.iloc[-2]ma_donema20.iloc[-2]datetime变化为真时iloc[-2]就是刚收盘的那根适合做一次决策。三、和“用 [-1] 算信号”的区别有人图省事用iloc[-1]的 close盘中会随着 tick 变均线金叉可以闪十几次。回测若与实盘规则不一致回测帧里 [-1] 有时等价于已完成 bar曲线会好看很多、实盘却完全不对。团队规范建议写死本策略所有入场在[-2]判定回测/模拟/实盘同一套代码。回测速度上统一[-2]也减少争论。四、指标 nan 与 data_length新 K 线触发时若ma20.iloc[-2]仍是 nan说明data_length不够或合约上市不久应continueimportmathifmath.isnan(ma20.iloc[-2]):continueget_kline_serial订阅后若再订阅同合约更短长度服务器可能不重复推历史内存 chart 与预期不符遇到 K 线长度异常检查订阅顺序API 内部对 serial 更新有说明。五、多周期策略怎么判断例如 5 分钟出信号、30 分钟过滤各周期各订一条get_kline_serial分别is_changing(kl5.iloc[-1], datetime)与kl30大周期未更新时不要用旧的大周期[-2]冒充新状态可在大周期datetime变化时把当时大周期[-2]的指标缓存到变量供小周期触发时读取。六、tick 策略的边界若策略必须在 tick 级反应就不应再用 K 线datetime作为主触发而要另写降频如is_changing(quote, last_price)加最小间隔。K 线与 tick 混用时必须规定以谁为准否则同一策略两套节奏。总结判断新 K 线在每次wait_update后用api.is_changing(kl.iloc[-1], datetime)为真作为 bar 推进信号决策数据用iloc[-2]表示刚收盘那根。避免用 [-1] 的 close 做收盘型突破防止盘中反复下单和回测实盘偏差。注意data_length、nan 跳过、多周期分别判断 datetime。tick 级策略另写触发规则不要与 K 线收盘规则混用。FAQ1回测里 datetime 变化频率和实盘一样吗回测按历史推送触发逻辑相同即可不要在回测里单独改成 [-1] 而实盘用 [-2]。2主连 KQ.m 判断方式相同吗仍是 serial 的 datetime 变化换月时要单独处理合约切换与 bar 判断正交。3夜盘跳空第一根算不算新 K 线算只要 datetime 字段更新策略里可加交易日过滤避免休市误触发。4能否用 K 线根数自增判断不推荐自己计数以 API 更新的 datetime 为准更稳。风险提示本文讨论技术实现不构成投资建议。