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

Pairs

Pairs trades involve entering into positions in two distinct assets. Because pairs strategies can revolve around the relationship between two assets, they are often sensitive to price spreads, can involve correlated assets, or are subject to dollar neutrality constraints. As a result, executing both legs of the trade separately can incur legging risk as prices change. In these examples, we use Expressive Bidding to control that risk.

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.

Note: these templates are meant to demonstrate bidder logic code in a simulated environment. Templates may require modification for use in production to meet your specific trading objectives and standards.

Weighted Long/Short Pair

Objective: Buy one security and sell another, ensuring that each is filled in the desired ratio (share quantity).

We use bidder data to express the desired ratio between the two securities and associate that data with target orders. For each security, we assign a weighting by creating a data type (security). The weighting will be used in bidder logic to enforce the desired share quantity ratio as a constraint. Using the symbol and side provided, the bidder logic can map the weighting data to the corresponding target order. Since this is a pairs trade we will need two instances of security, which we can represent as a list as shown in pairs_data_sample.

Bidder Data:

reason
type security = {
  symbol: string,
  side: side,
  price: int,
  weighting: int,
};

type pairs_data = {pair: list(security)};

/* Bidder data example: two securities, in a 5:1 ratio */
let pairs_data_sample = {
  pair: [
    {symbol: "ASDF", side: Buy, price: 70, weighting: 1},
    {symbol: "QWER", side: Sell, price: 20, weighting: 5},
  ],
};

Bidder Logic:

reason
let weighted_qty_pairs: bidder(_) = (arg, ~mkt) => {
    open Bid;
    let (a, b) = (List.hd(arg.orders), List.hd(List.tl(arg.orders)));
    let weighted_qty_a = a.data.weighting * qty(a);
    let weighted_qty_b = b.data.weighting * qty(b);

    Ok ([subject_to(weighted_qty_a - weighted_qty_b == const(0),
        place_orders([a,b]))]);
};

Dollar Neutral Pair

Objective: Trade two securities such that the expected notional amount bought in one is equal to the expected notional amount sold in the other.

Target orders contain all the information needed to compute a strict dollar neutrality constraint. Alternatively, we can incorporate a tolerance range that offers a controlled relaxation of the dollar neutrality constraint using bidder data. This can increase the set of possible fills for our Expressive Bid and help find a balance between execution precision and fill rate.

Note that the dollar neutrality constraint is constructed using limit price, not execution price. Price improvement in either security may result in differences in absolute notional executed.

Bidder Logic:

reason
let dollar_neutral_pairs: bidder(_) = (arg, ~mkt) => {
    open Bid;
    let (a, b) = (List.hd(arg.orders), List.hd(List.tl(arg.orders)));
    let dollars_filled = (o) => o.order.price * qty(o);
    Ok ([subject_to(dollars_filled(a) == dollars_filled(b),
        place_orders([a, b]))
    ]);
}

A more idiomatic alternative to the example above uses pattern matching on the list of orders. This also ensures that the list is exactly two orders in length as the bidder logic is expecting, whereas the example above takes the first two orders regardless of how many are presented through arg.

This example also demonstrates how to include a tolerance/error amount on dollar neutrality.

Bidder Data:

reason
type dollar_neutral_data = {tolerance: int};

/* Example: dollar neutral within +/- $1,000 notional */
let my_data = {tolerance: 1000}

Bidder Logic:

reason
let dollar_neutral_pairs_2: bidder(_) = (arg, ~mkt) => {
    open Bid;
    let my_tolerance = arg.bidder_data.tolerance;
    let dollars_filled = (o) => o.order.price * qty(o);

    switch(arg.orders) {
      | [a, b] =>
        let net_notional = dollars_filled(a) - dollars_filled(b);
        let dollar_neutral = abs(net_notional) <= const(my_tolerance);

        /* Place orders if and only if apprx dollar neutral */
        Ok ([subject_to(dollar_neutral,
            place_orders([a,b]))]);
      | _ => Error ("expected exactly two target orders");
    };
}

Pair Spread

Objective: Trade two securities subject to a constraint that the price spread between them is greater than some amount.

In this example, our bidder logic decides whether to execute the trade based on the spread between the midpoint price of the two symbols. We can access the midpoint prices measured by OneChronos at the moment of the auction using the mkt(symbol) market data accessor and mid helper function to extract the mid of NBBO. Note that we calculate spread as an absolute value assuming it is already known which security will be priced higher or lower. This could be verified at runtime by extending bidder data to include an indication of which symbol is expected to be priced higher.

Bidder Data:

reason
type spread_data = {
    spread: int
}

/* Example: min spread of 123 */
let my_data = {spread: 123}

Bidder Logic:

reason
let pairs_spread: bidder(_) = (arg, ~mkt) => {
  let mid = (o) => mkt(o.order.symbol) |> mid;
  switch arg.orders {
    | [a, b] =>
      let spread = abs(mid(a) - mid(b));

      open Bid;
      Ok ([subject_to(const(spread) >= const(arg.bidder_data.spread),
          place_notional(mid(a) * qty(a) + mid(b) * qty(b)))]);
    | _ => Error ("expected exactly two target orders");
  }
};

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 - Hedging (Not Live)
Next
Expressive Bidding - ETFs (Not Live)

On this page

  1. Weighted Long/Short Pair

  2. Dollar Neutral Pair

  3. Pair 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.