跳到正文

研究指南

资料归档与持续复查

定时选股怎么设置:先更新数据,再运行和核对候选名单

定时选股可靠与否,取决于目标数据日期的整条依赖链有没有完成。先确定交易会话,再刷新股票池和字段、验证日期与数值、执行规则、比较上次名单,最后才放行新结果。定时器触发只证明收到了一次启动请求,不证明今天的数据已经更新,更不证明筛选已经执行成功。

本文用独立Python对象演示这条链。调度标记默认关闭,不注册系统任务,发布只表示接受一个内存结果。用户手动传入合成数据调用dry-run,不启用Vibe调度、不运行模型、不发送消息、不下单,也不声称CoTrading已经提供对应功能。执行一次文件后,不会留下后台服务等待下次触发。

把时间合同写到数据日期

先明确股票池、规则版本、预期数据日、市场时区、允许启动窗口和交易日历来源。区分“要处理哪一天”与“请求什么时候抵达”。例如10月20日会话的请求16:30抵达,17:00再次重试,它们仍属于同一个更新时段。如果直接用完整触发时间戳做任务键,同一天就可能重复生成或发布多份结果。

合成日历只包含2026年10月19、20、21日,24日视为休市;允许时间是固定UTC+08时区16:00之后。这不是完整交易所节假日表。Python datetime文档说明带时区时间对象,程序拒绝缺时区或其他偏移,避免把服务器本地时间误当市场时钟。真实日历需要另外提供并核对版本。

实际安排还应处理提前收市、特殊交易日和供应商交付延迟。收盘后并不代表所有规则字段已经到达,例如财务指标更新、最终行情确认可能晚于交易结束。允许触发时间只是一道前置条件,字段实际可用仍要在每次运行时检查,不能凭“设置了16点”就跳过数据验证。

让刷新成为必须完成的前置步骤

样例refresh方法实际被调用时写入事件轨迹,并深复制传入的离线供应商载荷。这个载荷是数据适配器的替身,不是假装真的联网。接入真实数据时,适配器要返回股票覆盖、字段日期和来源;发生超时就终止当前流程,不能拿上次名单接着向下运行,再以新日期对外展示。

本例股票池精确是AAA和BBB,校验要求两只都在,字段日期等于目标交易日,PE存在且为有限正数。Decimal官方说明包含特殊数值,因此程序解析后还检查NaN和正负无穷。字段缺失、日期陈旧、非正PE是不同原因,虽然最终都可能阻止本次发布,日志也应保留具体失败位置。

扩展规则时,先补字段合同,再扩大执行。前瞻EPS、流动性或行业排除各自需要期间、单位和覆盖要求。供应商只返回容易取得的公司时,不能悄悄缩小股票池,筛出空名单后仍说原任务已成功。完整股票池与缺失覆盖名单应能够对账,避免数据失败被误解为市场没有符合条件的公司。

校验通过后筛选,再计算名单变化

规则为正PE小于20。上次接受结果日期2026年10月19日,名单只有AAA。20日新载荷AAA为25、BBB为18,因此筛出BBB;差分显示BBB新增、AAA移出。只有刷新、校验、筛选和差分全部完成,程序才更新已接受结果,并将逻辑时段screen-v1:2026-10-20记为成功。

实际方法轨迹依次是refresh:2026-10-20、validate、screen、diff、publish_in_memory。这些事件由真正执行步骤的方法写入,不是最后让模型概括“我完成了哪些步骤”。因此它能证明本地脚本的执行顺序,但不能扩张为真实行情、公告或产品自动化集成已经运行的证据。解释范围要与执行范围一致。

rows = self.refresh(day, payload)
self.validate(rows, day)
symbols = self.screen(rows)
# 完整程序随后计算差分,再接受带日期结果。

下载完整示例。需要Python 3.12+,仅用标准库和合成数据,保存后运行python R550.py。完整文件包含日历、时间、差分、内存放行、失败分支与断言,不需要配置模型或后台任务。

把当前失败与历史成功分开保存

先注入供应商超时,输出状态blocked、原因和空的current_result,上次接受结果仍标10月19日。再把20日载荷的一行日期改成19日,此次刷新成功但验证失败。第三次删除所需PE字段,也在验证处阻断。它们失败机制不同,轨迹可以说明究竟没有取到数据,还是拿到了不合格数据。

失败不会消耗成功时段,修正后允许重试20日。若失败也标done,会妨碍恢复;若把旧名单改贴20日日期,就制造“已核对今天条件”的假象。历史名单可以作为上下文展示,但原日期与当前失败要同时可见。将last_success和current_attempt分开,是为了不让一个有效旧结果掩盖当前任务没有完成。

本例采用全股票池校验通过才发布,不提供局部覆盖放行。确实需要允许部分公司可用时,应另写最低覆盖、排除公司和可见状态,不能继续使用完整成功标签。否则用户无法区分“只有BBB符合条件”和“只取得BBB数据”,而这两个结果对后续研究的意义完全不同。

休市与重复触发各有独立出口

10月24日请求返回closed,不调用刷新。20日16:30已经成功后,17:00再次触发返回duplicate_suppressed,同样不刷新也不再次发布。去重键是规则版本加目标交易日,不是抵达时刻、随机运行号或最终名单。这些值可能变化,但不应让同一预定更新被重复接受。

示例为单进程、内存状态,不保证多工作器并发、进程崩溃或外部消息投递的严格一次效果。扩展时需要持久保存逻辑时段,并协调接受结果与外部动作。已经成功的某日收到供应商纠错时,也要定义复核和版本规则,不能随意绕过去重,把修订当成原成功记录悄悄覆盖。

把启用动作与手动试跑分开

默认调用就是手动dry-run;若传dry_run=False而调度仍关闭,返回scheduler_disabled,数据步骤都不执行。这个标记只是演示边界,不是指导用户开启真实调度。真正接入需要可用调度器、数据权限、持久状态、失败监控和明确结果目的地,本教程没有配置任何这些外部服务,也没有假产品点击路径。

将来集成前,回放正常日、未到时间、休市、陈旧字段、缺字段、超时和重复时段,检查状态以及真实方法调用。确认失败修复后能完成,同日成功后不会重复放行,旧结果日期始终保留。描述验收时应说“这些本地分支已测试”,不能说整套Vibe或CoTrading服务已经在线可用。

保留能解释名单的运行记录

每次尝试记录目标时段、接收时间、日历判断、数据标识、验证错误、规则版本、候选名单、增删差分和执行轨迹。上次接受结果独立于本次尝试保存。股票池、规则或数据口径改变时建立新审阅版本,让后来的人知道名单变化究竟来自公司数据、筛选规则还是覆盖范围改变,而不是凭最终结果猜原因。

还应预先约定空名单的含义:只有完整数据通过、规则实际运行后,零候选才是有效空名单;未完成刷新或缺字段时不能转换成空数组冒充完成。日志中保留验证覆盖数量和筛选输入数量,能够把两种情况分开。收到新数据修正时,先检查是否需要重开逻辑时段,再让审阅者看到前后版本的来源与差分。

让重试继续处理同一个问题

失败后修复数据,再试仍应使用原目标交易日和规则版本,不能因为请求晚了一小时就自动变成另一个任务。若跨到次日,先决定是在补做昨天,还是按今天合同运行,两者要分别记录。这样能防止供应商延迟使名单日期漂移,也能让去重键始终表达用户原先预定的更新,而不是服务器收到请求的偶然时刻。

重试前核对数据快照是否完整,不能只把缺失公司补到一份已经变化的旧表,却没有说明其他公司字段来自哪里。真实来源最好提供批次标识或冻结导出,确保同次筛选数据能重现。样例深复制载荷只是本地隔离,不等于已经实现远端一致快照;接入时需要根据来源能力明确能保证的粒度。

名单差分还应保留对照基准日期。本例BBB新增、AAA移出是相对19日名单,并不是一天内的成交行为,也不是策略收益。若前一成功距离今天很久,差分覆盖的是整个间隔,不能写成“今日变化”。展示新旧日期和规则版本,可以帮助用户判断这是数据更新产生的候选变动,还是长期失败后恢复的一次跨期比较。

常见问题

运行文件会创建定时任务吗?

不会,只执行一次本地试跑和断言,调度保持关闭。

失败后还能显示旧名单吗?

可以,但必须保留原日期并明确本次失败,不能贴成今天新成功结果。

相关阅读