Introduction
The Virtufin Lib (virtufin-dotnet) is the .NET 10 foundational layer for the Virtufin trading platform. It provides the data model, type system, serialization format, and reactive primitives that the higher-level services (WorkManager, WebSocketManager, API Gateway) build on.
What this library is
- A data model for trading workflows: entities, attributes, values, positions, scenarios, transactions, contracts.
- A type system:
Variant(sealed discriminated union),DecimalAmount(arbitrary-precision decimal with explicit precision),Cash(currency-aware money),Currency(12 ISO codes). - A serialization format: FlatBuffers schema for
Variantso the same value can round-trip across C#, Python, and TypeScript SDKs. - A reactive layer:
IObservable<T>adapters for NATS pub/sub, WebSocket frames, and Valkey keyspaces, with auto-reconnect.
What this library is not
- Not a gRPC service. The transport is in
virtufin-api,virtufin-workmanager,virtufin-websocketmanager. - Not a strategy engine. Strategies are external workers that call into this library.
- Not a backtesting engine. The execution algebra is here (the
IExecutor<TState, TAction, TEvent>template), but actual backtest runners are out of scope. - Not an exchange connector. The
LiveExecutorBasein this library is a base class; subclasses route to a real exchange.
Who uses this library
| Consumer | Use |
|---|---|
virtufin-workmanager |
Worker engine — uses Variant for code payloads, IExecutor for the execution algebra |
virtufin-websocketmanager |
WebSocket proxy — uses Variant for message bodies, FlatBuffers for serialization |
virtufin-api |
gRPC gateway — uses Variant for state values, FlatBuffers for state payloads |
| External workers | Submit Variant values via gRPC; the lib defines the wire format |
Key concepts
The EAV model
Every business entity (order, position, scenario) is an IEntity<V, I> with a typed identifier I. The entity has a name, attributes, and a value. Attributes are looked up by name; values are produced by pluggable IValueProvider<V, I> instances. See Core EAV.
The Variant type
A Variant is exactly one of: None, Bool, Int32, String, Dictionary, or nested array. Implicit conversions exist for all C# primitives (int, string, bool, long, double, decimal). The FlatBuffers schema lets a value produced in C# be deserialized in Python or TypeScript with the same shape. See Variant Type.
The DecimalAmount type
DecimalAmount is a struct of (long Whole, int Fraction, byte N) where N is the precision (number of fractional digits). Two DecimalAmount values with different N are not equal — precision is part of the value. All arithmetic uses checked semantics and throws OverflowException on overflow. Cash wraps a DecimalAmount plus a Currency and rejects mismatched-currency operations. See DecimalAmount.
The execution algebra
IExecutor<TState, TAction, TEvent> is the morphism A → IO E from the trading domain spec — given a current state and an action, produce the next state and an outcome event. Three base classes capture distinct execution strategies: DeterministicExecutorBase<TState, TAction, TEvent> (no randomness), SlippageExecutorBase<TState, TAction, TEvent> (random slippage, distribution-agnostic), LiveExecutorBase<TState, TAction, TEvent> (exchange-routing subclass). All three are abstract — subclasses define the case-by-case fill logic. ObserveOnlyExecutor<TState, TAction, TEvent> decorates any other executor and records what would have happened (for SHADOW_* scenarios).
Conventions
- C# 14 preview features (e.g.,
extensionsyntax) are used where they reduce noise. - Nullable reference types are enabled — respect the annotations.
- Generic type parameters use single uppercase letters:
Vfor value types,Ifor identifier types,Afor attribute types. Iprefix for interfaces, PascalCase for classes,_camelCasefor private fields,UPPER_SNAKE_CASEfor constants.sealedon classes that aren't designed for inheritance (e.g.,Variant).