Robot examples
The examples are ordered as a course, and every one of them is the same twelve declarations in the same order: what differs between a moving-average crossover and a book-imbalance market maker is the body of one callable and the parameters on the rules. Each example is a directory holding a C++ and a Python version of the same strategy.
Hello world
Brings a robot up from nothing: the process-wide configuration, the full assembly, a parameter sweep, several feeds, the saved recipe, and the swap that takes it live.
01 — Initial parameters
No robot — process-wide configuration only; each account captures the data folder at construction.
Sets the data folder, the log folder and the log level before the first account exists. An account resolves its data folder when it is built, so the example builds one account, switches the folder, builds a second, and each blotter file sits in the folder configured at its own construction time.
02 — MACD
Input: MACD of the close → Patterns: thresholds against zero → Rules: market entry and exit.
The Input computes a MACD, the distance between a twelve-day and a twenty-six-day exponential average of the close, and returns readiness only once the slow average has seen enough days. Threshold Patterns compare that distance against zero, and the Rules bound to them enter and leave.
03 — Grid search
One robot built four times by the grid runner — a fresh account per lookback, the same history.
The same robot built four times, over lookbacks of 10, 20, 50 and 100 days against a 200-day trend. The grid runner takes a builder callback that assembles a fresh account for every parameter value and feeds it the same history, and the independent grid points run side by side on a pool of worker threads.
04 — Multiple contracts
Inputs: average AAPL close, average BTC mid → Patterns: threshold and peak → Rules: market entry and limit exit on WTI.
Three feeds of three different shapes on three adapters: daily AAPL bars, BTC/USDT quotes and WTI trade prints. Two Inputs average the Apple close and the Bitcoin mid, a threshold Pattern and a peak Pattern watch them, and the Rules trade a third contract, WTI, which no Input watches at all.
05 — Multiple adapters
Inputs: 50-day and 200-day AAPL averages → Pattern: crossover → Rules: entry and exit; BTC/USDT is subscribed for marking only.
One account, two market-data adapters: daily bars for the equity and a quote stream for the crypto pair. AAPL is traded off the golden cross of its fifty-day and two-hundred-day average Inputs, while BTC/USDT carries no Input and no Rule and is subscribed to the quote adapter only so the portfolio can mark it.
06 — Save / Load — Research → Production
One graph, two processes: Python saves the recipe, C++ loads it, binds each Input to a fresh adapter and starts.
The Python leg registers its two processors under keys, builds a WTI crossover from Inputs declared by those keys, runs the backtest and saves the recipe: contracts, inputs, patterns, rules and the robot travel, adapters and execution do not. The C++ leg registers the same processor keys, loads the robot, binds each restored Input to today's adapter, and starts.
07 — Live trading
Input: traded volume → Pattern: threshold → Rule: market entry; the execution is swapped from the Simulator to a broker callback.
A backtested robot goes live by swapping only its two ends: the IN end is an ordinary market adapter that a live feed pushes into, the OUT end is a custom execution whose transmit callback receives every order the engine emits and reports fills back. The strategy body is trivial on purpose — any trade print carrying volume is a buy signal and the order size is that volume — because the subject is the seam.
Robots
Builds strategies with that assembly, changing the code inside one callable and the parameters on the rules and nothing else.
08 — Gradient-boosted model
Input: model forecast from mid, spread and quote imbalance → Patterns: thresholds at zero → Rules: market entry and exit.
The MACD robot with the processor replaced. A gradient-boosted model trained before the run lives inside a bid/ask Input that derives mid price, spread and quote imbalance from every tick and pushes the model's forecast as the Input's value, and two thresholds at zero put the robot long while the forecast is positive and flat once it turns.
09 — Rebalance
Patterns: two timestamps → Rules: one market entry and one rebalance that adds to the open position.
Two timestamp Patterns drive an entry Rule and a rebalance Rule: the entry Pattern fires once, the rebalance Pattern rearms one second after firing and fires twice. The rebalance maintains an existing position instead of opening or closing one — it chains an adjustment order onto the open position, additively, and does not bring the position to a target size.
10 — Market maker
Inputs: two book feeds splitting client flow → Patterns: four formulas reading the live position → Rules: four orders sized from the signal.
Two book Inputs split client order flow — one keeps the client sells the maker buys against, the other the client buys it sells against — and four formula Patterns whose closures read the live position through get_position_state decide which side to quote: below the upper inventory band the maker quotes both sides, at the band it stops adding and trades only the side that unwinds, until the inventory is back to zero. The four Rules use a from-signal quantity, so every order the maker sends is exactly the size of the client order it absorbs.
11 — Market maker with amendments
Input: recorded prints → Patterns: outsized trade, same-side run, quiet gap → Rules: cancel, replace and modify on the one resting quote.
One measurement pass over each recorded print produces the three facts the maker reacts to, each of them a Pattern: an outsized trade relative to the running average size, a third trade in a row on one side, and a silence longer than ten seconds. One quote rests at a time and one amendment Rule acts on it per fact — a cancel pulls it, a replace steps it away and shrinks it, a modify restores it to full size.
12 — Voting group
Input: signed sum of three robots' fills on an executed-trade adapter → Patterns: two thresholds → Rules: entry and exit for a fourth robot.
Four robots on one account: three vote by a seeded coin flip on every WTI bar, and the fourth trades their behaviour. The voter's Input over an executed-trade adapter keeps the signed sum of the traders' fills, and two thresholds over that net put the voter long while the group is net long and flat when the net returns to zero.
13 — Order-book imbalance
Input: built-in book imbalance over an L3 book → Patterns: thresholds at +0.2 and −0.2 → Rules: entry and exit on each side.
The account owns a real L3 book replayed from recorded quote snapshots, and the built-in imbalance Input reads it: whose resting size is bigger, the buyers' or the sellers', +1 when only bids rest and -1 when only offers do. Two thresholds at plus and minus a fifth drive the robot both ways, with four Rules covering entry and exit on each side.
14 — The same signal on L1, L2 and L3
The graph of 13 unchanged; the only line that differs is the book's construction — L1, L2 or L3.
The imbalance robot of the previous example, run unchanged on all three book depths a venue may publish: the only line that differs between the three variants is the book's construction as L1, L2 or L3. The feed adds at each step exactly the size that drags the book onto the next target imbalance, so the sequence of signals is known before the run starts and the three variants can be compared field by field.
15 — Cross-venue book arbitrage
Inputs: imbalance on an L2 book and on an L3 book → Patterns: formulas comparing the two → Rules: entry and exit in a third contract.
The same asset is quoted on two venues: an L2 book tracks the first, an L3 book tracks the second, and each feeds its own imbalance Input. Each formula Pattern remembers the last value seen from each Input, refuses to answer until both books have spoken, and fires when the two disagree by more than 0.3; the Rules take the position in a third, liquid contract that neither book observes.
16 — Multileg butterfly
Patterns: two timestamps → Rule: one multileg transaction of three option legs, filled together or not at all.
Two timestamp Patterns supply the two moments, and the Rules submit a SPY call butterfly — long one 440 call, short two 450 calls, long one 460 call — as a single multileg transaction, each leg a descriptor carrying its own contract, side, quantity, limit price and transaction kind. No leg fills until every leg's market has reached its price, and the exit reverses every leg in one all-or-nothing transaction.
17 — Multileg strangle hedge
Patterns: two timestamps → Rule: one multileg transaction of a future and three option legs.
The same atomic mechanics, now mixing instrument types inside one transaction: a long CLF26 future carries the directional view, two long out-of-the-money puts at 45 and 44 insure it against a fall, and a far out-of-the-money 60 call buys the upside back. Four legs, one hedged position, filled together or not at all, so the hedge never exists half built.
Risk
Adds risk control, in the form the engine computes inside itself and in the form that rests at the venue.
18 — Internal risk calculation
Risk policies gate the order before it is sent; risk rules watch the position and fire on the unrealized-P&L ratio. Neither takes a Pattern.
Risk the engine computes inside itself, measured against a baseline run of the same strategy. Risk policies are pre-trade gates tested against the position an order would leave you holding — five thousand on the market value of the whole book, a hundred shares on one name, a repeating window of local time in a named zone — while stop-loss and take-profit rules, each in a fixed and a trailing variant, watch the position tick by tick.
19 — Fixed bracket
Pattern: three-over-ten crossover → Rule: one bracket — an entry leg plus a fixed stop and a fixed target resting at the venue.
The Pattern is a WTI three-over-ten crossover and one bracket Rule submits the entry leg together with a venue risk specification holding a fixed stop-loss leg and a fixed take-profit leg, both resting at the venue good-till-cancelled. The entry is a 580-lot market order guarded two percent below the fill and three percent above it, and whichever side the market touches first closes the position and cancels its sibling.
20 — Trailing bracket
Pattern: fifty-over-two-hundred crossover → Rule: one bracket with a trailing stop and a fixed target.
The fixed bracket with one leg changed: a fifty-over-two-hundred golden cross on AAPL daily bars, protected by a five percent trailing stop and a fixed ten percent target. The kind field of the risk leg selects the behaviour — a fixed stop is priced once off the entry, a trailing stop is re-priced off the best price the position has seen.
21 — OCO and amendments
Patterns: timestamps → Rules: cancel, modify and replace on a resting limit order, and one OCO pair on an open position.
Four scenarios, each on its own rig and each fired by a timestamp Pattern so the moment of the action is exact. Three act on a limit entry already resting at the venue — a cancel Rule withdraws it and releases its reservation, a modify Rule shrinks it in place from ten to four, a replace Rule pulls it and posts a fresh one at a different price and size — and the fourth arms a stop and a target on an open position as one pair.
Statistics
Reads the statistics back: the blotter of retained fills, the per-period scores, and a model that ranks candidates on them.
22 — Transaction and robot statistics
One crossover robot; the statistics are read back off the account afterwards, not declared in the graph.
One WTI crossover run, read back at two levels. The transaction level is the blotter: one row per retained fill, with symbol, price, quantity, booked profit and loss and side; the duration level cuts the same run into day buckets and scores each one, and the example asks for the parameter count and the bucket count, then saves the scores and loads them back.
23 — Candidate selection
Five robots from the grid runner, each scored through ex_post; a booster ranks the score rows and picks one.
Five candidates differing only in their fast lookback are swept with the grid runner, and each builder opens an ex_post object on its own finished account and extracts the score matrix. The feature vector is the last bucket's row, a booster is trained on every candidate but the one held back, and the pick is the highest predicted profit rather than the highest realized one.
Everything else
Collects the facilities that surround a running engine: cores, currency, storage, manual booking, bulk controls and the data toolkit.
24 — Core affinity
The same graph twice — once unpinned, once with the core id set on each Input and Pattern.
Every worker in the export surface takes a core identifier as its trailing argument — the account, each execution, each Input and each Pattern — where a non-negative value pins that worker to the named core and -1 leaves the choice to the operating system. One AAPL trend follower runs twice, unpinned and with its two Inputs and two Patterns nailed to two cores, and the two results agree.
25 — Multicurrency
Patterns: two timestamps → Rules: one entry and one exit; the only variable is the account's currency.
An account denominated in euro: the currency is the third argument of account construction, and prices, cash, booked profit and loss, the summary and the portfolio mark all inherit it. The strategy is a single round trip driven by two timestamp Patterns, ten units bought at 100 and sold at 110, because the subject is the unit and not the edge; the engine never converts between currencies. Note what this example is: the engine is validated on a single currency, the US dollar — the euro value and cross-currency portfolios are a feature in the process of shipping, so the interface here runs ahead of its cross-currency arithmetic.
26 — Storage regimes
The same crossover graph twice; the only variable is the account's storage regime.
The same WTI crossover backtest run twice, with the blotter in memory and with the blotter on disk in the configured data folder. The regime is the second argument of account construction and decides where the statistics live, never what the strategy does, and both runs agree on net profit and trade count.
27 — Manual booking
No graph at all — a contract registered straight with the portfolio, and fills booked by hand.
The portfolio without an adapter and without an execution: a contract is registered directly with the portfolio and fills the engine never placed are booked by hand. The plain mode runs the average-cost engine and computes the profit and loss while the caller only reports what traded; the exposure-parameterized mode prices the fill against exposure snapshots the caller supplies and leaves the live position exactly as it was.
28 — Bulk actions
Rules: one market entry and one resting limit exit, then the bulk actions addressed by robot label.
One rig — an entry that fills at the market and an exit that rests as a limit far above it — acted on by robot label, so there is always both a position and a resting order. Cancelling the resting orders and flattening the position cleans the desk without stopping the robot; halting plus a cancel keeps the position open; halting plus a market close leaves a flat desk; the composite of halt, cancel and flatten is the kill switch.
29 — Timeserie tools
No robot — the CSV reader, the slicing transforms and the writer run as one pipeline.
A CSV of daily Apple closes is read with an explicit date format, separator and header setting, and the index and one named column come back as a timestamp series and a value series. The series is cut to calendar year 2010 by nanosecond bounds taken as midnight UTC, written back out with formatted timestamps, read again, and windowed with head and tail, which hand back a begin-and-length view rather than a copy.