Overview
A strategy in Virtufin is the pair of morphisms (decide, execute)
modelled coalgebraically (see the behaviour spec). This devkit provides
the execute bridge: the consumer half of the loop
virtufin-strategy-devkit's
StrategyWorkerBase produces the decide half of.
In plain terms: decide watches the market and its own holdings and
submits orders; execute is the separate, downstream process that
actually places (or simulates) those orders and reports back what
happened. The two are connected by CloudEvents on the pubsub-topics
spec's trading topics, not a function call in the same process --
that's a deliberate architectural choice, not an implementation detail
that could just as well have been a direct call. A strategy worker and
an executor worker can be scaled, deployed, and restarted
independently, and the same executor can serve any number of
strategies that happen to submit orders into the same scenario.
The executor
execute is an IExecutor<TState, TAction, TEvent> (Virtufin.Core):
public interface IExecutor<TState, TAction, TEvent>
where TState : IExecutionState
where TAction : ITradeAction
where TEvent : ITradeEvent<TAction>
{
TState Initial { get; }
Task<(TState NextState, TEvent Event)> ExecuteAsync(TState state, TAction action);
}
TState— the executor's own hidden state (empty for a deterministic simulator, a PRNG seed for a slippage model, connection state for a live venue integration).TAction/TEvent— fixed toRichTradeAction/TradeEventbyExecutorWorkerBase<TState>(see Bridge) -- every executor in this org drives the same trade ADTs, only the state varies.
Virtufin.Base.Execution (in virtufin-dotnet) provides four
implementations: DeterministicExecutorBase (pure, synchronous fills),
SlippageExecutorBase (adds a slippage distribution), LiveExecutorBase
(genuinely async -- routes to a real exchange), and ObserveOnlyExecutor
(a decorator: wraps another executor, records what it produced without
altering the call).
Before wiring a strategy to a live executor (
act), see the strategy devkit's testing guidance: unit-test, backtest, then shadow-trade with anObserveOnlyExecutor-wrapped worker (see virtufin-execution-engines'sShadowExecutor) before ever settingstrategy.world = act. This devkit doesn't certify an executor as safe to trade with real capital -- it only provides the plumbing.