Table of Contents

Class DeterministicExecutorBase<TState, TAction, TEvent>

Namespace
Virtufin.Base.Execution
Assembly
Virtufin.Base.dll

Pure deterministic executor base: no randomness, no IO, no hidden state. Subclasses define the case-by-case fill logic (what event to emit for each TAction variant) and the initial state.

public abstract class DeterministicExecutorBase<TState, TAction, TEvent> : IExecutor<TState, TAction, TEvent> where TState : IExecutionState where TAction : ITradeAction where TEvent : ITradeEvent<TAction, DateTimeOffset>

Type Parameters

TState
TAction
TEvent
Inheritance
DeterministicExecutorBase<TState, TAction, TEvent>
Implements
IExecutor<TState, TAction, TEvent>
Inherited Members

Remarks

Template method pattern. The base owns the Execute flow and delegates to Process(TState, TAction). Pricing strategy (limit price, mid price, custom feed, etc.) is the subclass's concern — defined inside Process(TState, TAction).

Properties

Initial

The initial state of the executor.

public abstract TState Initial { get; }

Property Value

TState

Methods

ExecuteAsync(TState, TAction)

Execute one TAction, producing the next state and an outcome event.

public Task<(TState NextState, TEvent Event)> ExecuteAsync(TState state, TAction action)

Parameters

state TState

Current executor state.

action TAction

The action to execute.

Returns

Task<(TState NextState, TEvent Event)>

Tuple of (next state, outcome event).

Process(TState, TAction)

Subclass hook: given the current state and an action, produce the next state and the outcome event.

protected abstract (TState NextState, TEvent Event) Process(TState state, TAction action)

Parameters

state TState

Current executor state.

action TAction

The trade action to process.

Returns

(TState NextState, TEvent Event)

Tuple of (next state, outcome event).

Remarks

Implementations typically pattern-match on the concrete TAction ADT (e.g. BuyOrder, SellOrder, CancelOrder) and emit the appropriate TEvent subtype (e.g. FillReceived, OrderCancelled). All pricing decisions live here — the base does not assume a mid-price. Purely synchronous by design (no IO) -- ExecuteAsync(TState, TAction) wraps the result in a completed Task.