total ui refactor
total ui refactor, deslopification, tuning, mildly bbg-inspired if u squint
This commit is contained in:
commit
b3c63a19d0
15 changed files with 5722 additions and 4655 deletions
|
|
@ -192,6 +192,31 @@ const roundTo = (value: number, digits = 4): number => {
|
|||
return Number(value.toFixed(digits));
|
||||
};
|
||||
|
||||
const getErrorCode = (error: unknown): string | null => {
|
||||
if (error && typeof error === "object" && "code" in error) {
|
||||
const code = (error as { code?: unknown }).code;
|
||||
if (typeof code === "string" && code.length > 0) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
if (error instanceof Error) {
|
||||
const match = error.message.match(/\bCONNECTION_(?:DRAINING|CLOSED)\b/);
|
||||
if (match?.[0]) {
|
||||
return match[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof error === "string") {
|
||||
const match = error.match(/\bCONNECTION_(?:DRAINING|CLOSED)\b/);
|
||||
if (match?.[0]) {
|
||||
return match[0];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
type NbboPlacement = "AA" | "A" | "B" | "BB" | "MID" | "MISSING" | "STALE";
|
||||
|
||||
type NbboPlacementCounts = {
|
||||
|
|
@ -217,6 +242,7 @@ type ClusterState = {
|
|||
firstPrice: number;
|
||||
lastPrice: number;
|
||||
placements: NbboPlacementCounts;
|
||||
flushed: boolean;
|
||||
};
|
||||
|
||||
const clusters = new Map<string, ClusterState>();
|
||||
|
|
@ -226,6 +252,10 @@ const darkInferenceState = createDarkInferenceState();
|
|||
const recentLegsByKey = new Map<string, LegEvidence[]>();
|
||||
const recentLegsByRoot = new Map<string, LegEvidence[]>();
|
||||
const recentStructureEmits = new Map<string, number>();
|
||||
const runtimeState = {
|
||||
shuttingDown: false,
|
||||
shutdownPromise: null as Promise<void> | null
|
||||
};
|
||||
|
||||
const MAX_RECENT_LEGS = 20;
|
||||
|
||||
|
|
@ -233,6 +263,15 @@ const rollingKey = (metric: string, contractId: string): string => {
|
|||
return `rolling:${metric}:${contractId}`;
|
||||
};
|
||||
|
||||
const buildPacketId = (cluster: ClusterState): string => {
|
||||
return `flowpacket:${cluster.contractId}:${cluster.startTs}:${cluster.endTs}`;
|
||||
};
|
||||
|
||||
const isExpectedShutdownNatsError = (error: unknown): boolean => {
|
||||
const code = getErrorCode(error);
|
||||
return runtimeState.shuttingDown && (code === "CONNECTION_DRAINING" || code === "CONNECTION_CLOSED");
|
||||
};
|
||||
|
||||
const createPlacementCounts = (): NbboPlacementCounts => ({
|
||||
aa: 0,
|
||||
a: 0,
|
||||
|
|
@ -501,7 +540,8 @@ const buildCluster = (print: OptionPrint): ClusterState => {
|
|||
totalPremium: print.price * print.size,
|
||||
firstPrice: print.price,
|
||||
lastPrice: print.price,
|
||||
placements
|
||||
placements,
|
||||
flushed: false
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -613,8 +653,14 @@ const flushCluster = async (
|
|||
rollingConfig: RollingStatsConfig,
|
||||
cluster: ClusterState
|
||||
): Promise<void> => {
|
||||
if (cluster.flushed) {
|
||||
return;
|
||||
}
|
||||
|
||||
cluster.flushed = true;
|
||||
const joinQuality: Record<string, number> = {};
|
||||
const nbboJoin = selectNbbo(cluster.contractId, cluster.endTs);
|
||||
const packetId = buildPacketId(cluster);
|
||||
|
||||
const totalPremium = roundTo(cluster.totalPremium);
|
||||
const totalNotional = roundTo(totalPremium * 100, 2);
|
||||
|
|
@ -777,25 +823,38 @@ const flushCluster = async (
|
|||
source_ts: cluster.startSourceTs,
|
||||
ingest_ts: cluster.endIngestTs,
|
||||
seq: cluster.endSeq,
|
||||
trace_id: `flowpacket:${cluster.contractId}:${cluster.startTs}:${cluster.endTs}`,
|
||||
id: `flowpacket:${cluster.contractId}:${cluster.startTs}:${cluster.endTs}`,
|
||||
trace_id: packetId,
|
||||
id: packetId,
|
||||
members: cluster.members,
|
||||
features,
|
||||
join_quality: joinQuality
|
||||
};
|
||||
|
||||
const validated = FlowPacketSchema.parse(packet);
|
||||
try {
|
||||
await insertFlowPacket(clickhouse, validated);
|
||||
await publishJson(js, SUBJECT_FLOW_PACKETS, validated);
|
||||
|
||||
await insertFlowPacket(clickhouse, validated);
|
||||
await publishJson(js, SUBJECT_FLOW_PACKETS, validated);
|
||||
await emitClassifiers(clickhouse, js, validated);
|
||||
|
||||
await emitClassifiers(clickhouse, js, validated);
|
||||
logger.info("emitted flow packet", {
|
||||
id: validated.id,
|
||||
contract: cluster.contractId,
|
||||
count: cluster.members.length
|
||||
});
|
||||
} catch (error) {
|
||||
if (isExpectedShutdownNatsError(error)) {
|
||||
logger.info("skipped flow packet publish during shutdown", {
|
||||
id: packetId,
|
||||
contract: cluster.contractId,
|
||||
error: getErrorCode(error) ?? (error instanceof Error ? error.message : String(error))
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("emitted flow packet", {
|
||||
id: validated.id,
|
||||
contract: cluster.contractId,
|
||||
count: cluster.members.length
|
||||
});
|
||||
cluster.flushed = false;
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
const emitClassifiers = async (
|
||||
|
|
@ -823,6 +882,9 @@ const emitClassifiers = async (
|
|||
await insertClassifierHit(clickhouse, hit);
|
||||
await publishJson(js, SUBJECT_CLASSIFIER_HITS, hit);
|
||||
} catch (error) {
|
||||
if (isExpectedShutdownNatsError(error)) {
|
||||
continue;
|
||||
}
|
||||
logger.error("failed to emit classifier hit", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
classifier_id: hit.classifier_id,
|
||||
|
|
@ -852,6 +914,9 @@ const emitClassifiers = async (
|
|||
await insertAlert(clickhouse, alert);
|
||||
await publishJson(js, SUBJECT_ALERTS, alert);
|
||||
} catch (error) {
|
||||
if (isExpectedShutdownNatsError(error)) {
|
||||
return;
|
||||
}
|
||||
logger.error("failed to emit alert", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
packet_id: packet.id
|
||||
|
|
@ -880,6 +945,9 @@ const emitEquityJoin = async (
|
|||
try {
|
||||
await publishJson(js, SUBJECT_EQUITY_JOINS, payload);
|
||||
} catch (error) {
|
||||
if (isExpectedShutdownNatsError(error)) {
|
||||
return;
|
||||
}
|
||||
logger.error("failed to publish equity print join", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
trace_id: payload.trace_id
|
||||
|
|
@ -901,6 +969,9 @@ const emitDarkInferences = async (
|
|||
await insertInferredDark(clickhouse, validated);
|
||||
await publishJson(js, SUBJECT_INFERRED_DARK, validated);
|
||||
} catch (error) {
|
||||
if (isExpectedShutdownNatsError(error)) {
|
||||
continue;
|
||||
}
|
||||
logger.error("failed to emit inferred dark event", {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
trace_id: validated.trace_id
|
||||
|
|
@ -1366,6 +1437,10 @@ const run = async () => {
|
|||
|
||||
const nbboLoop = async () => {
|
||||
for await (const msg of nbboSubscription.messages) {
|
||||
if (runtimeState.shuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const nbbo = OptionNBBOSchema.parse(nbboSubscription.decode(msg));
|
||||
updateNbboCache(nbbo);
|
||||
|
|
@ -1381,6 +1456,10 @@ const run = async () => {
|
|||
|
||||
const equityQuoteLoop = async () => {
|
||||
for await (const msg of equityQuoteSubscription.messages) {
|
||||
if (runtimeState.shuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const quote = EquityQuoteSchema.parse(equityQuoteSubscription.decode(msg));
|
||||
updateEquityQuoteCache(quote);
|
||||
|
|
@ -1396,6 +1475,10 @@ const run = async () => {
|
|||
|
||||
const equityPrintLoop = async () => {
|
||||
for await (const msg of equitySubscription.messages) {
|
||||
if (runtimeState.shuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const print = EquityPrintSchema.parse(equitySubscription.decode(msg));
|
||||
await emitEquityJoin(clickhouse, js, print);
|
||||
|
|
@ -1414,23 +1497,64 @@ const run = async () => {
|
|||
void equityPrintLoop();
|
||||
|
||||
const shutdown = async (signal: string) => {
|
||||
logger.info("service stopping", { signal });
|
||||
|
||||
for (const cluster of clusters.values()) {
|
||||
await flushCluster(clickhouse, js, redis, rollingConfig, cluster);
|
||||
if (runtimeState.shutdownPromise) {
|
||||
await runtimeState.shutdownPromise;
|
||||
return;
|
||||
}
|
||||
clusters.clear();
|
||||
|
||||
await nc.drain();
|
||||
await clickhouse.close();
|
||||
await redis.quit();
|
||||
process.exit(0);
|
||||
runtimeState.shuttingDown = true;
|
||||
runtimeState.shutdownPromise = (async () => {
|
||||
logger.info("service stopping", { signal });
|
||||
|
||||
for (const cluster of [...clusters.values()]) {
|
||||
await flushCluster(clickhouse, js, redis, rollingConfig, cluster);
|
||||
}
|
||||
clusters.clear();
|
||||
|
||||
try {
|
||||
await nc.drain();
|
||||
} catch (error) {
|
||||
if (!isExpectedShutdownNatsError(error)) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
await clickhouse.close();
|
||||
if (redis.isOpen) {
|
||||
await redis.quit();
|
||||
}
|
||||
})();
|
||||
|
||||
try {
|
||||
await runtimeState.shutdownPromise;
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
logger.error("service shutdown failed", {
|
||||
error: error instanceof Error ? error.message : String(error)
|
||||
});
|
||||
|
||||
try {
|
||||
await clickhouse.close();
|
||||
} catch {}
|
||||
|
||||
try {
|
||||
if (redis.isOpen) {
|
||||
await redis.quit();
|
||||
}
|
||||
} catch {}
|
||||
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
process.on("SIGINT", () => void shutdown("SIGINT"));
|
||||
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
||||
|
||||
for await (const msg of subscription.messages) {
|
||||
if (runtimeState.shuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const print = OptionPrintSchema.parse(subscription.decode(msg));
|
||||
await flushEligibleClusters(
|
||||
|
|
@ -1442,6 +1566,10 @@ const run = async () => {
|
|||
print.option_contract_id
|
||||
);
|
||||
|
||||
if (runtimeState.shuttingDown) {
|
||||
break;
|
||||
}
|
||||
|
||||
const existing = clusters.get(print.option_contract_id);
|
||||
if (!existing) {
|
||||
clusters.set(print.option_contract_id, buildCluster(print));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue