vike
ReferenceBinaries

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.

On this page