Core Interface
Every operator in ClyptQ implements a single method — the equivalent of a CPU instruction in the Von Neumann-inspired architecture. Stateless, deterministic, and indifferent to where its data originates:- Inputs: Always
Dict[str, TaggedArray]— buffered by the graph’s RollingBuffers - Output: Always TaggedArray — 4 fields (value, exists, valid, updated)
- Stateless: No mutable state between ticks. The graph manages all state.
13 Operator Roles
Building Custom Operators
ClyptQ’s operator system is designed for extension. Inherit fromBaseOperator and implement compute() to create any custom logic:
Basic Custom Operator
Register and Use
Custom Filter
Custom Metric
compute() — NumPy, SciPy, PyTorch, sklearn, custom algorithms. The operator protocol only requires TaggedArray in, TaggedArray out.
Self-Referencing Operators
Some operators need their own previous output as input. The classic example is EMA:How It Works
- Topological sort excludes self-edges — The graph’s Kahn’s algorithm ignores self-references when computing execution order, preventing false cycle detection
- Buffer seeding — On the first tick, the self-reference buffer contains the initial/warmup value (typically
valid=False) - Each tick — After compute, the output is written to the self-reference buffer for the next tick
Self-Reference Use Cases
Iterative Computation Within compute()
Operators are called once per tick, but thecompute() method can contain arbitrary Python logic including loops. For algorithms that require iteration (numerical solvers, differential equations, convergence-based methods), you implement the full iteration within a single compute() call:
Differential Equation Solvers
Key Principle
You don’t need incremental implementation for iterative algorithms. A singlecompute() call can run for loops, while loops, convergence checks — any Python control flow. The graph calls compute() once per tick, but what happens inside is unrestricted.
This means:
- Newton-Raphson for portfolio optimization — iterate to convergence within
compute() - Runge-Kutta for ODE solvers — full integration step per tick
- Monte Carlo simulation — generate thousands of paths within
compute() - Gradient descent for online learning — run N steps per tick
- ADMM / convex optimization — full solver per tick
Execution Responsibility Separation
Following the Von Neumann principle of separating computation from state, ClyptQ separates execution into three memoryless components:Memoryless Execution
The executor is stateless — it receives an intention, computes a delta from current STATE, executes the order, updates STATE, and forgets everything. All metrics, tracking, and adaptation are done by operators in the graph, not by the executor.FIELD & STATE
How FIELD (market data) and STATE (portfolio state) flow through the graph and enable the memoryless execution pattern
Feedback Loop Control
Because STATE flows back into the graph as input, strategies can create closed-loop feedback:- Drawdown-based de-leveraging: Reduce position size when drawdown exceeds threshold
- Equity curve trading: Pause trading during losing streaks
- Adaptive position sizing: Scale based on realized equity volatility
- Kelly criterion: Dynamically size based on accumulated win rate and payoff ratio
- Regime switching: Change strategy behavior based on tracked portfolio metrics
ML and DL Integration
Online Learning (Per-Tick)
For models that update incrementally, the tick-by-tick architecture is natural:Batch Data Collection for Offline Training
ClyptQ processes data tick-by-tick, so standard batch DL training doesn’t work directly in the graph. However, you can use a collector node to accumulate all data, then train after the iteration completes:driver.run() completes, all data is available for batch processing:
Pre-Trained Model Inference (Recommended for DL)
Train externally, load model, run inference per tick:Reinforcement Learning
RL agents fit naturally — each tick is an environment step:Ephemeral Operators
Operators markedephemeral = True make external API calls (LLM, web search) and cannot reproduce the same output for the same historical input:
- Skip backtest validation
- Only run in paper or live mode
- Skip warmup (return neutral values)
- Should be gated with Control operators for cost control
ComputeContext
Thecontext parameter provides execution metadata:
Performance Considerations
Tips:
- Use NumPy vectorized operations (avoid Python loops over symbols)
- Minimize lookback — request only what the algorithm needs
- Cache expensive intermediate results in
self(e.g., covariance matrices) - For ML inference, batch symbols together in one forward pass
Relationship to Other Concepts
- TaggedArray: All inputs and outputs
- StatefulGraph: Manages operator execution and state
- Lookback Buffers: How operators receive historical data
- FIELD & STATE: Market data and portfolio state inputs
- Operator Reference: Complete catalog of built-in operators

