Add equity print quote joins
This commit is contained in:
parent
9908c431f0
commit
3164167bee
15 changed files with 1033 additions and 7 deletions
104
services/compute/src/equity-joins.ts
Normal file
104
services/compute/src/equity-joins.ts
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import type { EquityPrint, EquityPrintJoin, EquityQuote } from "@islandflow/types";
|
||||
|
||||
export type EquityQuoteJoin = {
|
||||
quote: EquityQuote | null;
|
||||
ageMs: number;
|
||||
stale: boolean;
|
||||
};
|
||||
|
||||
export type QuotePlacement = "AA" | "A" | "B" | "BB" | "MID" | "MISSING" | "STALE";
|
||||
|
||||
const roundTo = (value: number, digits = 4): number => {
|
||||
if (!Number.isFinite(value)) {
|
||||
return 0;
|
||||
}
|
||||
return Number(value.toFixed(digits));
|
||||
};
|
||||
|
||||
export const classifyQuotePlacement = (
|
||||
price: number,
|
||||
join: EquityQuoteJoin
|
||||
): QuotePlacement => {
|
||||
if (!Number.isFinite(price)) {
|
||||
return "MISSING";
|
||||
}
|
||||
if (!join.quote) {
|
||||
return "MISSING";
|
||||
}
|
||||
if (join.stale) {
|
||||
return "STALE";
|
||||
}
|
||||
|
||||
const bid = join.quote.bid;
|
||||
const ask = join.quote.ask;
|
||||
if (!Number.isFinite(bid) || !Number.isFinite(ask) || ask <= 0) {
|
||||
return "MISSING";
|
||||
}
|
||||
|
||||
const spread = Math.max(0, ask - bid);
|
||||
const epsilon = Math.max(0.01, spread * 0.05);
|
||||
|
||||
if (price > ask + epsilon) {
|
||||
return "AA";
|
||||
}
|
||||
if (price >= ask - epsilon) {
|
||||
return "A";
|
||||
}
|
||||
if (price < bid - epsilon) {
|
||||
return "BB";
|
||||
}
|
||||
if (price <= bid + epsilon) {
|
||||
return "B";
|
||||
}
|
||||
|
||||
return "MID";
|
||||
};
|
||||
|
||||
export const buildEquityPrintJoin = (
|
||||
print: EquityPrint,
|
||||
join: EquityQuoteJoin
|
||||
): EquityPrintJoin => {
|
||||
const joinQuality: Record<string, number> = {};
|
||||
const placement = classifyQuotePlacement(print.price, join);
|
||||
const features: Record<string, string | number | boolean> = {
|
||||
underlying_id: print.underlying_id,
|
||||
price: print.price,
|
||||
size: print.size,
|
||||
off_exchange_flag: print.offExchangeFlag,
|
||||
print_ts: print.ts,
|
||||
quote_placement: placement
|
||||
};
|
||||
|
||||
if (!join.quote) {
|
||||
joinQuality.quote_missing = 1;
|
||||
} else {
|
||||
joinQuality.quote_age_ms = join.ageMs;
|
||||
if (join.stale) {
|
||||
joinQuality.quote_stale = 1;
|
||||
} else {
|
||||
const bid = join.quote.bid;
|
||||
const ask = join.quote.ask;
|
||||
const mid = (bid + ask) / 2;
|
||||
const spread = ask - bid;
|
||||
features.quote_ts = join.quote.ts;
|
||||
features.quote_bid = bid;
|
||||
features.quote_ask = ask;
|
||||
features.quote_mid = roundTo(mid);
|
||||
features.quote_spread = roundTo(spread);
|
||||
}
|
||||
}
|
||||
|
||||
const joinId = `equityjoin:${print.trace_id}`;
|
||||
|
||||
return {
|
||||
source_ts: print.source_ts,
|
||||
ingest_ts: print.ingest_ts,
|
||||
seq: print.seq,
|
||||
trace_id: joinId,
|
||||
id: joinId,
|
||||
print_trace_id: print.trace_id,
|
||||
quote_trace_id: join.quote?.trace_id ?? "",
|
||||
features,
|
||||
join_quality: joinQuality
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue