Spreader

An advanced algo for trading spreads between products in different order books.

Specifically, this algo is meant for trading spreads that there is not an exchange listed spread for (e.g. a spread between two products that are not listed on the same exchange would be such a candidate).

This can be used for a variety of different strategies, including cross-exchange arbitrage, futures vs spot basis trading, and relative value trading

pub struct SpreaderAlgoOrder {
    pub order_id: OrderId,
    pub trader: UserId,
    pub account: Option<AccountId>,
    pub spread_kind: SpreadKind,
    pub legs: Vec<Leg>, // must be length at least 2
    pub taking_parameters: Option<TakingParameters>,
    pub quantity: Decimal,
    pub price: Decimal,
    pub dir: Dir,
}

A spread will have legs with taking and quoting parameters.

Every leg will have at most one taking order out, one quoting order, and one quote hedge out at once respectively.

The taking params will be relative to the far side (ie the crossing side) of the bbo. This will not necessarily cross (e.g. you send order one level away from far side so that others can aggress into you) completely but generally will cross.

The quoting params will be relative to the near side

There will be 2 execution types (assume N legs of the spread): SIMULTANEOUS TAKE: all take orders, where all N legs fire at once - there will be no orders out until the spread hits to desired level - the algo will then send orders relative to the far side of the bbo - the spread value is backed out using the potential fill prices relative to the far side of the bbo

QUOTE THEN TAKE: one leg is quoting, while the other legs take only after the quote fill (so there will be potentially N combos of this, one quote for each leg) - the price of the quote is based on the required price to get the desired spread value, assuming that all the other legs are takes - one product is quoting and the others will fire after - for example, for SUM SpreadKind, the quote price is backed out from the desired spread price - SUM(other leg potential fill prices relative to the far side of the bbo)

(if you want quoting on all ends, then you should use a strategy more akin to market making with a target position)

The Preview of the algo will be the one where you can see the synthetic order book of the spread (which will be generated in a greedy manner over the leg order books)

Key features:

  • SpreadKind: the way the spread is calculated

    • Sum: this just sums px_i * ratio_i, example spreads would be ES-SPY, HO-G, BTC Fut - BTC Perp, BTC Perp - BTC Spot

    • NetChangeInTicks: based on individual legs' net change from previous settle price, example spread would be NOB spread, 10s (ZN) vs 30s (ZB) spread

    • Yield: for treasury futures, this is calculated based on yield

    • Custom { formula: String }: based on the formula must watch out for division by zero, example spread would be X - Y / Z , where Y is a contract priced in another currency, and Z is the currency conversion rate currently, only Sum has been implemented

  • When the spread value is breached for TAKING (ie when buying spread value is LOWER than price, when selling spread value is HIGHER than price) then the algo will fire on each leg for the spread_quantity * the ratio of the leg

For each leg, there will be a market, a quantity_ratio, a price_multiplier, and a price_offset. The quantity_ratio is the ratio of the quantity of the leg to the total quantity of the spread. The price_multiplier is the multiplier of the price of the leg to the total price of the spread. Generally, the quantity_ratio and the price_multiplier will be the same, The exceptions will generally be when a spread is traded in different units. For example, Heating-Oil (HO) vs Gasoil (G): - HO is priced in $ / per gallon, G is priced in $ per metric ton - HO contract size is 42,000 gallons, G contract size is 100 metric tons - 1 gallon of heating oil is around 0.00318 metric tons, so the price_multiplier would be 1 HO x -0.00318 G - 42,000 gallons of heating oil is around 133.56 metric tons, so a quantity_ratio of 3 HO x -4 G would yield a similar tonnage (~400 vs 400 metric tons)

The price_offset is applied after the multiplier, and can be used to reflect costs.

Last updated