OpenOutcry
A leak-free, point-in-time environment for trading agents — and the language-agnostic contract they speak.
OpenOutcry is the open-outcry trading floor for agents: the harness hands the agent a point-in-time
Observation, the agent returns a Decision, repeat. Look-ahead is structurally impossible (the
environment owns the time cursor and never hands out a future bar), and trajectories are
recompute-from-raw-decisions, so an agent cannot lie about its returns.
The strategic bet is interface ownership: if every trading agent in the open ecosystem conforms to
the OpenOutcry Observation/Decision contract, then SharpeBench
is the natural scorer and the whole funnel — env → trajectory → score → leaderboard — runs on one
standard. The interface is the product; the simulator is the credibility behind it.
The agent contract (the standard)
An agent is just a program that reads an Observation and writes a Decision — in any language, over
stdio (newline-JSON) or HTTP (POST /decide):
// Observation (harness → agent)
{ "date": "2025-01-02", "cash": 1.0,
"symbols": [{ "symbol": "AAPL", "close_history": [187.2, 188.0, 190.4] }],
"portfolio": [] }
// Decision (agent → harness)
{ "orders": [{ "symbol": "AAPL", "action": "buy", "target_weight": 0.5 }] }
The wire shape is versioned (CONTRACT_VERSION), evolves additively only (new fields are optional
with defaults), and is pinned by published JSON Schemas + a conformance kit. See
GOVERNANCE.md and contract/.
The Gym lifecycle
The same engine SharpeBench runs closed (run_backtest), OpenOutcry exposes open — the caller drives it:
use ;
let data = synthetic;
let mut env = new;
let mut agent = BuyAndHold;
let mut obs = env.reset;
loop
Both stepping surfaces call one shared step_once body, so a trajectory the env produces is
byte-identical to the equivalent run_backtest (enforced by env_step_matches_run_backtest).
env → SharpeBench score
Run with capture, hand the trajectory to a separate verifier that recomputes the submission from the raw decisions + frozen data alone, then score:
cargo run -p openoutcry --example score-a-trajectory
(see examples/score-a-trajectory.rs). Tamper with the trajectory
and the honest replay recomputes to different returns — this is the trust hinge of the whole ecosystem.
Distribution
OpenOutcry ships from one Rust engine to every surface, with a language-agnostic wire contract on top so agents can be written in anything:
- Rust —
openoutcry(this crate). - TypeScript / npm —
@general-liquidity/openoutcry(the engine compiled to WASM). - Python / PyPI —
openoutcry, with agymnasium.Envadapter and a PrimeIntellectverifiersenvironment so it plugs into the RL-training stacks directly.
Reference agents in Rust, TypeScript, and Python double as the conformance smoke tests
(examples/).
Status
Incubating inside the SharpeBench workspace (it depends on the published sharpebench-sim engine).
It graduates to its own repository at distribution time, consuming the engine as a versioned crate.