先确认字段真实存在,并查有没有现成的因子。
现成因子里没有直接叫「W底」的字段。再看一下 K 线形态表里有没有可用的。
上一步的版本 3 在窗口没满的行上报错,因为向量里有 NULL。我把它改成不用列表的写法,用分步计算,再重新验证。
可检验的说法: 当一只股票最近约 60 个交易日走出"跌、涨、再跌、再涨"的 W 形,且现价回到中间那个高点(颈线)附近时,未来 20 个交易日,它倾向于比其他股票涨得更多。
先说明"因子":就是每天给每只股票按同一条规则打一个分,分越高越符合你的盘感。下面共列了 3 个版本,都保留,下一步一起检验。
| 盘感原话 | 可计算的定义(大白话) | 用到的字段 | 方向 |
|---|---|---|---|
| 股票形成 W 底(版本1,几何法) | 把 60 天分成前后两半,各取一个最低点。两个底越接近越好,相差 5% 以上记 0 分。两底之间要反弹到颈线,反弹幅度达到 10% 记满分。现价越靠近颈线分越高。三项相乘,0 到 1 分,只要有一项很差,总分就接近 0。 | cn_stock_bar1d:low、high、close | 越大越像 W 底,越看涨 |
| 同上(版本2,分段涨跌法) | 把 60 天切成 4 段,每段 15 天,W 应该是"跌、涨、跌、涨"。算出 4 段各自的涨跌幅,方向对了才算正,取最不像的那一段作为得分。4 段都明显才会得高分,所以这个分数很严格。 | cn_stock_bar1d:close | 越大越像 W 底,越看涨 |
| 同上(版本3,模板相似度法) | 在 60 天里每隔 10 天取一个收盘价,共 7 个点。拿这条走势去跟一条理想的 W(高、中、低、反弹、低、中、高)比相似度,范围是 -1 到 1。它不管涨跌幅大小,只看形状像不像,所以不要求两个底精确对称。 | cn_stock_bar1d:close | 越大越像 W 底,越看涨 |
三个版本的计算都写在 w_bottom_defs.sql。
- 现成因子: 我查了
cn_stock_prefactors和cn_stock_factors_ta_pattern,没有 W 底或双底字段,只有锤子线、早晨之星这类 1 到 3 根 K 线的形态,跟 60 天的 W 不是一回事,所以自己定义。 - 验证: 我用最新交易日(2026-10-28)对全 A 的 5576 只股票试算过。三个版本都能算出值,没有异常值,三个分数的取值范围也都符合上面的定义,只是版本2 的得分普遍偏低。最新一天的 5576 只里,版本1 得分超过 0.5 的有 158 只,说明它不是只挑出极少数股票。
我采用的默认假设:
- W 的观察窗口取 60 个交易日,时间区间取 2023-10-29 至今,用后复权价(把分红送股的影响抹平,走势才连续)。
- 范围是全 A,ST、停牌和涨跌停股票这一步没有剔除,留给后面处理。
- 20 个交易日后的涨跌是下一步才算的标签,这一步没有计算。
- 你没填例子,所以没有拿具体股票校准形态。
做不了的部分: "形态是否好看"的主观判断没法量化,我只能用上面三种数学方式近似。你没提放量突破颈线,我就没加成交量条件。
我做了什么:把"W 底"翻译成 3 个可计算的版本,并确认了字段存在,也在一个交易日上试算通过。为了试算,我临时启动了 AIStudio(启动时显示 6.4 宽币/分钟),试算完已经停掉。
先读产物文档和相关算子签名,再动手写 SQL。
先确认几处数据细节:停牌日在行情表里是否有记录、换手率是否有空值和零值、上市天数表的覆盖情况。
停牌日的换手率记为 0,会拉低窗口标准差,所以这些天要当作缺失。先测一下 m_nanstd 对缺失值的处理,以及过滤条件会不会被下推到窗口里。
最终空值有 14.97 万条,比"填充 1.36 万条"大一个量级,不能直接放过。先查这些空值落在哪些日期和标的。
这 51 个日期整天的中性化结果都是空,而中性化前的值是好的。我怀疑是个别股票的行业为空,导致整天的回归失败。先验证。
第一步和第二步已完成。第三步先用 SQL 算 IC 和分组,再和独立的 numpy 小样本核对。核对通过才采用 SQL 结果。
面板里的 o1(T+1 开盘价)全是 NULL,所以 ok 也全是 NULL。同时 c_ntile 对 NULL 输入仍然给出了组号。这是两个问题,先分别定位。
开头还在导入已删除的 sql_panel,改成 build_panel 后重跑。
IC 均值 0.088 偏高,而且分组、多空的数字还没看过。写报告之前,先把 json 里的关键结果读出来核对。
多空净值看起来很好,但面板里有收益 -100% 和 +419% 的极端值。极端值落在哪一组,会直接影响 G1 和 G10 的均值,所以先查清楚,再决定怎么写进报告。
三步结果都在 json 里了。第四步先写绘图脚本,再写 HTML 拼装脚本,所有数字都从 json 读取。
先把一个小遗漏补上。直方图需要按分箱正负分别着色,绘图脚本要支持按柱子指定颜色。另外让极端值核查和主检验用同一口径,再重跑一次。
语法没问题,页面里也没有外链。再用一个最小 DOM 桩,真正执行一遍 8 张图的绘制代码,确认运行时不报错。
8 张图都能正常绘制。最后抽查一下报告里的几句关键文字,再停掉 AIStudio。
报告已生成:。AIStudio 已发出停止指令,状态显示为 stopping,运行期间按 6.4 宽币/分钟计费。
- 第一步 加工(约 51 秒): 用一条 DAI SQL 完成股票池过滤、行业中位数填充、缩尾、z-score 和中性化,共 818 万行。每日均值为 0、标准差为 1,没有重复键,与对数市值的相关系数从 0.21 降到约 0。第一次跑时有 35 个交易日整天为空,原因是个别股票缺行业,导致当天的回归整体失败。我已把行业缺失的股票并入剔除条件,重跑后空值为 0。
- 第二步 落库(约 16 秒): 已按
date, instrument唯一键覆盖写入dfjafa,附带说明文档。回读行数一致,为 8,182,130 行。 - 第三步 检验(主检验约 63 秒,另有对账和极端值核查): RankIC、十分组和多空都已算完,结果在 json 里。IC 用 SQL 算,与 numpy 逐日对账,最大差约 1e-15。分组一开始不能直接用 SQL 出的面板:与因子表 JOIN 后,T+1 价格全部变空;
c_ntile对空值也会给出组号。所以分组改为在「T+1 可买入」的样本里用 numpy 切,并核对到与c_ntile完全一致。 - 第四步 报告: 自包含离线 HTML,共 8 张图,所有数字都读自 json。报告生成脚本只跑了 0.1 秒,写脚本和校验图表的时间没有单独计时。
结论: 总评为「有效,但有保留」。RankIC 均值 0.088,Newey-West t 值 12.4,十组收益逐级上升,扣费后多空每个年度都为正。有几点要注意:
- 收益约七成来自空头一侧,A 股个股不一定做得了空。
- 因子与平均换手率的相关系数为 -0.63,大体是低换手因子的变体。
- 2023 和 2025 年的年度 IC 超过 0.1,按课程口径属于「可疑」档。
- 随机因子对照里有一组的 |t| 略超 2。
- 没有样本外数据,报告里的原因解释已标注为「猜测」。
先读 SDK 文档、参考示例和因子表说明,同时建立任务清单。
文档输出被截断了,先读完整的 strategy/results/pitfalls,再读 sql.md 和 tuning.md。
还在进行中…
|1m 19s- 第一步 方向判定与规则卡
- 第二步 训练+验证段回测
- 第三步 过拟合体检
- 第四步 测试集与 HTML 报告