架构与设计取舍

本页说明库是如何组织的,以及公共接口为什么是现在这个样子。它是参考的“为什么”伴侣,参考回答的是“是什么”。

分层

data            dataframe, calendar, UTC timestamps, frequency helpers
metrics         returns, ratios, drawdowns, rolling windows, statistics
domain          risk, portfolio, factor, attribution, optimization
presentation    report documents, HTML/XLSX/PDF/Plotly/Bokeh/axes renderers
runtime         operation catalog, sessions, serialization, extensions

每一层可以使用它上面的层,绝不使用下面的层:指标不知道报表文档的存在,渲染器也从不重算统计量。这就是报表模型携带数值而不是帧的原因 —— 渲染不能改变数字,只能呈现它。

所有权

一条规则解释了大部分 API 形状:输入在边界处复制,结果拥有自己的数据。

  • portfolio_inputs、analysis_context 与 rolling_engine 以按值方式接收帧并保存自己的副本,因此调用方修改源帧不会改变已经产出的结果。

  • 返回 dataframe 的函数返回新帧。返回 span 或 std::string_view 的访问器是视图,只在其所有者存活期间有效。

  • materialize() 每次调用都返回新帧,这正是修改其结果不会破坏下一次调用的原因。

这里的取舍是分配与可预测性。对本库面向的日频与月频面板规模,可预测的所有权值得这份复制;基准框架的存在就是为了在更大规模上让这个判断保持诚实。

确定性

任何可能被比较、存储或重放的东西都被归约为摘要:

  • 运行时序列化给每个字段加长度前缀并标注类型,因此两份不同载荷不会因为分隔符或 bool/1 的歧义而碰撞。

  • 因子 fingerprint 哈希的是输入;报表摘要覆盖文档,因此渲染同一文档的两个后端在构造上一致。

  • 字节重要的场合,浮点值按 IEEE-754 位模式序列化,从而保留 NaN 载荷与带符号零。

随机方法接受显式种子。种子只在本库内复现一条流;只有文档写明参考映射的函数才承诺与 NumPy 相同的数值。

错误与退化结果

库区分三种结果,而这种区分是契约的一部分,不是实现细节:

结果

含义

例子

异常(input_error、factor_data_error)

请求在结构上是错的

列缺失、索引重复、内嵌 NUL

NaN

请求本身合法,但统计量无定义

观测太少、零偏差、无回撤

状态字段

拟合或校验确实运行并给出自己的结论

risk_estimate_status、walk_forward_status、risk_backtest_status

状态字段存在的意义,正是让调用方不必从一个看起来合理的数字里推断失败。

并发

自由函数是无状态的:相同参数产生相同结果,两个线程可以在各自帧上并发调用。有状态对象是显式的:

  • analysis_context 会缓存结果,因此单个实例在构造上就是单线程的。

  • analysis_session 拥有自己的输入与输出,并在 close() 之后拒绝调用。

  • rolling_engine 拥有副本,一次只宜在一个线程中使用。

没有隐藏的线程池、没有全局缓存、没有后台工作:一次调用在返回之前就完成了它承诺的事。

扩展点

扩展点

契约

数据提供者

返回帧的可调用对象;校验与摘要仍留在库内

报表后端

渲染器消费 report_document 并返回拥有的 artifact bundle

扩展

原生快照/hook ABI:hook 携带事件与优先级,并列时按 fingerprint 决定

操作

描述符列出输入与输出;执行返回带类型的 runtime_value

可选接口保持可选:ImPlot 适配器及其 GUI 依赖永远不会出现在核心 fincore::fincore 路径上。

刻意不提供的东西

  • 不承诺 Python 对象兼容。 fincore::dataframe 是自己的类型;parity 工作关注数值,而不是对象身份。

  • 没有隐式数据访问。 不会在你不知情时下载价格序列或读文件;I/O 是调用方的决定。

  • 不做单位换算。 收益是小数分数,年化是参数,权重沿用调用处的含义。

  • 不做静默修复。 重复索引会被拒绝而不是去重;缺失观测是 NaN,不是 0。

文档如何映射这一点

站点遵循同样的划分:教程与配方集展示用法,指南解释行为,参考由头文件生成,本页解释结构。发布状态存放在仓库中,从不在首页上断言。