Skip to content

Virtual Dealer

Virtual Dealer is an in-process automatic policy engine. It evaluates routed OPEN, CLOSE, and PARTIAL_CLOSE operations without creating a manual dealer request or starting a separate service process.

trade operation
    → route match
    → VIRTUAL_DEALER(policy_id)
        ├─ ACCEPT    → continue Core execution
        ├─ REJECT    → reject the operation
        └─ NEXT_STEP → evaluate the next route step

An accepted operation resumes the normal Core path with routing bypassed, preventing the same request from being routed twice. NEXT_STEP can lead to another Virtual Dealer policy, a manual dealer pool, INTERNAL, or REJECT.

Policy fields

Field Type Default Meaning
id int assigned Immutable policy identifier
name string required Unique administrative name
description string empty Administrative description
enabled bool true Whether the policy can accept operations
volume_min int 0 Inclusive minimum volume in server integer volume units
volume_max int 0 Inclusive maximum; 0 disables the upper bound
max_spread_points int 0 Maximum current symbol spread; 0 disables the check
max_price_deviation_points int 0 Maximum deviation from the requested price; 0 disables the check
failure_action string NEXT_STEP Decision when an enabled rule fails: NEXT_STEP or REJECT
created_at, updated_at int64 assigned Unix timestamps

The policy returns NEXT_STEP when it is missing or disabled. An enabled policy applies the volume, quote, spread, and price-deviation checks. When every active check passes, it returns ACCEPT.

For OPEN, the executable price is Ask for BUY and Bid for SELL. For CLOSE and PARTIAL_CLOSE, it is Bid for BUY and Ask for SELL. A price-deviation check is applied only when the request contains a positive reference price.

Failure reasons

Virtual Dealer decisions can contain the following reasons:

  • POLICY_ACCEPTED
  • POLICY_NOT_FOUND
  • POLICY_DISABLED
  • VOLUME_OUT_OF_RANGE
  • SYMBOL_NOT_FOUND
  • QUOTE_UNAVAILABLE
  • MAX_SPREAD_EXCEEDED
  • MAX_PRICE_DEVIATION_EXCEEDED

Persistence and runtime state

Policies are persisted in bases/virtual_dealer.db. Runtime reads use an immutable RAM snapshot. Successful mutations publish a new snapshot immediately and enqueue serialized SQLite persistence through the module's database worker.

A policy referenced by a route cannot be deleted. The server returns HTTP 409 with RET_CFG_NOT_EMPTY until the referencing route is changed or deleted.

Routing configuration

Create the policy before adding a route that references it:

{
  "position": 0,
  "target": "VIRTUAL_DEALER",
  "virtual_dealer_policy_id": 1,
  "timeout_ms": 1000
}

Route create and update operations verify that virtual_dealer_policy_id exists. A non-final Virtual Dealer step requires a positive timeout_ms under the routing validation contract. Policy evaluation in the current version is synchronous; delayed execution and requotes are not implemented.

Audit event

Every decision is published through the internal EventBus with the name virtual_dealer.decision. The payload contains the routing snapshot version, route and step identifiers, policy id, login, order, symbol, operation, decision, and reason. This is an internal audit event; it is not a manual dealer queue event.