Upcoming changes to OPRA data normalization

We’re introducing consolidated National Best Bid and Offer (NBBO) quotes for OPRA data, which will replace top-of-book quotes from each individual exchange. As part of this change, the following schemas will be removed from OPRA.PILLAR
on May 27, 2025, at 8:00 PM EDT:
To support this transition, the new consolidated schemas will be available for historical data and in a staging environment for live data starting May 21, 2025, at 8:00 PM EDT.
MBP-1 and TBBO will no longer be generated for OPRA after May 20, but you can continue to request them after that date until they're removed on May 27.
To avoid a breaking change, switch to the new schemas by updating the schema
parameter in your requests.
import databento as db
client = db.Historical()
data_mbp = client.timeseries.get_range(
dataset="OPRA.PILLAR",
schema="cmbp-1", # Instead of "mbp-1"
stype_in="parent",
symbols = ["VIX.OPT"],
start="2025-04-25",
)
data_tcbbo = client.timeseries.get_range(
dataset="OPRA.PILLAR",
schema="tcbbo", # Instead of "tbbo"
stype_in="parent",
symbols = ["VIX.OPT"],
start="2025-04-25",
)
If you still require regional quotes, it's recommended that you use our PCAP service instead. Contact sales to learn more.
CMBP-1 and TCBBO will be available in our staging environment starting May 21: opra-pillar.staging.lsg.databento.com. We strongly recommend validating your integration and testing the new record type(s) in staging before the cutoff on May 27.
import databento as db
client = db.Live(gateway="opra-pillar.staging.lsg.databento.com", port=13000)
client.subscribe(
dataset="OPRA.PILLAR",
schema="cmbp-1", # Instead of "mbp-1"
stype_in="parent",
symbols="MSFT.OPT",
)
client.subscribe(
dataset="OPRA.PILLAR",
schema="tcbbo", # Instead of "tbbo"
stype_in="parent",
symbols="VIX.OPT",
)
for rec in client:
print(rec)
#include <chrono>
#include <databento/fixed_price.hpp>
#include <databento/live.hpp>
#include <databento/publishers.hpp>
#include <databento/record.hpp>
#include <iostream>
using namespace databento;
KeepGoing RecordHandler(const Record& record) {
if (auto* sym = record.GetIf<SymbolMappingMsg>()) {
std::cout << sym->STypeInSymbol() << " has an instrument ID of "
<< sym->hd.instrument_id << '\n';
} else if (auto* cmbp1 = record.GetIf<Cmbp1Msg>()) {
std::cout << cmbp1->hd.instrument_id << cmbp1->levels[0] << '\n';
} else if (auto* error = record.GetIf<ErrorMsg>()) {
std::cerr << error->Err() << '\n';
} else if (auto* system = record.GetIf<SystemMsg>()) {
std::cerr << system->Msg() << '\n';
}
return KeepGoing::Continue;
}
int main() {
// Use staging gateway
auto client = LiveBuilder{}
.SetKeyFromEnv()
.SetAddress("opra-pillar.staging.lsg.databento.com", 13000)
.SetDataset(Dataset::OpraPillar)
.BuildThreaded();
// Instead of Schema::Mbp1
client.Subscribe({"MSFT.OPT"}, Schema::Cmbp1, SType::Parent);
// Instead of Schema::Tcbbo
client.Subscribe({"VIX.OPT"}, Schema::Tcbbo, SType::Parent);
client.Start(RecordHandler);
client.BlockForStop(std::chrono::seconds{5});
return 0;
}
No usage-based rates will apply when using the new schemas in the staging environment.
CMBP-1 vs. MBP-1. CMBP-1 only publishes order book events when the NBBO changes or a trade occurs. Key differences include:
- Order book events that don't update the NBBO are excluded.
bid_ct_00
andask_ct_00
are replaced withbid_pb_00
andask_pb_00
, which indicate the venue displaying the NBBO on each side.- For trades (
action == 'T'
),publisher_id
reflects the individual execution venue. - For all other NBBO updates (
action != 'T'
),publisher_id
is always set toOPRA_PILLAR_OPRA
since prices are consolidated across all venues. - The
depth
andsequence
fields are removed because they're not meaningful in a consolidated view.
TCBBO vs. TBBO. TCBBO also publishes a snapshot of the best bid and offer immediately before each trade, but this reflects the consolidated NBBO rather than the BBO from the executing venue. As a subset of CMBP-1, TCBBO inherits the same field changes listed above.
See our CMBP-1 and TCBBO documentation for a complete list of fields. Both schemas cover history back to March 28, 2023.
Currently, MBP-1 includes every regional quote from each individual exchange, even if those updates don't change the NBBO. This results in large volumes of data—about 1 TB per day—that most users discard during processing. For the same reason, most vendors don't support regional quotes on OPRA.
While our real-time and historical APIs can keep up with every regional quote on the OPRA feed, most users don't have enough bandwidth to process this. The current API doesn't present customers with an option to subscribe only to the NBBO updates to filter out unwanted regional quotes.
By introducing new schemas rather than altering the existing MBP-1 and TBBO schemas on OPRA, we're reserving the possibility of providing both consolidated NBBO and full regional depth in a future offering supported by our dedicated connectivity service.
This update is part of a broader rollout to enhance OPRA coverage and usability. Read the full list of changes in our announcement here.