How a robot works

The engine does not execute a program you write; it runs a graph you declare. Market data enters at an adapter, an input turns every tick into a number, a pattern decides when that number means something, a rule turns the decision into a fully specified order, a robot owns the rules and is the thing you start and stop, and an account owns the robots and everything they touch.

Two properties hold along the whole chain

Each stage is declared under a unique label and is referred to by that label from the stage above — a pattern names its inputs, a rule names its pattern, a robot names its rules — so the graph is assembled bottom-up out of names rather than out of pointers.

And declaring is not running: nothing in the graph touches data until the robot is started.

Market data arrives at an adapter

A market adapter is the single place where the outside world ends and the engine begins. It is a named, typed channel owned by the account: named, because inputs refer to it by that name; typed, because the record it accepts is fixed when it is created and validated on every push.

Adapter typeRecord pushed
OHLCVcandles
Bid/asktop-of-book quotes
Tradeprints
Executedtrades that happened elsewhere
Bookorder-book messages

An input processes every tick

An input is the entry node of the graph and the one place where your own ideas live. It is a named, duration-stamped cache built over a set of contracts on one adapter: the input hands each arriving tick to your data processor, and whatever the processor stores becomes the series that patterns later observe. The processor may push a timestamped value into the storage, and it returns a readiness flag.

The engine never inspects the callable — it holds a function pointer of a fixed signature and a pointer it does not interpret, and it calls them. The builders are add_input_ohlcv, add_input_bidask, add_input_trade, add_input_executed, add_input_book and add_input_book_imbalance.

A pattern watches inputs and fires

A pattern is the decision node. It observes one or more inputs by label and emits a signal whenever its condition holds. A pattern produces nothing tradeable by itself: a signal becomes an order only through a rule that names the pattern.

Six kinds cover the vocabulary of a condition, each demanding an exact number of observed inputs. Threshold, peak and timestamp take one input; comparison and crossover take two; formula takes any number and hands each update to your callback.

A rule turns a firing into an order

A rule is the bridge between observation and action. Everything the resulting order will carry — the sides, the quantity, the price form, slippage, fee, time-in-force and priority — is fixed when the rule is built, and none of those ten values has a library-supplied default. The firing supplies only the moment.

The market rule is an entry, an exit or a rebalance bound to a pattern. The risk rule is the stop-loss and take-profit family and takes no pattern at all — it watches the position. Multileg, bracket and OCO emit several legs as one atomic transaction; cancel, replace and modify amend an order already in flight. A rule decides what to send, not what is permitted: risk policies gate orders on position value, position quantity and the trading window.

A robot owns a set of rules

A robot is declared over rules that already exist and forwards every instruction they emit under its own label, so results can be read back per robot on an account running many at once. Since a rule names its pattern and a pattern names its inputs, adding a robot transitively takes in a whole dependency component whose leaves are inputs. The robot is the unit you start and stop, and the unit the licence counts.

An account owns the robots

The account is the root of every run. It is created first, with no default supplied for its label, storage regime, currency or core id, and it owns the contracts, the adapters, the single execution, the portfolio and the blotter. The execution is the account's outbound edge: the built-in Simulator fills orders as ticks arrive, while a custom execution hands each order to your callback. Swapping one for the other is the whole distance between a backtest and live trading.

The declaration order follows the dependency order

  1. Create the account, then declare its contracts.
  2. Create the market adapters the data will arrive on.
  3. Create the execution, simulated or custom.
  4. Declare the inputs, naming their adapter and contracts.
  5. Declare the patterns over the input labels.
  6. Declare the rules over the pattern labels, and the risk policies.
  7. Declare the robot over the rule labels.
  8. Start the robot, then push data.

What comes back

Fills return along the same chain in the opposite direction. Each one moves the portfolio, and each is journaled by the blotter as a retained trade carrying the rule and robot labels and the exposure captured at the moment of the trade. Beyond the summary lies the ex-post layer, which buckets each robot's trades over a time step and scores them.

Nothing above the input knows what your processor computed, and nothing below the rule knows why it was asked to trade — which is what lets you replace either end without disturbing the other.

Version 5.0