文献声明
本文不是 Rust 教程,也不是量化策略教程。
本文记录的是:在 Rust 语境下,量化算子应如何被工程化与定义。
文中所有代码仅作为工程定义的参考实现存在,其目的在于验证模型是否成立,而非作为教学成果本身。
作者
yuer
EDCA OS 作者
可控 AI 标准提出者
工程仓库:https://github.com/yuer-dsl
联系邮箱:lipxtk@gmail.com
1. 问题从哪里来
在大多数实现中,技术指标通常被建模为"函数":
-
输入一个数组
-
输出一个数组或一个数值
这种方式在早期是可行的,但在以下工程场景中会系统性失效:
-
指标需要维护跨调用状态(如 rolling / EMA)
-
指标需要对时间顺序敏感
-
指标需要在逐条与批量计算中保持一致语义
-
指标需要被组合、调度、复用
函数模型无法表达这些约束。
在 Rust 中,这个问题被进一步放大:
-
所有权与生命周期迫使我们必须明确"谁持有状态"
-
隐式共享状态几乎不可接受
-
高性能要求需要清晰的执行边界
继续把指标当函数,本质上是一种语义缺失。
2. 核心定义:什么是算子(Operator)
在本文中,算子(Operator) 被定义为:
一个在明确执行语义下,对输入数据进行处理的可调度执行单元。
刻意不使用"函数"一词,是因为函数模型无法覆盖算子的工程责任。
一个算子必须满足:
-
拥有明确的输入与输出语义
-
在一次"执行"中被调用,而非任意时间
-
对自身状态拥有明确责任边界
-
能够失败,并以结构化方式暴露失败
一个算子永远不负责:
-
决策(是否交易)
-
调度(何时执行)
-
资源管理(线程、内存池)
-
系统级错误恢复
3. 执行(Execution)的最小语义
执行(Execution) 指的是:
在给定输入与执行上下文下,对算子进行的一次不可分割的调用。
关键点是:
-
执行是语义单位,而不是函数调用次数
-
同一个算子可以被多次执行
-
执行之间的关系,本文不讨论
4. 失败不是 panic
算子失败不是 panic,而是:
一次可观察、可传播的执行结果。
最小约束是:
-
失败必须显式表达
-
失败不等同于系统崩溃
-
是否中断系统,由外部决定
5. 最小参考实现(v0.1)
下面的代码不是"教程示例",而是用于验证上述定义在 Rust 中可以成立。
pub trait Operator<Input, Output> {
type Error;
fn execute(&mut self, input: Input) -> Result<Output, Self::Error>;
}
说明:
-
&mut self明确算子可能持有状态 -
不引入时间、不引入批处理、不涉及调度
-
这是一个刻意"过小"的接口
一个最小无状态算子示例:
pub struct Sum;
impl Operator<&[f64], f64> for Sum {
type Error = ();
fn execute(&mut self, input: &[f64]) -> Result<f64, Self::Error> {
Ok(input.iter().sum())
}
}
它的意义不在功能,而在于:
算子 ≠ 函数调用。