@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/commands/cli.js
CHANGED
|
@@ -315838,6 +315838,22 @@ import {
|
|
|
315838
315838
|
import { basename, dirname } from "node:path";
|
|
315839
315839
|
var EXPORT_CHUNK_BYTES = 8 * 1024 * 1024;
|
|
315840
315840
|
var SHA256_RECEIPT_PATTERN = /^([0-9a-f]{64}) {2}(.+)\n$/;
|
|
315841
|
+
function sha256File(path) {
|
|
315842
|
+
const hash4 = createHash3("sha256");
|
|
315843
|
+
const fd2 = openSync(path, "r");
|
|
315844
|
+
try {
|
|
315845
|
+
const chunk = Buffer.alloc(EXPORT_CHUNK_BYTES);
|
|
315846
|
+
for (;; ) {
|
|
315847
|
+
const read = readSync(fd2, chunk, 0, chunk.length, null);
|
|
315848
|
+
if (read === 0)
|
|
315849
|
+
break;
|
|
315850
|
+
hash4.update(chunk.subarray(0, read));
|
|
315851
|
+
}
|
|
315852
|
+
} finally {
|
|
315853
|
+
closeSync(fd2);
|
|
315854
|
+
}
|
|
315855
|
+
return hash4.digest("hex");
|
|
315856
|
+
}
|
|
315841
315857
|
|
|
315842
315858
|
class DeadLetterJournalExportError extends Error {
|
|
315843
315859
|
constructor(message, options) {
|
|
@@ -315871,6 +315887,9 @@ function exportDeadLetterJournal(journalPath, exportPath) {
|
|
|
315871
315887
|
if (match?.[1] === undefined || match[2] !== basename(exportPath)) {
|
|
315872
315888
|
throw new Error("export receipt is malformed");
|
|
315873
315889
|
}
|
|
315890
|
+
if (sha256File(exportPath) !== match[1]) {
|
|
315891
|
+
throw new Error("export digest does not match receipt");
|
|
315892
|
+
}
|
|
315874
315893
|
} catch (error) {
|
|
315875
315894
|
throw new DeadLetterJournalExportError("Dead-letter journal export target is incomplete or unverifiable", { cause: error });
|
|
315876
315895
|
}
|
|
@@ -317778,10 +317797,7 @@ import { createHash as createHash4 } from "node:crypto";
|
|
|
317778
317797
|
var MARKET_CAPTURE_SCHEMA_VERSION = "1.0.0";
|
|
317779
317798
|
var CHECKSUM_ALGORITHM = "sha256-canonical-json-v1";
|
|
317780
317799
|
var ARCHIVE_SOURCES = ["broker_read", "broker_write"];
|
|
317781
|
-
var MARKET_ARCHIVE_SOURCES =
|
|
317782
|
-
...ARCHIVE_SOURCES,
|
|
317783
|
-
"external_backfill"
|
|
317784
|
-
];
|
|
317800
|
+
var MARKET_ARCHIVE_SOURCES = ARCHIVE_SOURCES;
|
|
317785
317801
|
var CAPTURE_FEEDS = [
|
|
317786
317802
|
"ORDERBOOK",
|
|
317787
317803
|
"TICKER",
|
|
@@ -317795,15 +317811,12 @@ var SOURCE_MODES = [
|
|
|
317795
317811
|
"broker_bootstrap_fetch_v1",
|
|
317796
317812
|
"external_ccxt_fallback_v1",
|
|
317797
317813
|
"external_hummingbot_fallback_v1",
|
|
317798
|
-
"legacy_migration_v1"
|
|
317799
|
-
"historical_vendor_orderbook_v1",
|
|
317800
|
-
"vendor_historical_backfill_v1"
|
|
317814
|
+
"legacy_migration_v1"
|
|
317801
317815
|
];
|
|
317802
317816
|
var RAW_CAPTURE_SCOPES = [
|
|
317803
317817
|
"ccxt_normalized_object",
|
|
317804
317818
|
"broker_visible_payload",
|
|
317805
|
-
"exchange_wire_frame"
|
|
317806
|
-
"vendor_normalized_dataset_file"
|
|
317819
|
+
"exchange_wire_frame"
|
|
317807
317820
|
];
|
|
317808
317821
|
var CHECKSUM_FIELDS = new Set([
|
|
317809
317822
|
"normalized_row_checksum",
|
|
@@ -317992,6 +318005,9 @@ function createRawCapture(context2, input) {
|
|
|
317992
318005
|
checksumAlgorithm: context2.checksumAlgorithm
|
|
317993
318006
|
};
|
|
317994
318007
|
}
|
|
318008
|
+
function projectRawCapturePayload(rawCapture, redactedPayload) {
|
|
318009
|
+
return { ...rawCapture, redactedPayload };
|
|
318010
|
+
}
|
|
317995
318011
|
function captureCoreFields(context2, rawCapture) {
|
|
317996
318012
|
assertCaptureContext(context2);
|
|
317997
318013
|
return {
|
|
@@ -318568,14 +318584,20 @@ function resolveConservativeOrderBookAcquisitionProfile(input) {
|
|
|
318568
318584
|
id: `${exchange}:conservative:default`,
|
|
318569
318585
|
upstreamLimit: undefined,
|
|
318570
318586
|
guaranteedRetainedDepth: undefined,
|
|
318571
|
-
coalescingSupported: false
|
|
318587
|
+
coalescingSupported: false,
|
|
318588
|
+
bidExhaustionEvidence: false,
|
|
318589
|
+
askExhaustionEvidence: false,
|
|
318590
|
+
exhaustionEvidenceValidated: true
|
|
318572
318591
|
};
|
|
318573
318592
|
}
|
|
318574
318593
|
return {
|
|
318575
318594
|
id: `${exchange}:conservative:limit:${input.requestedDepth}`,
|
|
318576
318595
|
upstreamLimit: input.requestedDepth,
|
|
318577
318596
|
guaranteedRetainedDepth: input.requestedDepth,
|
|
318578
|
-
coalescingSupported: false
|
|
318597
|
+
coalescingSupported: false,
|
|
318598
|
+
bidExhaustionEvidence: false,
|
|
318599
|
+
askExhaustionEvidence: false,
|
|
318600
|
+
exhaustionEvidenceValidated: true
|
|
318579
318601
|
};
|
|
318580
318602
|
}
|
|
318581
318603
|
function resolveOrderBookAcquisitionProfile(input) {
|
|
@@ -318587,7 +318609,10 @@ function resolveOrderBookAcquisitionProfile(input) {
|
|
|
318587
318609
|
id: candidateProfileId,
|
|
318588
318610
|
upstreamLimit: VERIFIED_PROFILE_DEPTH,
|
|
318589
318611
|
guaranteedRetainedDepth: VERIFIED_PROFILE_DEPTH,
|
|
318590
|
-
coalescingSupported: true
|
|
318612
|
+
coalescingSupported: true,
|
|
318613
|
+
bidExhaustionEvidence: false,
|
|
318614
|
+
askExhaustionEvidence: false,
|
|
318615
|
+
exhaustionEvidenceValidated: true
|
|
318591
318616
|
};
|
|
318592
318617
|
}
|
|
318593
318618
|
return resolveConservativeOrderBookAcquisitionProfile(input);
|
|
@@ -318737,7 +318762,63 @@ class PublicFeedSubscriberBuffer {
|
|
|
318737
318762
|
this.#bytes = 0;
|
|
318738
318763
|
}
|
|
318739
318764
|
}
|
|
318765
|
+
// src/helpers/market-data-archive/orderbook-depth.ts
|
|
318766
|
+
var DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 25;
|
|
318767
|
+
var MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 500;
|
|
318768
|
+
var MAX_ORDERBOOK_MEASUREMENT_BANDS = 64;
|
|
318769
|
+
var MAX_ORDERBOOK_MEASUREMENT_BAND_BPS = 1e4;
|
|
318770
|
+
var DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS = [10, 25, 50, 100];
|
|
318771
|
+
function parseBoundedDepth(raw, field) {
|
|
318772
|
+
if (!/^[1-9]\d*$/.test(raw)) {
|
|
318773
|
+
throw new Error(`${field} must be an integer between 1 and 500`);
|
|
318774
|
+
}
|
|
318775
|
+
const parsed = Number(raw);
|
|
318776
|
+
if (!Number.isSafeInteger(parsed) || parsed > MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT) {
|
|
318777
|
+
throw new Error(`${field} must be an integer between 1 and 500`);
|
|
318778
|
+
}
|
|
318779
|
+
return parsed;
|
|
318780
|
+
}
|
|
318781
|
+
function getOrderbookArchiveDepthLimit() {
|
|
318782
|
+
const raw = process.env.CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT?.trim();
|
|
318783
|
+
if (!raw) {
|
|
318784
|
+
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
318785
|
+
}
|
|
318786
|
+
return parseBoundedDepth(raw, "CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT");
|
|
318787
|
+
}
|
|
318788
|
+
function normalizeOrderbookMeasurementBandsBps(input) {
|
|
318789
|
+
const bands = input ?? DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS;
|
|
318790
|
+
if (bands.length === 0) {
|
|
318791
|
+
throw new Error("ORDERBOOK measurement bands must not be empty");
|
|
318792
|
+
}
|
|
318793
|
+
if (bands.length > MAX_ORDERBOOK_MEASUREMENT_BANDS) {
|
|
318794
|
+
throw new Error(`ORDERBOOK measurement bands must contain at most ${MAX_ORDERBOOK_MEASUREMENT_BANDS} entries`);
|
|
318795
|
+
}
|
|
318796
|
+
for (const band of bands) {
|
|
318797
|
+
if (!Number.isSafeInteger(band) || band <= 0 || band > MAX_ORDERBOOK_MEASUREMENT_BAND_BPS) {
|
|
318798
|
+
throw new Error("ORDERBOOK measurement bands must be integer basis points in 1..10000");
|
|
318799
|
+
}
|
|
318800
|
+
}
|
|
318801
|
+
const normalized = [...new Set(bands)].sort((left, right) => left - right);
|
|
318802
|
+
if (normalized.length > MAX_ORDERBOOK_MEASUREMENT_BANDS) {
|
|
318803
|
+
throw new Error(`ORDERBOOK measurement bands must contain at most ${MAX_ORDERBOOK_MEASUREMENT_BANDS} unique entries`);
|
|
318804
|
+
}
|
|
318805
|
+
return normalized;
|
|
318806
|
+
}
|
|
318807
|
+
function getOrderbookMeasurementBandsBps() {
|
|
318808
|
+
const raw = process.env.CEX_BROKER_ORDERBOOK_MEASUREMENT_BANDS_BPS?.trim();
|
|
318809
|
+
if (!raw) {
|
|
318810
|
+
return [...DEFAULT_ORDERBOOK_MEASUREMENT_BANDS_BPS];
|
|
318811
|
+
}
|
|
318812
|
+
const parts = raw.split(",").map((entry) => entry.trim());
|
|
318813
|
+
if (parts.some((entry) => !/^[1-9]\d*$/.test(entry))) {
|
|
318814
|
+
throw new Error("CEX_BROKER_ORDERBOOK_MEASUREMENT_BANDS_BPS must be a comma-separated list of positive integers");
|
|
318815
|
+
}
|
|
318816
|
+
return normalizeOrderbookMeasurementBandsBps(parts.map(Number));
|
|
318817
|
+
}
|
|
318818
|
+
|
|
318740
318819
|
// src/helpers/market-data-archive/canonical-orderbook.ts
|
|
318820
|
+
var ORDERBOOK_SUMMARY_SCHEMA_VERSION = "2.0.0";
|
|
318821
|
+
|
|
318741
318822
|
class OrderBookValidationError extends Error {
|
|
318742
318823
|
reason;
|
|
318743
318824
|
constructor(reason) {
|
|
@@ -318763,38 +318844,70 @@ function parseSequence(value) {
|
|
|
318763
318844
|
}
|
|
318764
318845
|
return parsed.toString(10);
|
|
318765
318846
|
}
|
|
318766
|
-
function
|
|
318847
|
+
function validatePositiveInteger(value, field, maximum = Number.MAX_SAFE_INTEGER) {
|
|
318848
|
+
if (!Number.isSafeInteger(value) || value <= 0 || value > maximum) {
|
|
318849
|
+
throw new OrderBookValidationError(`${field} must be a positive integer${maximum === 500 ? " between 1 and 500" : ""}`);
|
|
318850
|
+
}
|
|
318851
|
+
}
|
|
318852
|
+
function validateSide(side, levels) {
|
|
318767
318853
|
if (levels.length === 0) {
|
|
318768
318854
|
throw new OrderBookValidationError(`${side} side is missing`);
|
|
318769
318855
|
}
|
|
318770
|
-
const
|
|
318771
|
-
for (let index2 = 0;index2 <
|
|
318772
|
-
const entry =
|
|
318856
|
+
const validated = [];
|
|
318857
|
+
for (let index2 = 0;index2 < levels.length; index2 += 1) {
|
|
318858
|
+
const entry = levels[index2];
|
|
318773
318859
|
const price = entry?.[0];
|
|
318774
318860
|
const amount = entry?.[1];
|
|
318775
318861
|
if (!Array.isArray(entry) || entry.length < 2 || price === undefined || amount === undefined || !Number.isFinite(price) || !Number.isFinite(amount) || price <= 0 || amount <= 0) {
|
|
318776
318862
|
throw new OrderBookValidationError(`${side} level ${index2} has a non-positive or non-finite price/amount`);
|
|
318777
318863
|
}
|
|
318778
318864
|
if (index2 > 0) {
|
|
318779
|
-
const previous =
|
|
318865
|
+
const previous = validated[index2 - 1]?.price;
|
|
318780
318866
|
if (previous === undefined || (side === "bid" ? price >= previous : price <= previous)) {
|
|
318781
318867
|
throw new OrderBookValidationError(`${side} levels are not strictly ${side === "bid" ? "descending" : "ascending"}`);
|
|
318782
318868
|
}
|
|
318783
318869
|
}
|
|
318870
|
+
validated.push({ price, amount });
|
|
318784
318871
|
}
|
|
318785
|
-
return
|
|
318786
|
-
price,
|
|
318787
|
-
amount
|
|
318788
|
-
}));
|
|
318872
|
+
return validated;
|
|
318789
318873
|
}
|
|
318790
|
-
function
|
|
318791
|
-
|
|
318792
|
-
|
|
318793
|
-
|
|
318794
|
-
|
|
318874
|
+
function validateMetadata(metadata, observedBids, observedAsks) {
|
|
318875
|
+
if (!metadata.captureProfileId.trim()) {
|
|
318876
|
+
throw new OrderBookValidationError("capture_profile_id must not be empty");
|
|
318877
|
+
}
|
|
318878
|
+
validatePositiveInteger(metadata.effectiveCadenceMs, "effective_cadence_ms");
|
|
318879
|
+
if (metadata.requestedUpstreamDepth !== null) {
|
|
318880
|
+
validatePositiveInteger(metadata.requestedUpstreamDepth, "requested_upstream_depth", 500);
|
|
318881
|
+
}
|
|
318882
|
+
validatePositiveInteger(metadata.observedBidCount, "observed_bid_count");
|
|
318883
|
+
validatePositiveInteger(metadata.observedAskCount, "observed_ask_count");
|
|
318884
|
+
if (metadata.observedBidCount !== observedBids.length) {
|
|
318885
|
+
throw new OrderBookValidationError("observed_bid_count does not match the complete observation");
|
|
318886
|
+
}
|
|
318887
|
+
if (metadata.observedAskCount !== observedAsks.length) {
|
|
318888
|
+
throw new OrderBookValidationError("observed_ask_count does not match the complete observation");
|
|
318889
|
+
}
|
|
318890
|
+
const farthestBid = observedBids.at(-1)?.price;
|
|
318891
|
+
const farthestAsk = observedAsks.at(-1)?.price;
|
|
318892
|
+
if (!Number.isFinite(metadata.observedFarthestBid) || metadata.observedFarthestBid <= 0 || metadata.observedFarthestBid !== farthestBid) {
|
|
318893
|
+
throw new OrderBookValidationError("observed_farthest_bid does not match the complete observation");
|
|
318894
|
+
}
|
|
318895
|
+
if (!Number.isFinite(metadata.observedFarthestAsk) || metadata.observedFarthestAsk <= 0 || metadata.observedFarthestAsk !== farthestAsk) {
|
|
318896
|
+
throw new OrderBookValidationError("observed_farthest_ask does not match the complete observation");
|
|
318897
|
+
}
|
|
318898
|
+
for (const [side, evidence] of [
|
|
318899
|
+
["bid", metadata.exhaustionEvidence.bid],
|
|
318900
|
+
["ask", metadata.exhaustionEvidence.ask]
|
|
318901
|
+
]) {
|
|
318902
|
+
if (evidence.validated !== true || typeof evidence.exhausted !== "boolean" || !evidence.source.trim()) {
|
|
318903
|
+
throw new OrderBookValidationError(`${side} exhaustion evidence must be validated and source-bound`);
|
|
318795
318904
|
}
|
|
318796
318905
|
}
|
|
318797
|
-
|
|
318906
|
+
try {
|
|
318907
|
+
return normalizeOrderbookMeasurementBandsBps(metadata.measurementBandsBps);
|
|
318908
|
+
} catch (error) {
|
|
318909
|
+
throw new OrderBookValidationError(error instanceof Error ? error.message : "invalid measurement bands");
|
|
318910
|
+
}
|
|
318798
318911
|
}
|
|
318799
318912
|
function checksumRow(row) {
|
|
318800
318913
|
return { ...row, normalized_row_checksum: sha256Canonical(row) };
|
|
@@ -318805,20 +318918,33 @@ function commonEvidenceFields(context2, rawCapture, input) {
|
|
|
318805
318918
|
source_time_ms: input.eventTimeMs,
|
|
318806
318919
|
received_time_ms: input.receivedTimeMs,
|
|
318807
318920
|
snapshot_id: input.snapshotId,
|
|
318808
|
-
construction_mode:
|
|
318921
|
+
construction_mode: "sampled_top_n_snapshot",
|
|
318809
318922
|
gap_policy: "record_gap",
|
|
318810
318923
|
depth_limit: input.depthLimit,
|
|
318811
318924
|
sequence: input.sequence,
|
|
318812
318925
|
exact_l2_reconstruction_complete: 0
|
|
318813
318926
|
};
|
|
318814
318927
|
}
|
|
318928
|
+
function sideBandEvidence(input) {
|
|
318929
|
+
const farthest = input.levels.at(-1)?.price;
|
|
318930
|
+
const depths = input.boundaries.map((boundary) => input.levels.filter(({ price }) => input.side === "bid" ? price >= boundary : price <= boundary).reduce((sum3, { amount }) => sum3 + amount, 0));
|
|
318931
|
+
const statuses = input.boundaries.map((boundary) => {
|
|
318932
|
+
const boundaryReached = input.side === "bid" ? farthest <= boundary : farthest >= boundary;
|
|
318933
|
+
return boundaryReached || input.exhausted ? "exact" : "censored";
|
|
318934
|
+
});
|
|
318935
|
+
return { depths, statuses };
|
|
318936
|
+
}
|
|
318815
318937
|
function buildCanonicalOrderBookRows(input) {
|
|
318816
|
-
|
|
318817
|
-
throw new OrderBookValidationError("depth limit must be an integer between 1 and 500");
|
|
318818
|
-
}
|
|
318938
|
+
validatePositiveInteger(input.depthLimit, "depth limit", 500);
|
|
318819
318939
|
if (input.context.feed !== "ORDERBOOK") {
|
|
318820
318940
|
throw new OrderBookValidationError("capture context feed is not ORDERBOOK");
|
|
318821
318941
|
}
|
|
318942
|
+
if (input.context.schemaVersion !== "1.0.0") {
|
|
318943
|
+
throw new OrderBookValidationError("ORDERBOOK raw and level capture schema must be 1.0.0");
|
|
318944
|
+
}
|
|
318945
|
+
if (!input.context.provenanceComplete) {
|
|
318946
|
+
throw new OrderBookValidationError("summary v2 requires complete live provenance");
|
|
318947
|
+
}
|
|
318822
318948
|
if (input.constructionMode === "exact_l2_reconstruction") {
|
|
318823
318949
|
throw new OrderBookValidationError("exact L2 requires a complete continuity proof and is unsupported");
|
|
318824
318950
|
}
|
|
@@ -318833,13 +318959,18 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
318833
318959
|
if (receivedTimeMs < eventTimeMs) {
|
|
318834
318960
|
throw new OrderBookValidationError("received timestamp precedes source timestamp");
|
|
318835
318961
|
}
|
|
318836
|
-
const
|
|
318837
|
-
const
|
|
318838
|
-
const bestBid =
|
|
318839
|
-
const bestAsk =
|
|
318962
|
+
const observedBids = validateSide("bid", input.snapshot.bids);
|
|
318963
|
+
const observedAsks = validateSide("ask", input.snapshot.asks);
|
|
318964
|
+
const bestBid = observedBids[0];
|
|
318965
|
+
const bestAsk = observedAsks[0];
|
|
318840
318966
|
if (bestBid.price >= bestAsk.price) {
|
|
318841
318967
|
throw new OrderBookValidationError("book is crossed or locked");
|
|
318842
318968
|
}
|
|
318969
|
+
const bands = validateMetadata(input.archiveMetadata, observedBids, observedAsks);
|
|
318970
|
+
const bids = observedBids.slice(0, input.depthLimit);
|
|
318971
|
+
const asks = observedAsks.slice(0, input.depthLimit);
|
|
318972
|
+
const retainedFarthestBid = bids.at(-1);
|
|
318973
|
+
const retainedFarthestAsk = asks.at(-1);
|
|
318843
318974
|
const sequence = parseSequence(input.snapshot.sequence);
|
|
318844
318975
|
const midPrice = (bestBid.price + bestAsk.price) / 2;
|
|
318845
318976
|
const spread2 = bestAsk.price - bestBid.price;
|
|
@@ -318859,8 +318990,7 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
318859
318990
|
sequence,
|
|
318860
318991
|
depthLimit: input.depthLimit,
|
|
318861
318992
|
eventTimeMs,
|
|
318862
|
-
receivedTimeMs
|
|
318863
|
-
constructionMode: input.constructionMode ?? "sampled_top_n_snapshot"
|
|
318993
|
+
receivedTimeMs
|
|
318864
318994
|
});
|
|
318865
318995
|
const levels = [
|
|
318866
318996
|
["bid", bids],
|
|
@@ -318878,17 +319008,34 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
318878
319008
|
});
|
|
318879
319009
|
return { table: "market_data.cex_order_book_levels", row };
|
|
318880
319010
|
}));
|
|
318881
|
-
const
|
|
318882
|
-
const
|
|
318883
|
-
|
|
318884
|
-
|
|
319011
|
+
const bidBoundaries = bands.map((band) => midPrice * (1 - band / 1e4));
|
|
319012
|
+
const askBoundaries = bands.map((band) => midPrice * (1 + band / 1e4));
|
|
319013
|
+
const bidEvidence = sideBandEvidence({
|
|
319014
|
+
levels: observedBids,
|
|
319015
|
+
boundaries: bidBoundaries,
|
|
319016
|
+
side: "bid",
|
|
319017
|
+
exhausted: input.archiveMetadata.exhaustionEvidence.bid.exhausted
|
|
318885
319018
|
});
|
|
318886
|
-
const
|
|
318887
|
-
|
|
318888
|
-
|
|
319019
|
+
const askEvidence = sideBandEvidence({
|
|
319020
|
+
levels: observedAsks,
|
|
319021
|
+
boundaries: askBoundaries,
|
|
319022
|
+
side: "ask",
|
|
319023
|
+
exhausted: input.archiveMetadata.exhaustionEvidence.ask.exhausted
|
|
318889
319024
|
});
|
|
318890
319025
|
const summaryRow = checksumRow({
|
|
318891
319026
|
...common,
|
|
319027
|
+
schema_version: ORDERBOOK_SUMMARY_SCHEMA_VERSION,
|
|
319028
|
+
capture_profile_id: input.archiveMetadata.captureProfileId,
|
|
319029
|
+
effective_cadence_ms: input.archiveMetadata.effectiveCadenceMs,
|
|
319030
|
+
requested_upstream_depth: input.archiveMetadata.requestedUpstreamDepth,
|
|
319031
|
+
observed_bid_count: input.archiveMetadata.observedBidCount,
|
|
319032
|
+
observed_ask_count: input.archiveMetadata.observedAskCount,
|
|
319033
|
+
observed_farthest_bid: input.archiveMetadata.observedFarthestBid,
|
|
319034
|
+
observed_farthest_ask: input.archiveMetadata.observedFarthestAsk,
|
|
319035
|
+
retained_farthest_bid: retainedFarthestBid.price,
|
|
319036
|
+
retained_farthest_ask: retainedFarthestAsk.price,
|
|
319037
|
+
bid_exhausted: input.archiveMetadata.exhaustionEvidence.bid.exhausted ? 1 : 0,
|
|
319038
|
+
ask_exhausted: input.archiveMetadata.exhaustionEvidence.ask.exhausted ? 1 : 0,
|
|
318892
319039
|
best_bid: bestBid.price,
|
|
318893
319040
|
best_ask: bestAsk.price,
|
|
318894
319041
|
best_bid_amount: bestBid.amount,
|
|
@@ -318900,8 +319047,12 @@ function buildCanonicalOrderBookRows(input) {
|
|
|
318900
319047
|
bid_level_count: bids.length,
|
|
318901
319048
|
ask_level_count: asks.length,
|
|
318902
319049
|
measurement_bands_bps: bands,
|
|
318903
|
-
|
|
318904
|
-
|
|
319050
|
+
bid_boundary_price_by_band: bidBoundaries,
|
|
319051
|
+
ask_boundary_price_by_band: askBoundaries,
|
|
319052
|
+
bid_depth_by_band: bidEvidence.depths,
|
|
319053
|
+
ask_depth_by_band: askEvidence.depths,
|
|
319054
|
+
bid_status_by_band: bidEvidence.statuses,
|
|
319055
|
+
ask_status_by_band: askEvidence.statuses
|
|
318905
319056
|
});
|
|
318906
319057
|
return {
|
|
318907
319058
|
snapshotId,
|
|
@@ -319031,21 +319182,6 @@ class OhlcvBarTracker {
|
|
|
319031
319182
|
}
|
|
319032
319183
|
}
|
|
319033
319184
|
|
|
319034
|
-
// src/helpers/market-data-archive/orderbook-depth.ts
|
|
319035
|
-
var DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 25;
|
|
319036
|
-
var MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT = 500;
|
|
319037
|
-
function getOrderbookArchiveDepthLimit() {
|
|
319038
|
-
const raw = process.env.CEX_BROKER_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
319039
|
-
if (!raw) {
|
|
319040
|
-
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
319041
|
-
}
|
|
319042
|
-
const parsed = Number.parseInt(raw, 10);
|
|
319043
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
319044
|
-
return DEFAULT_ORDERBOOK_ARCHIVE_DEPTH_LIMIT;
|
|
319045
|
-
}
|
|
319046
|
-
return Math.min(parsed, MAX_ORDERBOOK_ARCHIVE_DEPTH_LIMIT);
|
|
319047
|
-
}
|
|
319048
|
-
|
|
319049
319185
|
// src/helpers/market-data-archive/parse-stream.ts
|
|
319050
319186
|
function isFiniteNumber2(value) {
|
|
319051
319187
|
return typeof value === "number" && Number.isFinite(value);
|
|
@@ -319169,13 +319305,17 @@ function legacyMarketFields(context2, rawCapture) {
|
|
|
319169
319305
|
function legacyDecimal8(value) {
|
|
319170
319306
|
return value === undefined ? undefined : Number(value.toFixed(8));
|
|
319171
319307
|
}
|
|
319172
|
-
function buildCanonicalCexStreamEventRow(context2, rawCapture) {
|
|
319308
|
+
function buildCanonicalCexStreamEventRow(context2, rawCapture, options) {
|
|
319309
|
+
const payloadEncoding = options?.payloadEncoding ?? "canonical_json_v1";
|
|
319310
|
+
if (payloadEncoding === "orderbook_metadata_only_v1" && context2.feed !== "ORDERBOOK") {
|
|
319311
|
+
throw new Error("Metadata-only raw encoding requires an ORDERBOOK context");
|
|
319312
|
+
}
|
|
319173
319313
|
const row = withNormalizedChecksum({
|
|
319174
319314
|
...captureCoreFields(context2, rawCapture),
|
|
319175
319315
|
...legacyMarketFields(context2, rawCapture),
|
|
319176
319316
|
stream_type: context2.feed,
|
|
319177
319317
|
event_time_ms: rawCapture.eventTimeMs,
|
|
319178
|
-
payload_encoding:
|
|
319318
|
+
payload_encoding: payloadEncoding,
|
|
319179
319319
|
payload_json: canonicalSerialize(rawCapture.redactedPayload)
|
|
319180
319320
|
});
|
|
319181
319321
|
return { table: "market_data.cex_stream_events", row };
|
|
@@ -319319,7 +319459,13 @@ function archiveOrderbookInBackground(archiver, otelMetrics, input, options) {
|
|
|
319319
319459
|
queueMicrotask(() => {
|
|
319320
319460
|
try {
|
|
319321
319461
|
const context2 = resolveCaptureContext(archiver, input, "ORDERBOOK", options?.sourceMode ?? "broker_live_sampling_v1");
|
|
319322
|
-
const
|
|
319462
|
+
const depthLimit = options?.depthLimit ?? getOrderbookArchiveDepthLimit();
|
|
319463
|
+
const measurementBandsBps = normalizeOrderbookMeasurementBandsBps(input.archiveMetadata.measurementBandsBps);
|
|
319464
|
+
const archiveMetadata = {
|
|
319465
|
+
...input.archiveMetadata,
|
|
319466
|
+
measurementBandsBps
|
|
319467
|
+
};
|
|
319468
|
+
const completeRawCapture = createRawCapture(context2, {
|
|
319323
319469
|
payload: input.snapshot,
|
|
319324
319470
|
eventTimeMs: input.snapshot.timestamp,
|
|
319325
319471
|
receivedTimeMs: input.snapshot.receivedTimestamp,
|
|
@@ -319328,10 +319474,29 @@ function archiveOrderbookInBackground(archiver, otelMetrics, input, options) {
|
|
|
319328
319474
|
const canonical = buildCanonicalOrderBookRows({
|
|
319329
319475
|
context: context2,
|
|
319330
319476
|
snapshot: input.snapshot,
|
|
319331
|
-
rawCapture,
|
|
319332
|
-
depthLimit
|
|
319477
|
+
rawCapture: completeRawCapture,
|
|
319478
|
+
depthLimit,
|
|
319479
|
+
archiveMetadata
|
|
319333
319480
|
});
|
|
319334
|
-
|
|
319481
|
+
const rawMetadata = {
|
|
319482
|
+
capture_profile_id: archiveMetadata.captureProfileId,
|
|
319483
|
+
effective_cadence_ms: archiveMetadata.effectiveCadenceMs,
|
|
319484
|
+
requested_upstream_depth: archiveMetadata.requestedUpstreamDepth,
|
|
319485
|
+
archive_depth_limit: depthLimit,
|
|
319486
|
+
observed_bid_count: archiveMetadata.observedBidCount,
|
|
319487
|
+
observed_ask_count: archiveMetadata.observedAskCount,
|
|
319488
|
+
observed_farthest_bid: canonicalDecimal(archiveMetadata.observedFarthestBid),
|
|
319489
|
+
observed_farthest_ask: canonicalDecimal(archiveMetadata.observedFarthestAsk),
|
|
319490
|
+
bid_exhausted: archiveMetadata.exhaustionEvidence.bid.exhausted,
|
|
319491
|
+
ask_exhausted: archiveMetadata.exhaustionEvidence.ask.exhausted,
|
|
319492
|
+
retained_bid_count: canonical.levels.filter(({ row }) => row.side === "bid").length,
|
|
319493
|
+
retained_ask_count: canonical.levels.filter(({ row }) => row.side === "ask").length,
|
|
319494
|
+
measurement_bands_bps: measurementBandsBps
|
|
319495
|
+
};
|
|
319496
|
+
const storedRawCapture = projectRawCapturePayload(completeRawCapture, rawMetadata);
|
|
319497
|
+
archiver.enqueue(buildCanonicalCexStreamEventRow(context2, storedRawCapture, {
|
|
319498
|
+
payloadEncoding: "orderbook_metadata_only_v1"
|
|
319499
|
+
}));
|
|
319335
319500
|
for (const row of canonical.levels)
|
|
319336
319501
|
archiver.enqueue(row);
|
|
319337
319502
|
archiver.enqueue(canonical.summary);
|
|
@@ -319453,6 +319618,9 @@ function archiveTickerInBackground(archiver, otelMetrics, input) {
|
|
|
319453
319618
|
});
|
|
319454
319619
|
}
|
|
319455
319620
|
function archiveCexStreamEventInBackground(archiver, otelMetrics, input) {
|
|
319621
|
+
if (input.streamType === "ORDERBOOK") {
|
|
319622
|
+
throw new Error("Generic ORDERBOOK archive events are unsupported; use archiveOrderbookInBackground");
|
|
319623
|
+
}
|
|
319456
319624
|
archiveMarketRowsInBackground(archiver, otelMetrics, "stream", input, input.streamType, () => [
|
|
319457
319625
|
buildCexStreamEventRow({
|
|
319458
319626
|
...input,
|
|
@@ -319477,6 +319645,82 @@ function resolveOhlcvBootstrapLimit(optionValue) {
|
|
|
319477
319645
|
}
|
|
319478
319646
|
return Math.min(parsed, MAX_OHLCV_BOOTSTRAP_LIMIT);
|
|
319479
319647
|
}
|
|
319648
|
+
// src/helpers/market-data-archive/summary-v2-conformance.ts
|
|
319649
|
+
var ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELDS = [
|
|
319650
|
+
["source", "String", false],
|
|
319651
|
+
["deployment_id", "String", false],
|
|
319652
|
+
["capture_bundle_id", "String", false],
|
|
319653
|
+
["exchange", "String", false],
|
|
319654
|
+
["symbol", "String", false],
|
|
319655
|
+
["trading_pair", "String", false],
|
|
319656
|
+
["source_symbol", "String", false],
|
|
319657
|
+
["asset_type", "String", false],
|
|
319658
|
+
["feed", "String", false],
|
|
319659
|
+
["provider", "String", false],
|
|
319660
|
+
["source_mode", "String", false],
|
|
319661
|
+
["source_time_ms", "UInt64", false],
|
|
319662
|
+
["received_time_ms", "UInt64", false],
|
|
319663
|
+
["raw_capture_id", "String", false],
|
|
319664
|
+
["raw_capture_scope", "String", false],
|
|
319665
|
+
["schema_version", "String", false],
|
|
319666
|
+
["checksum_algorithm", "String", false],
|
|
319667
|
+
["raw_checksum", "String", false],
|
|
319668
|
+
["provenance_complete", "UInt8", false],
|
|
319669
|
+
["snapshot_id", "String", false],
|
|
319670
|
+
["construction_mode", "String", false],
|
|
319671
|
+
["gap_policy", "String", false],
|
|
319672
|
+
["depth_limit", "UInt16", false],
|
|
319673
|
+
["sequence", "UInt64", true],
|
|
319674
|
+
["exact_l2_reconstruction_complete", "UInt8", false],
|
|
319675
|
+
["capture_profile_id", "String", false],
|
|
319676
|
+
["effective_cadence_ms", "UInt32", false],
|
|
319677
|
+
["requested_upstream_depth", "UInt16", true],
|
|
319678
|
+
["observed_bid_count", "UInt32", false],
|
|
319679
|
+
["observed_ask_count", "UInt32", false],
|
|
319680
|
+
["observed_farthest_bid", "Decimal(38,18)", false],
|
|
319681
|
+
["observed_farthest_ask", "Decimal(38,18)", false],
|
|
319682
|
+
["retained_farthest_bid", "Decimal(38,18)", false],
|
|
319683
|
+
["retained_farthest_ask", "Decimal(38,18)", false],
|
|
319684
|
+
["bid_exhausted", "UInt8", false],
|
|
319685
|
+
["ask_exhausted", "UInt8", false],
|
|
319686
|
+
["best_bid", "Decimal(38,18)", false],
|
|
319687
|
+
["best_ask", "Decimal(38,18)", false],
|
|
319688
|
+
["best_bid_amount", "Decimal(38,18)", false],
|
|
319689
|
+
["best_ask_amount", "Decimal(38,18)", false],
|
|
319690
|
+
["mid_price", "Decimal(38,18)", false],
|
|
319691
|
+
["spread", "Decimal(38,18)", false],
|
|
319692
|
+
["spread_bps", "Float64", false],
|
|
319693
|
+
["staleness_ms", "UInt64", false],
|
|
319694
|
+
["bid_level_count", "UInt16", false],
|
|
319695
|
+
["ask_level_count", "UInt16", false],
|
|
319696
|
+
["measurement_bands_bps", "Array(UInt32)", false],
|
|
319697
|
+
["bid_boundary_price_by_band", "Array(Decimal(38,18))", false],
|
|
319698
|
+
["ask_boundary_price_by_band", "Array(Decimal(38,18))", false],
|
|
319699
|
+
["bid_depth_by_band", "Array(Decimal(38,18))", false],
|
|
319700
|
+
["ask_depth_by_band", "Array(Decimal(38,18))", false],
|
|
319701
|
+
["bid_status_by_band", "Array(Enum8('exact'=1,'censored'=2))", false],
|
|
319702
|
+
["ask_status_by_band", "Array(Enum8('exact'=1,'censored'=2))", false],
|
|
319703
|
+
["normalized_row_checksum", "String", false]
|
|
319704
|
+
];
|
|
319705
|
+
var ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELD_NAMES = ORDERBOOK_SUMMARY_V2_SUPPORTED_VIEW_FIELDS.map(([name]) => name);
|
|
319706
|
+
var DECIMAL_38_18_FIELDS = new Set([
|
|
319707
|
+
"observed_farthest_bid",
|
|
319708
|
+
"observed_farthest_ask",
|
|
319709
|
+
"retained_farthest_bid",
|
|
319710
|
+
"retained_farthest_ask",
|
|
319711
|
+
"best_bid",
|
|
319712
|
+
"best_ask",
|
|
319713
|
+
"best_bid_amount",
|
|
319714
|
+
"best_ask_amount",
|
|
319715
|
+
"mid_price",
|
|
319716
|
+
"spread"
|
|
319717
|
+
]);
|
|
319718
|
+
var DECIMAL_38_18_ARRAY_FIELDS = new Set([
|
|
319719
|
+
"bid_boundary_price_by_band",
|
|
319720
|
+
"ask_boundary_price_by_band",
|
|
319721
|
+
"bid_depth_by_band",
|
|
319722
|
+
"ask_depth_by_band"
|
|
319723
|
+
]);
|
|
319480
319724
|
// src/helpers/order-book.ts
|
|
319481
319725
|
var ORDER_BOOK_CALL_METHODS = {
|
|
319482
319726
|
FETCH_CAPABILITY: "fetch_order_book_capability",
|
|
@@ -319828,7 +320072,7 @@ class PublicFeedWorker {
|
|
|
319828
320072
|
if (this.options.profile) {
|
|
319829
320073
|
this.options.metrics?.recordCounter("public_feed_acquisition_profiles_total", 1, {
|
|
319830
320074
|
...this.#metricLabels(),
|
|
319831
|
-
|
|
320075
|
+
profile_class: this.options.profile.coalescingSupported ? "coalesced" : "conservative"
|
|
319832
320076
|
});
|
|
319833
320077
|
}
|
|
319834
320078
|
this.#run = this.#watchLoop();
|
|
@@ -319896,7 +320140,34 @@ class PublicFeedWorker {
|
|
|
319896
320140
|
depthLimit: retainedDepth,
|
|
319897
320141
|
receivedTimestamp
|
|
319898
320142
|
});
|
|
319899
|
-
|
|
320143
|
+
const observedBidCount = snapshot.bids.length;
|
|
320144
|
+
const observedAskCount = snapshot.asks.length;
|
|
320145
|
+
this.options.archiveSink.orderbook({
|
|
320146
|
+
...context2,
|
|
320147
|
+
snapshot,
|
|
320148
|
+
archiveMetadata: {
|
|
320149
|
+
captureProfileId: this.options.profile?.id ?? `${this.options.exchangeName}:conservative:default`,
|
|
320150
|
+
effectiveCadenceMs: getOrderbookIntervalMs(),
|
|
320151
|
+
requestedUpstreamDepth: this.options.profile?.upstreamLimit ?? null,
|
|
320152
|
+
observedBidCount,
|
|
320153
|
+
observedAskCount,
|
|
320154
|
+
observedFarthestBid: snapshot.bids.at(-1)?.[0] ?? Number.NaN,
|
|
320155
|
+
observedFarthestAsk: snapshot.asks.at(-1)?.[0] ?? Number.NaN,
|
|
320156
|
+
exhaustionEvidence: {
|
|
320157
|
+
bid: {
|
|
320158
|
+
exhausted: this.options.profile?.bidExhaustionEvidence ?? false,
|
|
320159
|
+
validated: this.options.profile?.exhaustionEvidenceValidated ?? true,
|
|
320160
|
+
source: this.options.profile?.id ?? "broker:conservative"
|
|
320161
|
+
},
|
|
320162
|
+
ask: {
|
|
320163
|
+
exhausted: this.options.profile?.askExhaustionEvidence ?? false,
|
|
320164
|
+
validated: this.options.profile?.exhaustionEvidenceValidated ?? true,
|
|
320165
|
+
source: this.options.profile?.id ?? "broker:conservative"
|
|
320166
|
+
}
|
|
320167
|
+
},
|
|
320168
|
+
measurementBandsBps: getOrderbookMeasurementBandsBps()
|
|
320169
|
+
}
|
|
320170
|
+
}, { sampledOut: !this.#sampler.shouldEmit(receivedTimestamp) });
|
|
319900
320171
|
this.#recordCounter("public_feed_archive_decisions_total");
|
|
319901
320172
|
this.options.observer?.archiveDecision?.(this.#observation());
|
|
319902
320173
|
this.#fanout((subscriber) => this.#frame(projectOrderBookSnapshot(snapshot, subscriber.depthLimit), receivedTimestamp));
|
|
@@ -320069,7 +320340,7 @@ class PublicFeedWorker {
|
|
|
320069
320340
|
}
|
|
320070
320341
|
#metricLabels() {
|
|
320071
320342
|
return {
|
|
320072
|
-
|
|
320343
|
+
exchange_bucket: this.options.exchangeOwned ? "dynamic" : "configured",
|
|
320073
320344
|
feed: this.options.feed,
|
|
320074
320345
|
market_type: this.options.marketType
|
|
320075
320346
|
};
|
|
@@ -335436,7 +335707,29 @@ async function handleOrderBookCall(ctx) {
|
|
|
335436
335707
|
assetType: "spot",
|
|
335437
335708
|
accountSelector: ctx.selectedBrokerAccount?.label,
|
|
335438
335709
|
deploymentId: ctx.brokerArchiver?.getDeploymentId() ?? "unarchived",
|
|
335439
|
-
snapshot
|
|
335710
|
+
snapshot,
|
|
335711
|
+
archiveMetadata: {
|
|
335712
|
+
captureProfileId: `${orderBookPayload.exchange.trim().toLowerCase()}:current-snapshot:requested:${orderBookPayload.depthLimit}`,
|
|
335713
|
+
effectiveCadenceMs: 1,
|
|
335714
|
+
requestedUpstreamDepth: orderBookPayload.depthLimit,
|
|
335715
|
+
observedBidCount: snapshot.bids.length,
|
|
335716
|
+
observedAskCount: snapshot.asks.length,
|
|
335717
|
+
observedFarthestBid: snapshot.bids.at(-1)?.[0] ?? Number.NaN,
|
|
335718
|
+
observedFarthestAsk: snapshot.asks.at(-1)?.[0] ?? Number.NaN,
|
|
335719
|
+
exhaustionEvidence: {
|
|
335720
|
+
bid: {
|
|
335721
|
+
exhausted: false,
|
|
335722
|
+
validated: true,
|
|
335723
|
+
source: "broker:current-snapshot"
|
|
335724
|
+
},
|
|
335725
|
+
ask: {
|
|
335726
|
+
exhausted: false,
|
|
335727
|
+
validated: true,
|
|
335728
|
+
source: "broker:current-snapshot"
|
|
335729
|
+
}
|
|
335730
|
+
},
|
|
335731
|
+
measurementBandsBps: getOrderbookMeasurementBandsBps()
|
|
335732
|
+
}
|
|
335440
335733
|
}, {
|
|
335441
335734
|
sourceMode: "broker_current_snapshot_v1",
|
|
335442
335735
|
depthLimit: orderBookPayload.depthLimit
|