Metadata-Version: 2.4
Name: quant1x-foundations
Version: 0.1.20
Summary: Quant1X Foundations
Author: Quant1X
Author-email: Quant1X <wangfengxy@sina.cn>
License-Expression: MIT
Project-URL: Homepage, https://codeberg.org/quant1x/foundations
Keywords: monorepo,foundations,benchmark,performance
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: holidays>=0.50
Requires-Dist: mopr>=0.0.99
Requires-Dist: requests>=2.32.0
Provides-Extra: legacy
Requires-Dist: pandas>=2.1.0; extra == "legacy"
Requires-Dist: numpy>=1.26; extra == "legacy"
Requires-Dist: loguru>=0.7.3; extra == "legacy"
Requires-Dist: icecream>=2.1; extra == "legacy"
Requires-Dist: PyYAML>=6.0; extra == "legacy"
Requires-Dist: python-dateutil>=2.9.0; extra == "legacy"
Requires-Dist: GitPython>=3.1; extra == "legacy"
Provides-Extra: full
Requires-Dist: matplotlib>=3.8; extra == "full"
Requires-Dist: TA-Lib>=0.4.28; extra == "full"
Requires-Dist: tqdm>=4.66; extra == "full"
Requires-Dist: akshare>=1.14; extra == "full"
Provides-Extra: scripts
Requires-Dist: pdfminer.six>=20221105; extra == "scripts"
Provides-Extra: dev
Requires-Dist: ruff>=0.17; extra == "dev"
Requires-Dist: pyright>=1.1.414; extra == "dev"
Requires-Dist: pandas-stubs>=2.1; extra == "dev"
Dynamic: license-file

# foundations

Quant1X 基础设施库 —— monorepo、多语言、偏数据标准化。

**Python 是 spec，Rust 是生产实现。** 任何语义都先在 Python 侧落成可读的契约与用例，再由 Rust 逐项对齐、扛生产流量。

> 当前仅收录 **panshi（磐石）**，其余目录为存量代码，尚未纳入新契约体系。

## 项目定位

金融数据的难点不在算得快，而在算得**一样**：同一份数据在不同语言、不同服务、不同批次里，如果边界语义各说各话（`T+1` 到底踩哪一天、非交易日要不要出点、缺失值填 0 还是 NaN），下游所有结论都不可复现。

foundations 的做法是把这些语义从业务代码里抽出来，做成一层可共享的基础设施：

- **数据标准化**：交易日历、证券代码、时区与时间粒度、数值精度与缺失值表示 —— 凡是需要跨服务对齐的东西，先在这层钉死定义；
- **多语言同构**：同一套语义在每种语言里有一份同名实现，跑同一批测试用例，杜绝“Python 原型是一套、生产是另一套”；
- **monorepo 收拢**：所有语言实现放在一个仓库、按模块并列，语义改动一次提交同步走完。

## 双语言角色分工

| 角色 | 语言 | 职责 | 产物 |
| --- | --- | --- | --- |
| **spec** | Python | 定义数据契约、算法语义、边界条件；以可执行用例把语义固化下来；负责人工校对与快速试错 | `panshi/**/*.py` |
| **production** | Rust | 按 spec 逐项实现，面向服务的性能与内存/类型安全；不允许自行发明语义 | crate 根在仓库根：`Cargo.toml` + `lib.rs`，模块按同名目录展开（`panshi/mod.rs`） |

一致性规则（违反即视为缺陷）：

1. **语义先落地再实现**：能在 Python 侧跑出确定结果的语义，才允许进 Rust；Rust 不得引入 spec 中没有的行为分支。
2. **同一批用例两种语言都跑**：用例以数据边界（节假日、跨时区、跨粒度、缺失输入）为重点，不允许只对某一侧放宽。
3. **冲突以 spec 为准**：两侧结果不一致时，判定依据是 Python 侧的描述与用例，修正方向永远是改 Rust（除非确认 spec 描述错了，那先改 spec 再同步）。
4. **同义同名**：模块名、类型名、枚举成员名跨语言保持一致，便于按名字回溯。

> 仓库历史中存在 Go 实现（`mpr/scoring`）。按当前定位，新语义不再在 Go 侧扩展，语言并行轴线收拢为 Python / Rust。

## 当前收录：panshi（磐石）

磐石，数据域基础设施，承接上面说的“数据标准化”。目前只有一块：

### 日历契约 `panshi/data/calendar.py`

两个概念，一个管“是什么”、一个管“怎么答”：

- `CalendarType`（`IntFlag` 类型位掩码）：一个日期承担哪些角色就是一组 bit。`CALENDAR` 自然日 → `BUSINESS` 工作日 → `TRADING` 交易日，前三位逐级收窄、位序越高收得越紧；`SETTLEMENT` 结算日、`REPORTING` 报告日、`FINANCIAL` 财务日不决定在册与否，只是叠加在其上的业务概念，可与前三位按位组合（例：`CalendarType.TRADING | CalendarType.FINANCIAL` 表示“交易日且为财务日”）。
- `Calendar`（抽象基类，日历本体）：约定一份日历必须回答什么 —— `mask_of`（某天承担什么角色）与 `select`（哪些日子承担这些角色）为抽象方法；`test`（某天是否承担指定角色）与 `latest`（不晚于基准时刻的最近日期）由这两个派生，子类不必各写一遍。数据源可以是静态预计算表、按规则推导或远端接口。
- `MarketCalendar`（`Calendar` 的预计算实现）：升序日期序列 + 逐项对齐的类型掩码。`MarketCalendarRegistry` 按交易所代码注册/取用，注册的是 `Calendar` 而非具体类。

```python
from panshi.data.calendar import CalendarType, MarketCalendar, registry

# days 与 masks 逐项对应, masks 是 CalendarType 的位组合
registry.register("SSE", MarketCalendar(days, masks))

# "上交所截至此刻最近一个交易日且为结算日的日期"
latest = registry.get_calendar("SSE").latest(utc_ts, CalendarType.TRADING | CalendarType.SETTLEMENT)
```

## 目录布局

```
foundations/
├── AGENTS.md            # 智能体作业规范(含 git 提交规范), 改动前先读
├── Cargo.toml           # rust crate 清单(与 go.mod / pyproject.toml 同在根)
├── lib.rs               # crate 入口, 当前只声明 panshi
├── panshi/              # 磐石: 同一棵模块树下放两种语言实现
│   ├── mod.rs           # rust 生产实现(待按 spec 逐项填充)
│   └── data/
│       └── calendar.py  # python spec: 日历契约
├── mpr/                  # 存量代码归集: base/ 与 core/ 为 python, scoring/ 为 Go
│   ├── base/             # 基础设施(配置/文件/日志/网络/交易所适配)
│   ├── core/             # 策略与算法(因子/波浪/期权/VIX)
│   └── scoring/          # 存量 Go 实现, 不在新语义轴线上
└── labs/                 # 实验室: 完整可运行的项目, 与契约层分开
    └── sta/              # 溯源式记账引擎: 无源不入账, 按日期与属地适配当时当地财税规则
```

Rust crate 根就是仓库根：`Cargo.toml` 里 `[lib] path = "lib.rs"`，模块树按同名目录向下展开（`panshi/mod.rs` 与 Python spec 的 `panshi/` 同一棵树），改语义时一次提交能同时覆盖两侧。`Cargo.lock` 按库的惯例不入库。

## 快速开始

```bash
python -c "from panshi.data.calendar import Calendar"
cargo check
```

## 规范

- 编码与提交规范见 [`AGENTS.md`](AGENTS.md)：作业前先看“编码前思考 / 简洁优先 / 精准修改 / 目标驱动执行”四节；
- 提交信息主题模板 `<type>[<language>]:<中文摘要>`，`<language>` 取 `python` / `rust` / `multi`；
- Windows 下提交中文信息一律写 `.git/commit-msg.tmp` 用 `git commit -F` 传，别跟 PowerShell 的转义死磕。

## License

[MIT](LICENSE)
