Table of Contents

MBO (market by orders)

Market-by-order data, the individual orders of the order book, is available only when the connector and the data feed of the instrument provide it, and the user's tariff may restrict it.

  1. Subscribe with SubscribeMarketByOrderData; the returned Task completes when the subscription is active.
  2. MarketByOrders is then the snapshot of the current orders, a collection of MarketByOrder.
  3. Override OnMarketByOrdersChanged(values) to receive the changed orders in real time.
  4. GetMarketByOrdersCache and GetMarketByOrdersWithTradesCache return caches that keep the updates received during a time window.

A MarketByOrder:

Property Meaning
Security The instrument
Time The time of the entry
SourceTimeNs The exchange time in nanoseconds since the Unix epoch (UTC); 0 if the feed does not provide it
Type Snapshot (from the cache, not from the live stream), New, Change or Delete
Side Bid (a buy order) or Ask (a sell order)
Priority The position of the order in the queue of the matching engine
ExchangeOrderId The exchange id of the order
Price, Volume The price and the volume
Reason Why the order changed (cancelled, executed, ...); Unknown if the feed does not state it
Flags Batch boundaries (the beginning and the end of a snapshot) for feeds that deliver updates in atomic batches
ReceivedTime The UTC time the platform received the entry

With MBO data a trade delivered to OnNewTrade carries ExchangeOrderId and AggressorExchangeOrderId: the ids of the resting and the aggressing order.

using System.Collections.Generic;

using ATAS.DataFeedsCore;
using ATAS.Indicators;
using Utils.Common.Logging;

namespace ATAS.Docs.Samples.ChartIndicators.MarketData;

public class MboDataIndicator : Indicator
{
    protected override async void OnInitialize()
    {
        // The task completes when the subscription is active; MarketByOrders is the snapshot
        await SubscribeMarketByOrderData();

        ProcessMarketByOrders(MarketByOrders);
    }

    protected override void OnMarketByOrdersChanged(IEnumerable<MarketByOrder> values)
    {
        this.LogInfo("new MBO data");

        ProcessMarketByOrders(values);
    }

    protected override void OnNewTrade(MarketDataArg trade)
    {
        // With MBO data a trade carries the ids of the orders it was matched with
        this.LogInfo($"ExchangeOrderId: {trade.ExchangeOrderId}, AggressorExchangeOrderId: {trade.AggressorExchangeOrderId}");
    }

    protected override void OnCalculate(int bar, decimal value)
    {
    }

    private void ProcessMarketByOrders(IEnumerable<MarketByOrder> marketByOrders)
    {
        foreach (var marketByOrder in marketByOrders)
            this.LogInfo("{0}", marketByOrder);
    }
}