Mount binaries
Two headless mounts that live in vike-run behind their own cargo features — a Polymarket paper maker on a live feed, and a real IBKR mount that is not paper.
vike-run carries two runnable mounts, each behind a required-features gate, so a default build
of the crate contains neither. They look alike from the outside and are opposite in the one way
that matters: one of them cannot place a real order, and the other exists to.
polymarket_maker_paper — a live feed, a paper book
Behind the polymarket feature. crates/vike-run/src/bin/polymarket_maker_paper.rs mounts the
Avellaneda–Stoikov maker on a real Polymarket market: the strategy quotes and trades off the
live tick feed, and every fill lands in the paper exchange. No credentials, no signing, no money.
It picks a market three ways — --auto (universe selection: the most-liquid tradeable market, no
name needed, with --min-liquidity as the floor), --query by name through the Gamma catalog, or
--token-id for an exact outcome token. The market's end_date becomes the A-S resolution_ts.
It then builds a vike_mm::SpreadMaker and mounts it on the production live core through
vike_core::spawn_core, with the paper exchange as the ExecutionClient and the real
vike_polymarket::Feeds as the tick source. The module header states the property that makes this
worth having: it is an identical mount to the offline scripted test, and only the feed differs.
That is enforced by sharing one builder. vike_run::build_paper_maker_core puts
PaperExecutionClient behind the ExecutionClient seam and the maker behind a StrategyMount on
spawn_core, and it is deliberately feature-free — no venue code — so the live binary and the
offline test use it verbatim, differing only in what feeds the returned handle. Its default options
are documented as today's plain-path values: RiskLimits::new() (explicitly not
RiskLimits::default(), which differs), every other knob off, and the halt sentinel at
process-wide — the armed default, because the alternative silently disarms an operator's kill
switch on the shipped paper daemon. See halt and
the paper exchange.
It logs position, working quotes, paper fills and realized PnL every few seconds, then flushes the last synthesised bar and shuts the core down cleanly.
Polymarket is geo-blocked from the US
The Polymarket CLOB — the Gamma catalog read and the market WS alike — is geo-blocked from the US, so this binary must run on, or egress through, an EU host, the same route the catalog and the live market smokes use. No API keys are needed: the market channel is public and unauthenticated, and the mount is paper, so it never signs or sends an order. A US machine can still compile and run the offline test; only the live path needs the route. See Polymarket operations.
Every research knob is opt-in and inert by default, and the defaults are chosen so an unset flag
gives a byte-identical mount: reward-aware quoting (--reward-weight, else POLY_REWARD_WEIGHT,
else 0.0 — off; see liquidity rewards); the
cross-symbol underlying anchor (--underlying, with --underlying-weight, --window-secs and
--atm-blackout-scale, all inert without it); and the flow-toxicity guard (--toxicity, with
--tox-widen, --tox-size-cut, --tox-window-secs and a --wallet-classes JSON map — an absent
map means every wallet is unknown, never toxic, guard inert).
One direction of failure is worth knowing: an unparseable POLY_REWARD_WEIGHT degrades silently
to 0.0, so a decimal comma turns reward-aware quoting off rather than on, with no diagnostic —
and 0.0 is also what an absent variable means, so the two are indistinguishable.
ibkr_mount — a real mount, not paper
Behind the ibkr feature. crates/vike-run/src/bin/ibkr_mount.rs is a headless Interactive
Brokers mount: it loads IBKR_{DEMO|LIVE}_* config, connects the chosen backend as a real
out-of-process ExecutionClient, wires its venue events into a vike-core runtime, and drives
place and cancel from stdin.
usage: ibkr_mount --env demo|live [--backend socket|cpapi] [--sub SYM@INTERVAL ...]The two backends are the bridge's umbrella feature: socket is the vendored blocking client
speaking the TWS wire protocol to a Gateway, cpapi is REST and WS to a browser-authenticated
Client Portal Gateway. Both implement one transport seam and share one exec loop and one mapper,
so they can only diverge inside the transport.
`--env live` is a live account
The parser defaults to demo, and its own test calls that the parser's safety property: this
binary connects a real execution client and drives place and cancel from stdin, so a forgotten or
mistyped --env must never resolve to a live account. --env accepts exactly demo, paper and
live and refuses everything else — including LIVE in the wrong case, which is the shape a typo
actually takes. --sub is repeatable and order-preserving; the last --backend wins, silently.
The mount pattern mirrors the desktop app's, and the header explains why it has to: the live client
cannot be handed the core's event sender, because the core does not exist until spawn_core and
the client is moved into the engine. So the binary builds a standalone event lane, connects the
client against it, spawns the core, and runs a forwarder thread relaying that lane into the core's
sender. Orders go through the core's command lane, never by holding the client.
Market data is separate and optional: --sub SYM@INTERVAL subscribes IBKR bars and trades into the
core's data lanes through a vike_core::CoreLaneSink, over IBKR's own connection with a distinct
client id, and that connection is opened only when at least one --sub was given.
The stuck-order watchdog is armed here at 30 seconds, matching the desktop app's live mount, and the comment on that field argues it is not a nice-to-have: the bridge's own event mapper ends its unroutable-reject arm "relying on submit-ack watchdog", and its rejection code table is a six-code allowlist — so an IB rejection carrying any other code, or an id-less one arriving while two orders are unacked, emits no terminal at all. Without the timeout an order IBKR had already refused sat submitted forever. See the watchdog and IBKR.
Once up, the binary prints its account and backend and accepts buy SYM QTY [PX],
sell SYM QTY [PX], cancel COID, status and quit; an order with no price is a market order.
On exit it shuts down every subscription pump and joins the core.
Venue setup tools
Two one-off operator binaries that arrange something at a venue before trading — cTrader's OAuth catcher and Hyperliquid's builder-fee grant.
Settings files
Four TOML files in one directory, split by who is allowed to change a value and from where, with the precedence order and the compiler-enforced exception that makes a ceiling a ceiling.