---
title: "概念-AlphaGPT-择时框架的频率无关设计"
date: 2026-07-21
tags: [AlphaGPT, 择时, 元认知, 频率, 概念]
source: "AlphaGPT择时框架"
---

## 一句话(元认知)

**内核只认"第几根K线"这个序号,与日频/分钟频无关;频率不是内核的一部分,只是"翻译成
人话"时才需要的一层换算,应该由数据决定、由用户显式告知,而不是硬编码。** ^核心洞察

> 这条是使用者自己悟出的:"把 DataFrame 的时间列抹掉,系统也不知道是日频还是分钟频,
> 所以这项目本来就该和频率无关。"

---

## 为什么内核天然频率无关

把时间列抹掉后,`pivot_table` 拿到的就是 `[N品种, T]` 矩阵——**T 只是"第几根bar"的序号,
系统根本不看它是日还是分钟**。往下所有环节都只认这个序号:

```
  滚动算子 TS_MEAN(窗口5)  →  "过去5根bar"    ← 不是"5天"
  DELAY1                    →  "前1根bar"      ← 不是"昨天"
  target = log(bar_{t+1+H} / bar_{t+1})  →  "未来H根bar的收益"
  valid_mask / 换手 / 成本   →  全部按bar
```

**整条挖掘链路里没有任何一处出现"日历"。** 它处理的是"一串等间隔的时间步",间隔多久
它不知道也不关心。所以日线换成5分钟线,挖掘照跑,挖出的公式一样有效。 ^内核无日历

---

## 那些"日"是伪装,不是内核

系统里两处出现过"日",性质完全不同——它们是**解读层的化妆**,不是内核:

### ① backtest 的 `sqrt(252)` 年化因子
```python
mu / sd * (252 ** 0.5)
    ↑ 频率无关的真身(每根bar夏普)  ↑ 只为让数字"看起来像年化"
```
关键:它对所有公式是**同一个常数,不影响公式之间的排名**。所以对"挖矿选公式"这个核心
目的完全无所谓。它唯一错处:①分钟数据下夏普**绝对值**失真(低估约√48倍);②会干扰
复杂度惩罚(那是绝对值相减,不是排序)。 ^sqrt252是化妆

### ② classify_factor 的"20日"(已修正)
基准因子曾命名"动量(20日)",但 `close.shift(20)` 算的是"20根bar"。分钟数据下
"20日"名不副实。**已改为"20根K线"**,见 [[概念-AlphaGPT-因子可解释性#^K线命名]]。 ^日字已修正

---

## 正确的设计哲学:两种做法

那两处不该"假装知道频率"。正确做法二选一:

- **彻底不假装**:夏普输出 `mu/sd`(每-bar夏普),基准命名用中性的"N根K线"。系统从头到尾
  不提频率,谁传什么频率都对。(当前"日→K线"的修正走的是这条路。)
- **让用户告知**:加可选 `periods_per_year`(日频=252、5分钟≈12096),只在展示"年化夏普"
  和"周期命名"时用它翻译,默认退回"每-bar"表述。

倾向第一种——最符合"项目本就该频率无关"的本质。副产品:改用 `mu/sd` 后,复杂度惩罚的
标定也跟着变频率无关(否则 penalty 系数会因频率不同而错乱)。 ^两种做法

---

## 可迁移的通用教训

这条元认知不止适用于本框架:**任何"处理等间隔时间序列"的系统,都应把"频率"隔离在
解读层,内核只操作序号。** 一旦内核里混入 252、"日"这类日历常量,就默默绑死了频率,
换数据就出错且难察觉(因为不报错,只是结果名不副实)。 ^通用教训

---

## 相关笔记
- [[MOC-AlphaGPT择时框架]] — 架构入口
- [[概念-AlphaGPT-回测评分与仓位映射]] — √252 出现在夏普计算里
- [[概念-AlphaGPT-因子可解释性]] — 归类单位改用"K线"
- [[概念-AlphaGPT-数据加载与期货缺失值处理]] — target 也是按"根bar"算

