When Indicators Are Not Functions: Defining Quant Operators in Rust

Published: (January 13, 2026 at 10:54 PM EST)
2 min read
Source: Dev.to

Source: Dev.to

Where the problem comes from

Most technical indicators today are modeled as functions: they take an array and return a value or another array.
This breaks down once indicators need:

  • Persistent state (rolling, EMA)
  • Sensitivity to time ordering
  • Consistent semantics across batch and streaming
  • Composition and scheduling

A pure‑function model cannot express these constraints. In Rust, the limitation becomes explicit:

  • Ownership forces state responsibility to be explicit
  • Implicit globals are unacceptable
  • Performance requires clear execution boundaries

Core Definition: Operator

In this document, an Operator is defined as:

A schedulable execution unit that processes input data under explicit execution semantics.

The term “function” is intentionally avoided.

An operator must:

  • Have explicit input/output semantics
  • Be invoked as a semantic execution unit
  • Own its state boundaries explicitly
  • Fail in a structured, observable way

An operator must never:

  • Make decisions about scheduling
  • Manage system resources
  • Perform system‑level recovery

Execution as a semantic unit

An Execution is defined as:

An indivisible invocation of an operator under a given input and execution context.

Key properties:

  • Execution is semantic, not syntactic
  • Operators may execute multiple times
  • Relationships between executions are out of scope here

Failure is not panic

Operator failure is not a panic. It is a first‑class execution result that may propagate outward. Whether a failure halts the system is the responsibility of the caller.

Minimal Reference Implementation (v0.1)

The following code exists to prove that the above definitions are implementable in Rust.

pub trait Operator {
    type Error;

    fn execute(&mut self, input: Input) -> Result;
}

Notes:

  • &mut self explicitly allows internal state.
  • No time, batch, or scheduling semantics are included yet.
  • The implementation is intentionally minimal.

A trivial stateless example:

pub struct Sum;

impl Operator for Sum {
    type Error = ();

    fn execute(&mut self, input: &[f64]) -> Result {
        Ok(input.iter().sum())
    }
}

Its purpose is conceptual, not functional.

Non‑goals

This article intentionally does not define:

  • State models
  • Time semantics
  • Batch consistency
  • DataFrame or Polars integration

Engineering repository:
Contact:

Back to Blog

Related posts

Read more »

Embedding JVM in Rust

Java ↔ Rust Interop with the jni Crate !Ivan Yurchenkohttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fd...