@usherlabs/cex-broker 0.2.52 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/cli.js +364 -71
- package/dist/index.js +365 -72
- package/dist/index.js.map +14 -13
- package/package.json +5 -28
- package/dist/commands/cex-canonical-orderbook-export.d.ts +0 -23
- package/dist/commands/cex-canonical-orderbook-export.js +0 -34275
- package/dist/commands/cex-canonical-orderbook-export.js.map +0 -266
- package/dist/commands/market-data-vendor-backfill.d.ts +0 -24
- package/dist/commands/market-data-vendor-backfill.js +0 -34930
- package/dist/commands/market-data-vendor-backfill.js.map +0 -268
- package/dist/handlers/execute-action/context.d.ts +0 -50
- package/dist/handlers/execute-action/deposit.d.ts +0 -2
- package/dist/handlers/execute-action/handler.d.ts +0 -19
- package/dist/handlers/execute-action/index.d.ts +0 -10
- package/dist/handlers/execute-action/internal-transfer.d.ts +0 -2
- package/dist/handlers/execute-action/order-book-call.d.ts +0 -3
- package/dist/handlers/execute-action/orders.d.ts +0 -2
- package/dist/handlers/execute-action/pass-through.d.ts +0 -2
- package/dist/handlers/execute-action/perp-config.d.ts +0 -2
- package/dist/handlers/execute-action/registry.d.ts +0 -5
- package/dist/handlers/execute-action/treasury-call.d.ts +0 -2
- package/dist/handlers/execute-action/withdraw.d.ts +0 -2
- package/dist/handlers/subscribe/broker-lifecycle.d.ts +0 -13
- package/dist/handlers/subscribe/handler.d.ts +0 -20
- package/dist/handlers/subscribe/index.d.ts +0 -2
- package/dist/handlers/types.d.ts +0 -23
- package/dist/helpers/account-balance-archive-poller.d.ts +0 -19
- package/dist/helpers/auth.d.ts +0 -5
- package/dist/helpers/balance-update-archive-consumer.d.ts +0 -16
- package/dist/helpers/binance-user-data-normalization.d.ts +0 -3
- package/dist/helpers/binance-user-data-stream.d.ts +0 -58
- package/dist/helpers/broker-execution-archive/capture.d.ts +0 -41
- package/dist/helpers/broker-execution-archive/index.d.ts +0 -7
- package/dist/helpers/broker-execution-archive/journal-export.d.ts +0 -20
- package/dist/helpers/broker-execution-archive/loss-journal.d.ts +0 -36
- package/dist/helpers/broker-execution-archive/redact.d.ts +0 -7
- package/dist/helpers/broker-execution-archive/rows.d.ts +0 -134
- package/dist/helpers/broker-execution-archive/types.d.ts +0 -26
- package/dist/helpers/broker-execution-archive/withdrawal-observation-tracker.d.ts +0 -23
- package/dist/helpers/broker-execution-archive/writer.d.ts +0 -105
- package/dist/helpers/broker.d.ts +0 -38
- package/dist/helpers/canonical-orderbook-export/exact-selection.d.ts +0 -21
- package/dist/helpers/canonical-orderbook-export/exporter.d.ts +0 -26
- package/dist/helpers/canonical-orderbook-export/parquet-projection.d.ts +0 -19
- package/dist/helpers/constants.d.ts +0 -36
- package/dist/helpers/deposit-archive-poller.d.ts +0 -66
- package/dist/helpers/deposit.d.ts +0 -5
- package/dist/helpers/exchange-credentials.d.ts +0 -10
- package/dist/helpers/fill-archive-poller.d.ts +0 -42
- package/dist/helpers/grpc/broker.d.ts +0 -5
- package/dist/helpers/grpc/callbacks.d.ts +0 -9
- package/dist/helpers/grpc/payload.d.ts +0 -9
- package/dist/helpers/grpc/status.d.ts +0 -8
- package/dist/helpers/index.d.ts +0 -44
- package/dist/helpers/logger.d.ts +0 -13
- package/dist/helpers/market-data-archive/canonical-orderbook.d.ts +0 -20
- package/dist/helpers/market-data-archive/capture-context.d.ts +0 -53
- package/dist/helpers/market-data-archive/capture-contract.d.ts +0 -30
- package/dist/helpers/market-data-archive/capture.d.ts +0 -22
- package/dist/helpers/market-data-archive/index.d.ts +0 -13
- package/dist/helpers/market-data-archive/legacy-migration.d.ts +0 -37
- package/dist/helpers/market-data-archive/ohlcv-bar-tracker.d.ts +0 -11
- package/dist/helpers/market-data-archive/ohlcv-bootstrap.d.ts +0 -1
- package/dist/helpers/market-data-archive/ohlcv-history.d.ts +0 -8
- package/dist/helpers/market-data-archive/orderbook-depth.d.ts +0 -5
- package/dist/helpers/market-data-archive/orderbook-sampler.d.ts +0 -12
- package/dist/helpers/market-data-archive/parse-stream.d.ts +0 -26
- package/dist/helpers/market-data-archive/rows.d.ts +0 -14
- package/dist/helpers/market-data-archive/types.d.ts +0 -83
- package/dist/helpers/market-data-preparation/conformance-fixtures.d.ts +0 -128
- package/dist/helpers/market-data-preparation/contracts.d.ts +0 -2970
- package/dist/helpers/market-data-preparation/file-job.d.ts +0 -38
- package/dist/helpers/market-data-preparation/required-clock-qualification.d.ts +0 -43
- package/dist/helpers/market-data-preparation/source-tape-dependencies.d.ts +0 -19
- package/dist/helpers/market-data-preparation/source-tape-operation.d.ts +0 -109
- package/dist/helpers/market-data-source-forensics.d.ts +0 -400
- package/dist/helpers/market-data-vendor-backfill/archive-reader.d.ts +0 -26
- package/dist/helpers/market-data-vendor-backfill/batching.d.ts +0 -10
- package/dist/helpers/market-data-vendor-backfill/conformance-fixtures.d.ts +0 -78
- package/dist/helpers/market-data-vendor-backfill/contracts.d.ts +0 -358
- package/dist/helpers/market-data-vendor-backfill/core.d.ts +0 -101
- package/dist/helpers/market-data-vendor-backfill/cryptohftdata.d.ts +0 -118
- package/dist/helpers/market-data-vendor-backfill/forwarder-client.d.ts +0 -25
- package/dist/helpers/market-data-vendor-backfill/identity.d.ts +0 -10
- package/dist/helpers/market-data-vendor-backfill/manifests.d.ts +0 -61
- package/dist/helpers/market-data-vendor-backfill/promotion.d.ts +0 -10
- package/dist/helpers/market-data-vendor-backfill/qualification.d.ts +0 -20
- package/dist/helpers/market-data-vendor-backfill/selection.d.ts +0 -30
- package/dist/helpers/market-data-vendor-backfill/semantic-verification.d.ts +0 -25
- package/dist/helpers/market-type.d.ts +0 -16
- package/dist/helpers/order-activity-tracker.d.ts +0 -22
- package/dist/helpers/order-book.d.ts +0 -79
- package/dist/helpers/order-telemetry.d.ts +0 -50
- package/dist/helpers/otel.d.ts +0 -83
- package/dist/helpers/passive-order.d.ts +0 -8
- package/dist/helpers/public-market-data-feed/identity.d.ts +0 -12
- package/dist/helpers/public-market-data-feed/index.d.ts +0 -5
- package/dist/helpers/public-market-data-feed/orderbook-coalescing-evidence.d.ts +0 -79
- package/dist/helpers/public-market-data-feed/orderbook-profile.d.ts +0 -54
- package/dist/helpers/public-market-data-feed/subscriber-buffer.d.ts +0 -31
- package/dist/helpers/public-market-data-feed/supervisor.d.ts +0 -82
- package/dist/helpers/shared/errors.d.ts +0 -14
- package/dist/helpers/shared/guards.d.ts +0 -2
- package/dist/helpers/source-tape-sandbox.d.ts +0 -82
- package/dist/helpers/source-tape.d.ts +0 -165
- package/dist/helpers/stream-health-publisher.d.ts +0 -41
- package/dist/helpers/trace-context.d.ts +0 -8
- package/dist/helpers/transfer-network.d.ts +0 -12
- package/dist/helpers/travel-rule-deposit-reconciler.d.ts +0 -159
- package/dist/helpers/travel-rule.d.ts +0 -75
- package/dist/helpers/treasury-discovery.d.ts +0 -17
- package/dist/helpers/user-asset-archive-poller.d.ts +0 -19
- package/dist/helpers/user-data-stream-supervisor.d.ts +0 -27
- package/dist/helpers/verity.d.ts +0 -5
- package/dist/index.d.ts +0 -56
- package/dist/market-data-preparation/fixtures/conformance-v3.json +0 -621
- package/dist/market-data-preparation/policies/capability-policy.json +0 -39
- package/dist/market-data-preparation/policies/resource-policy.json +0 -16
- package/dist/market-data-preparation/policies/source-tape-capability-v1.json +0 -35
- package/dist/market-data-preparation/schema-manifest.json +0 -66
- package/dist/market-data-preparation/schemas/archive-selection-v1.schema.json +0 -224
- package/dist/market-data-preparation/schemas/backfill-request-v1.schema.json +0 -166
- package/dist/market-data-preparation/schemas/backfill-result-v2.schema.json +0 -212
- package/dist/market-data-preparation/schemas/canonical-orderbook-export-request-v1.schema.json +0 -61
- package/dist/market-data-preparation/schemas/canonical-orderbook-export-result-v2.schema.json +0 -252
- package/dist/market-data-preparation/schemas/order-book-depth-summary-parquet-projection-v1.schema.json +0 -256
- package/dist/market-data-preparation/schemas/order-book-levels-parquet-projection-v1.schema.json +0 -220
- package/dist/market-data-preparation/schemas/preparation-product-pin-v2.schema.json +0 -176
- package/dist/market-data-preparation/schemas/promotion-receipt-v1.schema.json +0 -175
- package/dist/market-data-preparation/schemas/required-clock-v1.schema.json +0 -47
- package/dist/market-data-preparation/schemas/source-forensics-ledger-v1.schema.json +0 -463
- package/dist/market-data-preparation/schemas/source-qualification-record-v1.schema.json +0 -394
- package/dist/market-data-preparation.d.ts +0 -11
- package/dist/market-data-preparation.js +0 -37488
- package/dist/market-data-preparation.js.map +0 -277
- package/dist/market-data-vendor-backfill.d.ts +0 -21
- package/dist/market-data-vendor-backfill.js +0 -22463
- package/dist/market-data-vendor-backfill.js.map +0 -199
- package/dist/proto/node.descriptor.d.ts +0 -127
- package/dist/proto-loader-options.d.ts +0 -7
- package/dist/proto-package-definition.d.ts +0 -2
- package/dist/schemas/action-payloads.d.ts +0 -88
- package/dist/server.d.ts +0 -10
- package/dist/types.d.ts +0 -100
package/dist/index.js
CHANGED
|
@@ -291352,6 +291352,22 @@ import {
|
|
|
291352
291352
|
import { basename, dirname } from "node:path";
|
|
291353
291353
|
var EXPORT_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
291354
291354
|
var SHA256_RECEIPT_PATTERN = /^([0-9a-f]{64}) {2}(.+)\n$/;
|
|
291355
|
+
function sha256File(path) {
|
|
291356
|
+
const hash4 = createHash3("sha256");
|
|
291357
|
+
const fd2 = openSync(path, "r");
|
|
291358
|
+
try {
|
|
291359
|
+
const chunk = Buffer.alloc(EXPORT_CHUNK_BYTES);
|
|
291360
|
+
for (;; ) {
|
|
291361
|
+
const read = readSync(fd2, chunk, 0, chunk.length, null);
|
|
291362
|
+
if (read === 0)
|
|
291363
|
+
break;
|
|
291364
|
+
hash4.update(chunk.subarray(0, read));
|
|
291365
|
+
}
|
|
291366
|
+
} finally {
|
|
291367
|
+
closeSync(fd2);
|
|
291368
|
+
}
|
|
291369
|
+
return hash4.digest("hex");
|
|
291370
|
+
}
|
|
291355
291371
|
|
|
291356
291372
|
class DeadLetterJournalExportError extends Error {
|
|
291357
291373
|
constructor(message, options) {
|
|
@@ -291385,6 +291401,9 @@ function exportDeadLetterJournal(journalPath, exportPath) {
|
|
|
291385
291401
|
if (match?.[1] === undefined || match[2] !== basename(exportPath)) {
|
|
291386
291402
|
throw new Error("export receipt is malformed");
|
|
291387
291403
|
}
|
|
291404
|
+
if (sha256File(exportPath) !== match[1]) {
|
|
291405
|
+
throw new Error("export digest does not match receipt");
|
|
291406
|
+
}
|
|
291388
291407
|
} catch (error) {
|
|
291389
291408
|
throw new DeadLetterJournalExportError("Dead-letter journal export target is incomplete or unverifiable", { cause: error });
|
|
291390
291409
|
}
|
|
@@ -293292,10 +293311,7 @@ import { createHash as createHash4 } from "node:crypto";
|
|
|
293292
293311
|
var MARKET_CAPTURE_SCHEMA_VERSION = "1.0.0";
|
|
293293
293312
|
var CHECKSUM_ALGORITHM = "sha256-canonical-json-v1";
|
|
293294
293313
|
var ARCHIVE_SOURCES = ["broker_read", "broker_write"];
|
|
293295
|
-
var MARKET_ARCHIVE_SOURCES =
|
|
293296
|
-
...ARCHIVE_SOURCES,
|
|
293297
|
-
"external_backfill"
|
|
293298
|
-
];
|
|
293314
|
+
var MARKET_ARCHIVE_SOURCES = ARCHIVE_SOURCES;
|
|
293299
293315
|
var CAPTURE_FEEDS = [
|
|
293300
293316
|
"ORDERBOOK",
|
|
293301
293317
|
"TICKER",
|
|
@@ -293309,15 +293325,12 @@ var SOURCE_MODES = [
|
|
|
293309
293325
|
"broker_bootstrap_fetch_v1",
|
|
293310
293326
|
"external_ccxt_fallback_v1",
|
|
293311
293327
|
"external_hummingbot_fallback_v1",
|
|
293312
|
-
"legacy_migration_v1"
|
|
293313
|
-
"historical_vendor_orderbook_v1",
|
|
293314
|
-
"vendor_historical_backfill_v1"
|
|
293328
|
+
"legacy_migration_v1"
|
|
293315
293329
|
];
|
|
293316
293330
|
var RAW_CAPTURE_SCOPES = [
|
|
293317
293331
|
"ccxt_normalized_object",
|
|
293318
293332
|
"broker_visible_payload",
|
|
293319
|
-
"exchange_wire_frame"
|
|
293320
|
-
"vendor_normalized_dataset_file"
|
|
293333
|
+
"exchange_wire_frame"
|
|
293321
293334
|
];
|
|
293322
293335
|
var CHECKSUM_FIELDS = new Set([
|
|
293323
293336
|
"normalized_row_checksum",
|
|
@@ -293506,6 +293519,9 @@ function createRawCapture(context2, input) {
|
|
|
293506
293519
|
checksumAlgorithm: context2.checksumAlgorithm
|
|
293507
293520
|
};
|
|
293508
293521
|
}
|
|
293522
|
+
function projectRawCapturePayload(rawCapture, redactedPayload) {
|
|
293523
|
+
return { ...rawCapture, redactedPayload };
|
|
293524
|
+
}
|
|
293509
293525
|
function captureCoreFields(context2, rawCapture) {
|
|
293510
293526
|
assertCaptureContext(context2);
|
|
293511
293527
|
return {
|
|
@@ -294082,14 +294098,20 @@ function resolveConservativeOrderBookAcquisitionProfile(input) {
|
|
|
294082
294098
|
id: `${exchange}:conservative:default`,
|
|
294083
294099
|
upstreamLimit: undefined,
|
|
294084
294100
|
guaranteedRetainedDepth: undefined,
|
|
294085
|
-
coalescingSupported: false
|
|
294101
|
+
coalescingSupported: false,
|
|
294102
|
+
bidExhaustionEvidence: false,
|
|
294103
|
+
askExhaustionEvidence: false,
|
|
294104
|
+
exhaustionEvidenceValidated: true
|
|
294086
294105
|
};
|
|
294087
294106
|
}
|
|
294088
294107
|
return {
|
|
294089
294108
|
id: `${exchange}:conservative:limit:${input.requestedDepth}`,
|
|
294090
294109
|
upstreamLimit: input.requestedDepth,
|
|
294091
294110
|
guaranteedRetainedDepth: input.requestedDepth,
|
|
294092
|
-
coalescingSupported: false
|
|
294111
|
+
coalescingSupported: false,
|
|
294112
|
+
bidExhaustionEvidence: false,
|
|
294113
|
+
askExhaustionEvidence: false,
|
|
294114
|
+
exhaustionEvidenceValidated: true
|
|
294093
294115
|
};
|
|
294094
294116
|
}
|
|
294095
294117
|
function resolveOrderBookAcquisitionProfile(input) {
|
|
@@ -294101,7 +294123,10 @@ function resolveOrderBookAcquisitionProfile(input) {
|
|
|
294101
294123
|
id: candidateProfileId,
|
|
294102
294124
|
upstreamLimit: VERIFIED_PROFILE_DEPTH,
|
|
294103
294125
|
guaranteedRetainedDepth: VERIFIED_PROFILE_DEPTH,
|
|
294104
|
-
coalescingSupported: true
|
|
294126
|
+
coalescingSupported: true,
|
|
294127
|
+
bidExhaustionEvidence: false,
|
|
294128
|
+
askExhaustionEvidence: false,
|
|
294129
|
+
exhaustionEvidenceValidated: true
|
|
294105
294130
|
};
|
|
294106
294131
|
}
|
|
294107
294132
|
return resolveConservativeOrderBookAcquisitionProfile(input);
|
|
@@ -294251,7 +294276,63 @@ class PublicFeedSubscriberBuffer {
|
|
|
294251
294276
|
this.#bytes = 0;
|
|
294252
294277
|
}
|
|
294253
294278
|
}
|
|
294279
|
+
// src/helpers/market-data-archive/orderbook-depth.ts
|
|
294280
|
+
var DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 25;
|
|
294281
|
+
var MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 500;
|
|
294282
|
+
var MAX_ORDERBOOK_MEASUREMENT_BANDS = 64;
|
|
294283
|
+
var MAX_ORDERBOOK_MEASUREMENT_BAND_BPS = 1e4;
|
|
294284
|
+
var DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS = [10, 25, 50, 100];
|
|
294285
|
+
function parseBoundedDepth(raw, field) {
|
|
294286
|
+
if (!/^[1-9]\d*$/.test(raw)) {
|
|
294287
|
+
throw new Error(`${field} must be an integer between 1 and 500`);
|
|
294288
|
+
}
|
|
294289
|
+
const parsed = Number(raw);
|
|
294290
|
+
if (!Number.isSafeInteger(parsed) || parsed > MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT) {
|
|
294291
|
+
throw new Error(`${field} must be an integer between 1 and 500`);
|
|
294292
|
+
}
|
|
294293
|
+
return parsed;
|
|
294294
|
+
}
|
|
294295
|
+
function getOrderbookArchiveDepthLimit() {
|
|
294296
|
+
const raw = process.env.CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT?.trim();
|
|
294297
|
+
if (!raw) {
|
|
294298
|
+
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
294299
|
+
}
|
|
294300
|
+
return parseBoundedDepth(raw, "CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT");
|
|
294301
|
+
}
|
|
294302
|
+
function normalizeOrderbookMeasurementBandsBps(input) {
|
|
294303
|
+
const bands = input ?? DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS;
|
|
294304
|
+
if (bands.length === 0) {
|
|
294305
|
+
throw new Error("ORDERBOOK measurement bands must not be empty");
|
|
294306
|
+
}
|
|
294307
|
+
if (bands.length > MAX_ORDERBOOK_MEASUREMENT_BANDS) {
|
|
294308
|
+
throw new Error(`ORDERBOOK measurement bands must contain at most ${MAX_ORDERBOOK_MEASUREMENT_BANDS} entries`);
|
|
294309
|
+
}
|
|
294310
|
+
for (const band of bands) {
|
|
294311
|
+
if (!Number.isSafeInteger(band) || band <= 0 || band > MAX_ORDERBOOK_MEASUREMENT_BAND_BPS) {
|
|
294312
|
+
throw new Error("ORDERBOOK measurement bands must be integer basis points in 1..10000");
|
|
294313
|
+
}
|
|
294314
|
+
}
|
|
294315
|
+
const normalized = [...new Set(bands)].sort((left, right) => left - right);
|
|
294316
|
+
if (normalized.length > MAX_ORDERBOOK_MEASUREMENT_BANDS) {
|
|
294317
|
+
throw new Error(`ORDERBOOK measurement bands must contain at most ${MAX_ORDERBOOK_MEASUREMENT_BANDS} unique entries`);
|
|
294318
|
+
}
|
|
294319
|
+
return normalized;
|
|
294320
|
+
}
|
|
294321
|
+
function getOrderbookMeasurementBandsBps() {
|
|
294322
|
+
const raw = process.env.CEX_BROKER_ORDERBOOK_MEASUREMENT_BANDS_BPS?.trim();
|
|
294323
|
+
if (!raw) {
|
|
294324
|
+
return [...DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS];
|
|
294325
|
+
}
|
|
294326
|
+
const parts = raw.split(",").map((entry) => entry.trim());
|
|
294327
|
+
if (parts.some((entry) => !/^[1-9]\d*$/.test(entry))) {
|
|
294328
|
+
throw new Error("CEX_BROKER_ORDERBOOK_MEASUREMENT_BANDS_BPS must be a comma-separated list of positive integers");
|
|
294329
|
+
}
|
|
294330
|
+
return normalizeOrderbookMeasurementBandsBps(parts.map(Number));
|
|
294331
|
+
}
|
|
294332
|
+
|
|
294254
294333
|
// src/helpers/market-data-archive/canonical-orderbook.ts
|
|
294334
|
+
var ORDERBOOK_SUMMARY_SCHEMA_VERSION = "2.0.0";
|
|
294335
|
+
|
|
294255
294336
|
class OrderBookValidationError extends Error {
|
|
294256
294337
|
reason;
|
|
294257
294338
|
constructor(reason) {
|
|
@@ -294277,38 +294358,70 @@ function parseSequence(value) {
|
|
|
294277
294358
|
}
|
|
294278
294359
|
return parsed.toString(10);
|
|
294279
294360
|
}
|
|
294280
|
-
function
|
|
294361
|
+
function validatePositiveInteger(value, field, maximum = Number.MAX_SAFE_INTEGER) {
|
|
294362
|
+
if (!Number.isSafeInteger(value) || value <= 0 || value > maximum) {
|
|
294363
|
+
throw new OrderBookValidationError(`${field} must be a positive integer${maximum === 500 ? " between 1 and 500" : ""}`);
|
|
294364
|
+
}
|
|
294365
|
+
}
|
|
294366
|
+
function validateSide(side, levels) {
|
|
294281
294367
|
if (levels.length === 0) {
|
|
294282
294368
|
throw new OrderBookValidationError(`${side} side is missing`);
|
|
294283
294369
|
}
|
|
294284
|
-
const
|
|
294285
|
-
for (let index2 = 0;index2 <
|
|
294286
|
-
const entry =
|
|
294370
|
+
const validated = [];
|
|
294371
|
+
for (let index2 = 0;index2 < levels.length; index2 += 1) {
|
|
294372
|
+
const entry = levels[index2];
|
|
294287
294373
|
const price = entry?.[0];
|
|
294288
294374
|
const amount = entry?.[1];
|
|
294289
294375
|
if (!Array.isArray(entry) || entry.length < 2 || price === undefined || amount === undefined || !Number.isFinite(price) || !Number.isFinite(amount) || price <= 0 || amount <= 0) {
|
|
294290
294376
|
throw new OrderBookValidationError(`${side} level ${index2} has a non-positive or non-finite price/amount`);
|
|
294291
294377
|
}
|
|
294292
294378
|
if (index2 > 0) {
|
|
294293
|
-
const previous =
|
|
294379
|
+
const previous = validated[index2 - 1]?.price;
|
|
294294
294380
|
if (previous === undefined || (side === "bid" ? price >= previous : price <= previous)) {
|
|
294295
294381
|
throw new OrderBookValidationError(`${side} levels are not strictly ${side === "bid" ? "descending" : "ascending"}`);
|
|
294296
294382
|
}
|
|
294297
294383
|
}
|
|
294384
|
+
validated.push({ price, amount });
|
|
294298
294385
|
}
|
|
294299
|
-
return
|
|
294300
|
-
price,
|
|
294301
|
-
amount
|
|
294302
|
-
}));
|
|
294386
|
+
return validated;
|
|
294303
294387
|
}
|
|
294304
|
-
function
|
|
294305
|
-
|
|
294306
|
-
|
|
294307
|
-
|
|
294308
|
-
|
|
294388
|
+
function validateMetadata(metadata, observedBids, observedAsks) {
|
|
294389
|
+
if (!metadata.captureProfileId.trim()) {
|
|
294390
|
+
throw new OrderBookValidationError("capture_profile_id must not be empty");
|
|
294391
|
+
}
|
|
294392
|
+
validatePositiveInteger(metadata.effectiveCadenceMs, "effective_cadence_ms");
|
|
294393
|
+
if (metadata.requestedUpstreamDepth !== null) {
|
|
294394
|
+
validatePositiveInteger(metadata.requestedUpstreamDepth, "requested_upstream_depth", 500);
|
|
294395
|
+
}
|
|
294396
|
+
validatePositiveInteger(metadata.observedBidCount, "observed_bid_count");
|
|
294397
|
+
validatePositiveInteger(metadata.observedAskCount, "observed_ask_count");
|
|
294398
|
+
if (metadata.observedBidCount !== observedBids.length) {
|
|
294399
|
+
throw new OrderBookValidationError("observed_bid_count does not match the complete observation");
|
|
294400
|
+
}
|
|
294401
|
+
if (metadata.observedAskCount !== observedAsks.length) {
|
|
294402
|
+
throw new OrderBookValidationError("observed_ask_count does not match the complete observation");
|
|
294403
|
+
}
|
|
294404
|
+
const farthestBid = observedBids.at(-1)?.price;
|
|
294405
|
+
const farthestAsk = observedAsks.at(-1)?.price;
|
|
294406
|
+
if (!Number.isFinite(metadata.observedFarthestBid) || metadata.observedFarthestBid <= 0 || metadata.observedFarthestBid !== farthestBid) {
|
|
294407
|
+
throw new OrderBookValidationError("observed_farthest_bid does not match the complete observation");
|
|
294408
|
+
}
|
|
294409
|
+
if (!Number.isFinite(metadata.observedFarthestAsk) || metadata.observedFarthestAsk <= 0 || metadata.observedFarthestAsk !== farthestAsk) {
|
|
294410
|
+
throw new OrderBookValidationError("observed_farthest_ask does not match the complete observation");
|
|
294411
|
+
}
|
|
294412
|
+
for (const [side, evidence] of [
|
|
294413
|
+
["bid", metadata.exhaustionEvidence.bid],
|
|
294414
|
+
["ask", metadata.exhaustionEvidence.ask]
|
|
294415
|
+
]) {
|
|
294416
|
+
if (evidence.validated !== true || typeof evidence.exhausted !== "boolean" || !evidence.source.trim()) {
|
|
294417
|
+
throw new OrderBookValidationError(`${side} exhaustion evidence must be validated and source-bound`);
|
|
294309
294418
|
}
|
|
294310
294419
|
}
|
|
294311
|
-
|
|
294420
|
+
try {
|
|
294421
|
+
return normalizeOrderbookMeasurementBandsBps(metadata.measurementBandsBps);
|
|
294422
|
+
} catch (error) {
|
|
294423
|
+
throw new OrderBookValidationError(error instanceof Error ? error.message : "invalid measurement bands");
|
|
294424
|
+
}
|
|
294312
294425
|
}
|
|
294313
294426
|
function checksumRow(row) {
|
|
294314
294427
|
return { ...row, normalized_row_checksum: sha256Canonical(row) };
|
|
@@ -294319,20 +294432,33 @@ function commonEvidenceFields(context2, rawCapture, input) {
|
|
|
294319
294432
|
source_time_ms: input.eventTimeMs,
|
|
294320
294433
|
received_time_ms: input.receivedTimeMs,
|
|
294321
294434
|
snapshot_id: input.snapshotId,
|
|
294322
|
-
construction_mode:
|
|
294435
|
+
construction_mode: "sampled_top_n_snapshot",
|
|
294323
294436
|
gap_policy: "record_gap",
|
|
294324
294437
|
depth_limit: input.depthLimit,
|
|
294325
294438
|
sequence: input.sequence,
|
|
294326
294439
|
exact_l2_reconstruction_complete: 0
|
|
294327
294440
|
};
|
|
294328
294441
|
}
|
|
294442
|
+
function sideBandEvidence(input) {
|
|
294443
|
+
const farthest = input.levels.at(-1)?.price;
|
|
294444
|
+
const depths = input.boundaries.map((boundary) => input.levels.filter(({ price }) => input.side === "bid" ? price >= boundary : price <= boundary).reduce((sum3, { amount }) => sum3 + amount, 0));
|
|
294445
|
+
const statuses = input.boundaries.map((boundary) => {
|
|
294446
|
+
const boundaryReached = input.side === "bid" ? farthest <= boundary : farthest >= boundary;
|
|
294447
|
+
return boundaryReached || input.exhausted ? "exact" : "censored";
|
|
294448
|
+
});
|
|
294449
|
+
return { depths, statuses };
|
|
294450
|
+
}
|
|
294329
294451
|
function buildCanonicalOrderBookRows(input) {
|
|
294330
|
-
|
|
294331
|
-
throw new OrderBookValidationError("depth limit must be an integer between 1 and 500");
|
|
294332
|
-
}
|
|
294452
|
+
validatePositiveInteger(input.depthLimit, "depth limit", 500);
|
|
294333
294453
|
if (input.context.feed !== "ORDERBOOK") {
|
|
294334
294454
|
throw new OrderBookValidationError("capture context feed is not ORDERBOOK");
|
|
294335
294455
|
}
|
|
294456
|
+
if (input.context.schemaVersion !== "1.0.0") {
|
|
294457
|
+
throw new OrderBookValidationError("ORDERBOOK raw and level capture schema must be 1.0.0");
|
|
294458
|
+
}
|
|
294459
|
+
if (!input.context.provenanceComplete) {
|
|
294460
|
+
throw new OrderBookValidationError("summary v2 requires complete live provenance");
|
|
294461
|
+
}
|
|
294336
294462
|
if (input.constructionMode === "exact_l2_reconstruction") {
|
|
294337
294463
|
throw new OrderBookValidationError("exact L2 requires a complete continuity proof and is unsupported");
|
|
294338
294464
|
}
|
|
@@ -294347,13 +294473,18 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
294347
294473
|
if (receivedTimeMs < eventTimeMs) {
|
|
294348
294474
|
throw new OrderBookValidationError("received timestamp precedes source timestamp");
|
|
294349
294475
|
}
|
|
294350
|
-
const
|
|
294351
|
-
const
|
|
294352
|
-
const bestBid =
|
|
294353
|
-
const bestAsk =
|
|
294476
|
+
const observedBids = validateSide("bid", input.snapshot.bids);
|
|
294477
|
+
const observedAsks = validateSide("ask", input.snapshot.asks);
|
|
294478
|
+
const bestBid = observedBids[0];
|
|
294479
|
+
const bestAsk = observedAsks[0];
|
|
294354
294480
|
if (bestBid.price >= bestAsk.price) {
|
|
294355
294481
|
throw new OrderBookValidationError("book is crossed or locked");
|
|
294356
294482
|
}
|
|
294483
|
+
const bands = validateMetadata(input.archiveMetadata, observedBids, observedAsks);
|
|
294484
|
+
const bids = observedBids.slice(0, input.depthLimit);
|
|
294485
|
+
const asks = observedAsks.slice(0, input.depthLimit);
|
|
294486
|
+
const retainedFarthestBid = bids.at(-1);
|
|
294487
|
+
const retainedFarthestAsk = asks.at(-1);
|
|
294357
294488
|
const sequence = parseSequence(input.snapshot.sequence);
|
|
294358
294489
|
const midPrice = (bestBid.price + bestAsk.price) / 2;
|
|
294359
294490
|
const spread2 = bestAsk.price - bestBid.price;
|
|
@@ -294373,8 +294504,7 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
294373
294504
|
sequence,
|
|
294374
294505
|
depthLimit: input.depthLimit,
|
|
294375
294506
|
eventTimeMs,
|
|
294376
|
-
receivedTimeMs
|
|
294377
|
-
constructionMode: input.constructionMode ?? "sampled_top_n_snapshot"
|
|
294507
|
+
receivedTimeMs
|
|
294378
294508
|
});
|
|
294379
294509
|
const levels = [
|
|
294380
294510
|
["bid", bids],
|
|
@@ -294392,17 +294522,34 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
294392
294522
|
});
|
|
294393
294523
|
return { table: "market_data.cex_order_book_levels", row };
|
|
294394
294524
|
}));
|
|
294395
|
-
const
|
|
294396
|
-
const
|
|
294397
|
-
|
|
294398
|
-
|
|
294525
|
+
const bidBoundaries = bands.map((band) => midPrice * (1 - band / 1e4));
|
|
294526
|
+
const askBoundaries = bands.map((band) => midPrice * (1 + band / 1e4));
|
|
294527
|
+
const bidEvidence = sideBandEvidence({
|
|
294528
|
+
levels: observedBids,
|
|
294529
|
+
boundaries: bidBoundaries,
|
|
294530
|
+
side: "bid",
|
|
294531
|
+
exhausted: input.archiveMetadata.exhaustionEvidence.bid.exhausted
|
|
294399
294532
|
});
|
|
294400
|
-
const
|
|
294401
|
-
|
|
294402
|
-
|
|
294533
|
+
const askEvidence = sideBandEvidence({
|
|
294534
|
+
levels: observedAsks,
|
|
294535
|
+
boundaries: askBoundaries,
|
|
294536
|
+
side: "ask",
|
|
294537
|
+
exhausted: input.archiveMetadata.exhaustionEvidence.ask.exhausted
|
|
294403
294538
|
});
|
|
294404
294539
|
const summaryRow = checksumRow({
|
|
294405
294540
|
...common,
|
|
294541
|
+
schema_version: ORDERBOOK_SUMMARY_SCHEMA_VERSION,
|
|
294542
|
+
capture_profile_id: input.archiveMetadata.captureProfileId,
|
|
294543
|
+
effective_cadence_ms: input.archiveMetadata.effectiveCadenceMs,
|
|
294544
|
+
requested_upstream_depth: input.archiveMetadata.requestedUpstreamDepth,
|
|
294545
|
+
observed_bid_count: input.archiveMetadata.observedBidCount,
|
|
294546
|
+
observed_ask_count: input.archiveMetadata.observedAskCount,
|
|
294547
|
+
observed_farthest_bid: input.archiveMetadata.observedFarthestBid,
|
|
294548
|
+
observed_farthest_ask: input.archiveMetadata.observedFarthestAsk,
|
|
294549
|
+
retained_farthest_bid: retainedFarthestBid.price,
|
|
294550
|
+
retained_farthest_ask: retainedFarthestAsk.price,
|
|
294551
|
+
bid_exhausted: input.archiveMetadata.exhaustionEvidence.bid.exhausted ? 1 : 0,
|
|
294552
|
+
ask_exhausted: input.archiveMetadata.exhaustionEvidence.ask.exhausted ? 1 : 0,
|
|
294406
294553
|
best_bid: bestBid.price,
|
|
294407
294554
|
best_ask: bestAsk.price,
|
|
294408
294555
|
best_bid_amount: bestBid.amount,
|
|
@@ -294414,8 +294561,12 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
294414
294561
|
bid_level_count: bids.length,
|
|
294415
294562
|
ask_level_count: asks.length,
|
|
294416
294563
|
measurement_bands_bps: bands,
|
|
294417
|
-
|
|
294418
|
-
|
|
294564
|
+
bid_boundary_price_by_band: bidBoundaries,
|
|
294565
|
+
ask_boundary_price_by_band: askBoundaries,
|
|
294566
|
+
bid_depth_by_band: bidEvidence.depths,
|
|
294567
|
+
ask_depth_by_band: askEvidence.depths,
|
|
294568
|
+
bid_status_by_band: bidEvidence.statuses,
|
|
294569
|
+
ask_status_by_band: askEvidence.statuses
|
|
294419
294570
|
});
|
|
294420
294571
|
return {
|
|
294421
294572
|
snapshotId,
|
|
@@ -294545,21 +294696,6 @@ class OhlcvBarTracker {
|
|
|
294545
294696
|
}
|
|
294546
294697
|
}
|
|
294547
294698
|
|
|
294548
|
-
// src/helpers/market-data-archive/orderbook-depth.ts
|
|
294549
|
-
var DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 25;
|
|
294550
|
-
var MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 500;
|
|
294551
|
-
function getOrderbookArchiveDepthLimit() {
|
|
294552
|
-
const raw = process.env.CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
294553
|
-
if (!raw) {
|
|
294554
|
-
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
294555
|
-
}
|
|
294556
|
-
const parsed = Number.parseInt(raw, 10);
|
|
294557
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
294558
|
-
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
294559
|
-
}
|
|
294560
|
-
return Math.min(parsed, MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT);
|
|
294561
|
-
}
|
|
294562
|
-
|
|
294563
294699
|
// src/helpers/market-data-archive/parse-stream.ts
|
|
294564
294700
|
function isFiniteNumber2(value) {
|
|
294565
294701
|
return typeof value === "number" && Number.isFinite(value);
|
|
@@ -294683,13 +294819,17 @@ function legacyMarketFields(context2, rawCapture) {
|
|
|
294683
294819
|
function legacyDecimal8(value) {
|
|
294684
294820
|
return value === undefined ? undefined : Number(value.toFixed(8));
|
|
294685
294821
|
}
|
|
294686
|
-
function buildCanonicalCexStreamEventRow(context2, rawCapture) {
|
|
294822
|
+
function buildCanonicalCexStreamEventRow(context2, rawCapture, options) {
|
|
294823
|
+
const payloadEncoding = options?.payloadEncoding ?? "canonical_json_v1";
|
|
294824
|
+
if (payloadEncoding === "orderbook_metadata_only_v1" && context2.feed !== "ORDERBOOK") {
|
|
294825
|
+
throw new Error("Metadata-only raw encoding requires an ORDERBOOK context");
|
|
294826
|
+
}
|
|
294687
294827
|
const row = withNormalizedChecksum({
|
|
294688
294828
|
...captureCoreFields(context2, rawCapture),
|
|
294689
294829
|
...legacyMarketFields(context2, rawCapture),
|
|
294690
294830
|
stream_type: context2.feed,
|
|
294691
294831
|
event_time_ms: rawCapture.eventTimeMs,
|
|
294692
|
-
payload_encoding:
|
|
294832
|
+
payload_encoding: payloadEncoding,
|
|
294693
294833
|
payload_json: canonicalSerialize(rawCapture.redactedPayload)
|
|
294694
294834
|
});
|
|
294695
294835
|
return { table: "market_data.cex_stream_events", row };
|
|
@@ -294833,7 +294973,13 @@ function archiveOrderbookInBackground(archiver, otelMetrics, input, options) {
|
|
|
294833
294973
|
queueMicrotask(() => {
|
|
294834
294974
|
try {
|
|
294835
294975
|
const context2 = resolveCaptureContext(archiver, input, "ORDERBOOK", options?.sourceMode ?? "broker_live_sampling_v1");
|
|
294836
|
-
const
|
|
294976
|
+
const depthLimit = options?.depthLimit ?? getOrderbookArchiveDepthLimit();
|
|
294977
|
+
const measurementBandsBps = normalizeOrderbookMeasurementBandsBps(input.archiveMetadata.measurementBandsBps);
|
|
294978
|
+
const archiveMetadata = {
|
|
294979
|
+
...input.archiveMetadata,
|
|
294980
|
+
measurementBandsBps
|
|
294981
|
+
};
|
|
294982
|
+
const completeRawCapture = createRawCapture(context2, {
|
|
294837
294983
|
payload: input.snapshot,
|
|
294838
294984
|
eventTimeMs: input.snapshot.timestamp,
|
|
294839
294985
|
receivedTimeMs: input.snapshot.receivedTimestamp,
|
|
@@ -294842,10 +294988,29 @@ function archiveOrderbookInBackground(archiver, otelMetrics, input, options) {
|
|
|
294842
294988
|
const canonical = buildCanonicalOrderBookRows({
|
|
294843
294989
|
context: context2,
|
|
294844
294990
|
snapshot: input.snapshot,
|
|
294845
|
-
rawCapture,
|
|
294846
|
-
depthLimit
|
|
294991
|
+
rawCapture: completeRawCapture,
|
|
294992
|
+
depthLimit,
|
|
294993
|
+
archiveMetadata
|
|
294847
294994
|
});
|
|
294848
|
-
|
|
294995
|
+
const rawMetadata = {
|
|
294996
|
+
capture_profile_id: archiveMetadata.captureProfileId,
|
|
294997
|
+
effective_cadence_ms: archiveMetadata.effectiveCadenceMs,
|
|
294998
|
+
requested_upstream_depth: archiveMetadata.requestedUpstreamDepth,
|
|
294999
|
+
archive_depth_limit: depthLimit,
|
|
295000
|
+
observed_bid_count: archiveMetadata.observedBidCount,
|
|
295001
|
+
observed_ask_count: archiveMetadata.observedAskCount,
|
|
295002
|
+
observed_farthest_bid: canonicalDecimal(archiveMetadata.observedFarthestBid),
|
|
295003
|
+
observed_farthest_ask: canonicalDecimal(archiveMetadata.observedFarthestAsk),
|
|
295004
|
+
bid_exhausted: archiveMetadata.exhaustionEvidence.bid.exhausted,
|
|
295005
|
+
ask_exhausted: archiveMetadata.exhaustionEvidence.ask.exhausted,
|
|
295006
|
+
retained_bid_count: canonical.levels.filter(({ row }) => row.side === "bid").length,
|
|
295007
|
+
retained_ask_count: canonical.levels.filter(({ row }) => row.side === "ask").length,
|
|
295008
|
+
measurement_bands_bps: measurementBandsBps
|
|
295009
|
+
};
|
|
295010
|
+
const storedRawCapture = projectRawCapturePayload(completeRawCapture, rawMetadata);
|
|
295011
|
+
archiver.enqueue(buildCanonicalCexStreamEventRow(context2, storedRawCapture, {
|
|
295012
|
+
payloadEncoding: "orderbook_metadata_only_v1"
|
|
295013
|
+
}));
|
|
294849
295014
|
for (const row of canonical.levels)
|
|
294850
295015
|
archiver.enqueue(row);
|
|
294851
295016
|
archiver.enqueue(canonical.summary);
|
|
@@ -294967,6 +295132,9 @@ function archiveTickerInBackground(archiver, otelMetrics, input) {
|
|
|
294967
295132
|
});
|
|
294968
295133
|
}
|
|
294969
295134
|
function archiveCexStreamEventInBackground(archiver, otelMetrics, input) {
|
|
295135
|
+
if (input.streamType === "ORDERBOOK") {
|
|
295136
|
+
throw new Error("Generic ORDERBOOK archive events are unsupported; use archiveOrderbookInBackground");
|
|
295137
|
+
}
|
|
294970
295138
|
archiveMarketRowsInBackground(archiver, otelMetrics, "stream", input, input.streamType, () => [
|
|
294971
295139
|
buildCexStreamEventRow({
|
|
294972
295140
|
...input,
|
|
@@ -294991,6 +295159,82 @@ function resolveOhlcvBootstrapLimit(optionValue) {
|
|
|
294991
295159
|
}
|
|
294992
295160
|
return Math.min(parsed, MAX_OHLCV_BOOTSTRAP_LIMIT);
|
|
294993
295161
|
}
|
|
295162
|
+
// src/helpers/market-data-archive/summary-v2-conformance.ts
|
|
295163
|
+
var ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELDS = [
|
|
295164
|
+
["source", "String", false],
|
|
295165
|
+
["deployment_id", "String", false],
|
|
295166
|
+
["capture_bundle_id", "String", false],
|
|
295167
|
+
["exchange", "String", false],
|
|
295168
|
+
["symbol", "String", false],
|
|
295169
|
+
["trading_pair", "String", false],
|
|
295170
|
+
["source_symbol", "String", false],
|
|
295171
|
+
["asset_type", "String", false],
|
|
295172
|
+
["feed", "String", false],
|
|
295173
|
+
["provider", "String", false],
|
|
295174
|
+
["source_mode", "String", false],
|
|
295175
|
+
["source_time_ms", "UInt64", false],
|
|
295176
|
+
["received_time_ms", "UInt64", false],
|
|
295177
|
+
["raw_capture_id", "String", false],
|
|
295178
|
+
["raw_capture_scope", "String", false],
|
|
295179
|
+
["schema_version", "String", false],
|
|
295180
|
+
["checksum_algorithm", "String", false],
|
|
295181
|
+
["raw_checksum", "String", false],
|
|
295182
|
+
["provenance_complete", "UInt8", false],
|
|
295183
|
+
["snapshot_id", "String", false],
|
|
295184
|
+
["construction_mode", "String", false],
|
|
295185
|
+
["gap_policy", "String", false],
|
|
295186
|
+
["depth_limit", "UInt16", false],
|
|
295187
|
+
["sequence", "UInt64", true],
|
|
295188
|
+
["exact_l2_reconstruction_complete", "UInt8", false],
|
|
295189
|
+
["capture_profile_id", "String", false],
|
|
295190
|
+
["effective_cadence_ms", "UInt32", false],
|
|
295191
|
+
["requested_upstream_depth", "UInt16", true],
|
|
295192
|
+
["observed_bid_count", "UInt32", false],
|
|
295193
|
+
["observed_ask_count", "UInt32", false],
|
|
295194
|
+
["observed_farthest_bid", "Decimal(38,18)", false],
|
|
295195
|
+
["observed_farthest_ask", "Decimal(38,18)", false],
|
|
295196
|
+
["retained_farthest_bid", "Decimal(38,18)", false],
|
|
295197
|
+
["retained_farthest_ask", "Decimal(38,18)", false],
|
|
295198
|
+
["bid_exhausted", "UInt8", false],
|
|
295199
|
+
["ask_exhausted", "UInt8", false],
|
|
295200
|
+
["best_bid", "Decimal(38,18)", false],
|
|
295201
|
+
["best_ask", "Decimal(38,18)", false],
|
|
295202
|
+
["best_bid_amount", "Decimal(38,18)", false],
|
|
295203
|
+
["best_ask_amount", "Decimal(38,18)", false],
|
|
295204
|
+
["mid_price", "Decimal(38,18)", false],
|
|
295205
|
+
["spread", "Decimal(38,18)", false],
|
|
295206
|
+
["spread_bps", "Float64", false],
|
|
295207
|
+
["staleness_ms", "UInt64", false],
|
|
295208
|
+
["bid_level_count", "UInt16", false],
|
|
295209
|
+
["ask_level_count", "UInt16", false],
|
|
295210
|
+
["measurement_bands_bps", "Array(UInt32)", false],
|
|
295211
|
+
["bid_boundary_price_by_band", "Array(Decimal(38,18))", false],
|
|
295212
|
+
["ask_boundary_price_by_band", "Array(Decimal(38,18))", false],
|
|
295213
|
+
["bid_depth_by_band", "Array(Decimal(38,18))", false],
|
|
295214
|
+
["ask_depth_by_band", "Array(Decimal(38,18))", false],
|
|
295215
|
+
["bid_status_by_band", "Array(Enum8('exact'=1,'censored'=2))", false],
|
|
295216
|
+
["ask_status_by_band", "Array(Enum8('exact'=1,'censored'=2))", false],
|
|
295217
|
+
["normalized_row_checksum", "String", false]
|
|
295218
|
+
];
|
|
295219
|
+
var ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELD_NAMES = ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELDS.map(([name]) => name);
|
|
295220
|
+
var DECIMAL_38_18_FIELDS = new Set([
|
|
295221
|
+
"observed_farthest_bid",
|
|
295222
|
+
"observed_farthest_ask",
|
|
295223
|
+
"retained_farthest_bid",
|
|
295224
|
+
"retained_farthest_ask",
|
|
295225
|
+
"best_bid",
|
|
295226
|
+
"best_ask",
|
|
295227
|
+
"best_bid_amount",
|
|
295228
|
+
"best_ask_amount",
|
|
295229
|
+
"mid_price",
|
|
295230
|
+
"spread"
|
|
295231
|
+
]);
|
|
295232
|
+
var DECIMAL_38_18_ARRAY_FIELDS = new Set([
|
|
295233
|
+
"bid_boundary_price_by_band",
|
|
295234
|
+
"ask_boundary_price_by_band",
|
|
295235
|
+
"bid_depth_by_band",
|
|
295236
|
+
"ask_depth_by_band"
|
|
295237
|
+
]);
|
|
294994
295238
|
// src/helpers/order-book.ts
|
|
294995
295239
|
var ORDER_BOOK_CALL_METHODS = {
|
|
294996
295240
|
FETCH_CAPABILITY: "fetch_order_book_capability",
|
|
@@ -295342,7 +295586,7 @@ class PublicFeedWorker {
|
|
|
295342
295586
|
if (this.options.profile) {
|
|
295343
295587
|
this.options.metrics?.recordCounter("public_feed_acquisition_profiles_total", 1, {
|
|
295344
295588
|
...this.#metricLabels(),
|
|
295345
|
-
|
|
295589
|
+
profile_class: this.options.profile.coalescingSupported ? "coalesced" : "conservative"
|
|
295346
295590
|
});
|
|
295347
295591
|
}
|
|
295348
295592
|
this.#run = this.#watchLoop();
|
|
@@ -295410,7 +295654,34 @@ class PublicFeedWorker {
|
|
|
295410
295654
|
depthLimit: retainedDepth,
|
|
295411
295655
|
receivedTimestamp
|
|
295412
295656
|
});
|
|
295413
|
-
|
|
295657
|
+
const observedBidCount = snapshot.bids.length;
|
|
295658
|
+
const observedAskCount = snapshot.asks.length;
|
|
295659
|
+
this.options.archiveSink.orderbook({
|
|
295660
|
+
...context2,
|
|
295661
|
+
snapshot,
|
|
295662
|
+
archiveMetadata: {
|
|
295663
|
+
captureProfileId: this.options.profile?.id ?? `${this.options.exchangeName}:conservative:default`,
|
|
295664
|
+
effectiveCadenceMs: getOrderbookIntervalMs(),
|
|
295665
|
+
requestedUpstreamDepth: this.options.profile?.upstreamLimit ?? null,
|
|
295666
|
+
observedBidCount,
|
|
295667
|
+
observedAskCount,
|
|
295668
|
+
observedFarthestBid: snapshot.bids.at(-1)?.[0] ?? Number.NaN,
|
|
295669
|
+
observedFarthestAsk: snapshot.asks.at(-1)?.[0] ?? Number.NaN,
|
|
295670
|
+
exhaustionEvidence: {
|
|
295671
|
+
bid: {
|
|
295672
|
+
exhausted: this.options.profile?.bidExhaustionEvidence ?? false,
|
|
295673
|
+
validated: this.options.profile?.exhaustionEvidenceValidated ?? true,
|
|
295674
|
+
source: this.options.profile?.id ?? "broker:conservative"
|
|
295675
|
+
},
|
|
295676
|
+
ask: {
|
|
295677
|
+
exhausted: this.options.profile?.askExhaustionEvidence ?? false,
|
|
295678
|
+
validated: this.options.profile?.exhaustionEvidenceValidated ?? true,
|
|
295679
|
+
source: this.options.profile?.id ?? "broker:conservative"
|
|
295680
|
+
}
|
|
295681
|
+
},
|
|
295682
|
+
measurementBandsBps: getOrderbookMeasurementBandsBps()
|
|
295683
|
+
}
|
|
295684
|
+
}, { sampledOut: !this.#sampler.shouldEmit(receivedTimestamp) });
|
|
295414
295685
|
this.#recordCounter("public_feed_archive_decisions_total");
|
|
295415
295686
|
this.options.observer?.archiveDecision?.(this.#observation());
|
|
295416
295687
|
this.#fanout((subscriber) => this.#frame(projectOrderBookSnapshot(snapshot, subscriber.depthLimit), receivedTimestamp));
|
|
@@ -295583,7 +295854,7 @@ class PublicFeedWorker {
|
|
|
295583
295854
|
}
|
|
295584
295855
|
#metricLabels() {
|
|
295585
295856
|
return {
|
|
295586
|
-
|
|
295857
|
+
exchange_bucket: this.options.exchangeOwned ? "dynamic" : "configured",
|
|
295587
295858
|
feed: this.options.feed,
|
|
295588
295859
|
market_type: this.options.marketType
|
|
295589
295860
|
};
|
|
@@ -310950,7 +311221,29 @@ async function handleOrderBookCall(ctx) {
|
|
|
310950
311221
|
assetType: "spot",
|
|
310951
311222
|
accountSelector: ctx.selectedBrokerAccount?.label,
|
|
310952
311223
|
deploymentId: ctx.brokerArchiver?.getDeploymentId() ?? "unarchived",
|
|
310953
|
-
snapshot
|
|
311224
|
+
snapshot,
|
|
311225
|
+
archiveMetadata: {
|
|
311226
|
+
captureProfileId: `${orderBookPayload.exchange.trim().toLowerCase()}:current-snapshot:requested:${orderBookPayload.depthLimit}`,
|
|
311227
|
+
effectiveCadenceMs: 1,
|
|
311228
|
+
requestedUpstreamDepth: orderBookPayload.depthLimit,
|
|
311229
|
+
observedBidCount: snapshot.bids.length,
|
|
311230
|
+
observedAskCount: snapshot.asks.length,
|
|
311231
|
+
observedFarthestBid: snapshot.bids.at(-1)?.[0] ?? Number.NaN,
|
|
311232
|
+
observedFarthestAsk: snapshot.asks.at(-1)?.[0] ?? Number.NaN,
|
|
311233
|
+
exhaustionEvidence: {
|
|
311234
|
+
bid: {
|
|
311235
|
+
exhausted: false,
|
|
311236
|
+
validated: true,
|
|
311237
|
+
source: "broker:current-snapshot"
|
|
311238
|
+
},
|
|
311239
|
+
ask: {
|
|
311240
|
+
exhausted: false,
|
|
311241
|
+
validated: true,
|
|
311242
|
+
source: "broker:current-snapshot"
|
|
311243
|
+
}
|
|
311244
|
+
},
|
|
311245
|
+
measurementBandsBps: getOrderbookMeasurementBandsBps()
|
|
311246
|
+
}
|
|
310954
311247
|
}, {
|
|
310955
311248
|
sourceMode: "broker_current_snapshot_v1",
|
|
310956
311249
|
depthLimit: orderBookPayload.depthLimit
|
|
@@ -313539,4 +313832,4 @@ export {
|
|
|
313539
313832
|
CEXBroker as default
|
|
313540
313833
|
};
|
|
313541
313834
|
|
|
313542
|
-
//# debugId=
|
|
313835
|
+
//# debugId=46EFCE207D029E0F64756E2164756E21
|