OneChronos logo

OneChronos

Contact Sales

Market Structure

  • US Equities ATS
  • FX

FIX Integration

  • FIX Spec
    • US Equities ATS
    • FX
  • Primer

Symbology

  • US Equities ATS
  • FX

User Manual

  • US Equities ATS

Expressive Bidding

  • Introduction
  • Getting Started
  • Expressive Bidding Guide
  • Expressive Bidding FAQ
  • Quickstart Examples
    • Dynamic Peg (Not Live)
    • Pairs (Live)
    • Price-Quantity Curves (Not Live)
  • Runnable Templates
    • Single Stock Execution (Not Live)
    • Price-Quantity Indifference Curves (Not Live)
    • Hedging (Not Live)
    • Pairs (Live)
    • ETFs (Not Live)
    • Portfolios (Not Live)
  • Developer Reference

Expressive Bidding

Indifference Curves

Standard limit orders permit one price limit, and that same price limit applies regardless of fill size. However, factors like market impact and cost of liquidity mean the price per share for 100 shares is rarely the same as that of a block.

Production Status: Expressive Bidding is currently enabled for the US Equities ATS "Pairs" only (i.e. Expressive Orders consisting of two symbols with constraints on relative price and quantity), and does not currently include the `mkt()` function. Examples are included beyond what is currently live to facilitate discussion of expected use cases and testing. For details on currently available functionality, please see our Form ATS-N.

Single-Stock Indifference Curve

Objective: Express a willingness to trade different quantities at different price levels, accepting a precise max cost of liquidity for different size fills.

This example involves specifying "tiers", where each tier is a range of fill quantities (min and max) and an associated limit price for fills within the range. This is represented by tier data type below. By combining multiple tiers, we create a price-quantity curve.

Bidder Data:

reason
type tier = {
  min: quantity,
  max: quantity,
  px: int,
};

type curve_data = {
  tiers: list(tier),
};

/* example; provided over FIX */
let curve_data_sample = {
  tiers: [
    {min: 0, max: 999, px: 201},
    {min: 1000, max: 5000, px: 202},
    {min: 5000, max: 9999, px: 203},
    {min: 15000, max: 25000, px: 204},
  ],
};

Bidder Logic:

reason
let price_volume_curve: bidder(_) = (arg, ~mkt) => {
    open Bid;
    let o = List.hd(arg.orders); // Assumes only one order
    Ok (List.map(
        tier => {
            /* Construct an action for a given price/qty tier */
            let within_qty_tier = qty(o) >= const(tier.min)
                               && qty(o) <= const(tier.max);

            subject_to(within_qty_tier,
                place_notional(tier.px * qty(o)));
        },
        arg.bidder_data.tiers)
    );
};

Midpoint Discretion

Objective: Trade different quantities at either the midpoint or at the near touch (NBB or NBO).

Express willingness to trade a larger quantity at a more favorable price (near touch) than at the midpoint. Here we don't need to enumerate tiers as above; we simply denote the quantity thresholds for the two tiers, mid_qty and nbbo_qty. The limit prices for each tier are determined later within bidder logic, through market data accessors such as MID and NBB that expose prices from the latest market snapshot.

Bidder Data:

reason
type midpoint_discretion_data = {
  mid_qty: quantity,
  nbbo_qty: quantity,
};

let midpoint_discretion_data_sample = {
  mid_qty: 200,
  nbbo_qty: 500,
};

Bidder Logic:

reason
let midpoint_discretion: bidder(_) = (arg, ~mkt) => {
  open Bid;
  let o = List.hd(arg.orders); // Assumes only one order
  let mid_qty = o.data.mid_qty;
  let nbbo_qty = o.data.nbbo_qty;

  let nbbo_px = switch (o.order.side) {
    | Buy =>  mkt(o.order.symbol) |> nbb;
    | Sell => mkt(o.order.symbol) |> nbo;
  };
  let mid_px = mkt(o.order.symbol) |> mid;

  Ok ([subject_to(qty(o) <= const(mid_qty),
      place_notional(mid_px * qty(o))),
   subject_to(const(mid_qty) < qty(o) && qty(o) <= const(nbbo_qty),
      place_notional(nbbo_px * qty(o)))]);
};

Dynamic Percent-of-Spread

Objective: Express willingness to trade different quantities at different percentages of spread (with 0% meaning near touch, 50% meaning midpoint, and 100% meaning far touch).

Rather than selecting between NBBO and midpoint as in the "midpoint discretion" template, we can express more specific price preferences by including a "percent of spread" factor in bidder data. Instead of expressing price as a specific value, we include pct_of_spread which will be used to compute the limit price in bidder logic based on momentary market conditions.

Bidder Data:

reason
type spread_tier = {
  min_qty: quantity,
  max_qty: quantity,
  pct_of_spread: int,
};

type spread_data = {tiers: list(spread_tier)};

let spread_data_sample = {
  tiers: [
    {min_qty: 500, max_qty: 1000, pct_of_spread: 0},
    {min_qty: 200, max_qty: 500, pct_of_spread: 20},
    {min_qty: 0, max_qty: 200, pct_of_spread: 50},
  ],
};

Bidder Logic:

reason
let spread_discretion: bidder(_) = (arg, ~mkt) => {
    let o = List.hd(arg.orders); // Assumes only one order
    let nbb = mkt(o.order.symbol) |> nbb;
    let nbo = mkt(o.order.symbol) |> nbo;
    let computed_limit (tier) = switch (o.order.side) {
        | Buy => nbo - (tier.pct_of_spread / 100) * (nbo - nbb);
        | Sell => nbb + (tier.pct_of_spread / 100) * (nbo - nbb);
    };

    open Bid;
    Ok (List.map(
        tier => { subject_to(
            qty(o) >= const(tier.min_qty) && qty(o) <= const(tier.max_qty),
            place_notional(computed_limit(tier) * qty(o)))
        },
        arg.bidder_data.tiers
    ));
};

Next Steps

  1. Try this code in a simulated auction. Load the simulator walkthrough, and replace the bidder logic and data type with an example of your choosing. Tune the runtime arguments and auction parameters to your liking, and run the auction to see results.
  2. Modify to your needs and reach out to the OneChronos team at info@onechronos.com for usage in production.
Previous
Expressive Bidding - Single Stock Execution (Not Live)
Next
Expressive Bidding - Hedging (Not Live)

On this page

  1. Single-Stock Indifference Curve

  2. Midpoint Discretion

  3. Dynamic Percent-of-Spread

  4. Next Steps

OneChronos logo

OneChronos

Asset Classes

US EquitiesEuropean EquitiesFX

Documentation

Getting StartedExpressive BiddingMarket StructureFIX SpecUser Manual

Company

AboutCareersPodcastNewsletter

Support

Contact Sales

Legal

Privacy PolicyTerms of UseCookie PolicyAcceptable Use PolicyBusiness Continuity PlanRegulatory Disclosures
Cookie Settings

OCX Group Inc. is an independent, venture backed company that uses cutting edge technological paradigms to enable the next generation of electronic trading through its separate subsidiary entities. Contact us at info@onechronos.com.

OneChronos ® Markets LLC is a wholly-owned broker-dealer that operates a U.S. equities ATS and is a subsidiary of OCX Group Inc. Member FINRA/SIPC: www.finra.org. Check the background of OneChronos Markets LLC on FINRA’s BrokerCheck. A copy of OneChronos Markets LLC’s ATS-N is available here.

OneChronos Markets FX LLC will operate a Spot FX Platform and is a subsidiary of OCX Group Inc.

Subject to regulatory approval, OneChronos Markets UK Limited will operate a Multilateral Trading Facility to trade UK and Swiss equities, and its wholly owned subsidiary OneChronos Markets NL B.V. will operate a Multilateral Trading Facility to trade European equities.

Copyright © 2025 OneChronos. All rights reserved.