expand ci quality gates
All checks were successful
CI / Validate (push) Successful in 1m13s

This commit is contained in:
dirtydishes 2026-05-30 02:34:28 -04:00
parent 65139bf8d0
commit 44431c4e66
71 changed files with 2262 additions and 1173 deletions

View file

@ -85,10 +85,14 @@ const decodePayload = (data: WebSocket.RawData): unknown => {
}
if (ArrayBuffer.isView(data)) {
return JSON.parse(new TextDecoder().decode(new Uint8Array(data.buffer, data.byteOffset, data.byteLength))) as unknown;
return JSON.parse(
new TextDecoder().decode(new Uint8Array(data.buffer, data.byteOffset, data.byteLength))
) as unknown;
}
return JSON.parse(new TextDecoder().decode(new Uint8Array(data as unknown as ArrayBuffer))) as unknown;
return JSON.parse(
new TextDecoder().decode(new Uint8Array(data as unknown as ArrayBuffer))
) as unknown;
};
const extractExchangeMeta = (payload: unknown): AlpacaExchangeMetaEntry[] => {
@ -103,8 +107,18 @@ const extractExchangeMeta = (payload: unknown): AlpacaExchangeMetaEntry[] => {
continue;
}
const candidate = entry as Record<string, unknown>;
const code = typeof candidate.code === "string" ? candidate.code : typeof candidate.exchange === "string" ? candidate.exchange : null;
const name = typeof candidate.name === "string" ? candidate.name : typeof candidate.description === "string" ? candidate.description : null;
const code =
typeof candidate.code === "string"
? candidate.code
: typeof candidate.exchange === "string"
? candidate.exchange
: null;
const name =
typeof candidate.name === "string"
? candidate.name
: typeof candidate.description === "string"
? candidate.description
: null;
if (!code || !name) {
continue;
}
@ -128,9 +142,19 @@ const buildExchangeNameMap = (entries: AlpacaExchangeMetaEntry[]): Map<string, s
return map;
};
const OFF_EXCHANGE_HINTS = ["FINRA", "TRF", "ADF", "OTC", "Trade Reporting Facility", "Alternative Display Facility"];
const OFF_EXCHANGE_HINTS = [
"FINRA",
"TRF",
"ADF",
"OTC",
"Trade Reporting Facility",
"Alternative Display Facility"
];
export const inferOffExchangeFlag = (exchangeCode: string | undefined, exchangeNameMap: Map<string, string>): boolean => {
export const inferOffExchangeFlag = (
exchangeCode: string | undefined,
exchangeNameMap: Map<string, string>
): boolean => {
if (!exchangeCode) {
return false;
}
@ -151,7 +175,9 @@ const buildWsUrl = (wsBaseUrl: string, feed: AlpacaEquitiesFeed): string => {
return `${parsed.origin}/v2/${feed}`;
};
const fetchExchangeMeta = async (config: AlpacaEquitiesAdapterConfig): Promise<Map<string, string>> => {
const fetchExchangeMeta = async (
config: AlpacaEquitiesAdapterConfig
): Promise<Map<string, string>> => {
const url = new URL("/v2/stocks/meta/exchanges", config.restUrl);
try {
@ -243,7 +269,10 @@ export const createAlpacaEquitiesAdapter = (
continue;
}
const message = entry as (AlpacaTradeMessage | AlpacaQuoteMessage | { T?: string; msg?: string });
const message = entry as
| AlpacaTradeMessage
| AlpacaQuoteMessage
| { T?: string; msg?: string };
const type = message.T;
if (type === "success") {

View file

@ -89,11 +89,7 @@ const priceForPlacement = (
return formatPrice(Math.max(0.01, price));
};
const buildQuoteContext = (
symbol: string,
now: number,
control: SyntheticControlState
) => {
const buildQuoteContext = (symbol: string, now: number, control: SyntheticControlState) => {
const session = getSyntheticSessionState(now, control);
const state = getSyntheticUnderlyingState(symbol, now, control, session);
return {
@ -184,7 +180,9 @@ export const createSyntheticEquitiesAdapter = (
session.regime === "retail_chase";
if (allowDark) {
const darkSymbol = focusSymbols[seq % focusSymbols.length] ?? SYNTHETIC_SYMBOLS[symbolCursor % SYNTHETIC_SYMBOLS.length]!;
const darkSymbol =
focusSymbols[seq % focusSymbols.length] ??
SYNTHETIC_SYMBOLS[symbolCursor % SYNTHETIC_SYMBOLS.length]!;
const darkQuote = buildQuoteContext(darkSymbol, now, control);
const darkPlacement = pickDarkPlacement(
darkQuote.state.driftBps,
@ -203,13 +201,7 @@ export const createSyntheticEquitiesAdapter = (
if (handlers.onQuote) {
quoteSeq += 1;
void handlers.onQuote(
buildSyntheticQuote(
quoteSeq,
now - 2,
darkSymbol,
darkQuote.bid,
darkQuote.ask
)
buildSyntheticQuote(quoteSeq, now - 2, darkSymbol, darkQuote.bid, darkQuote.ask)
);
}
@ -236,11 +228,7 @@ export const createSyntheticEquitiesAdapter = (
const eventTs = now + i * 4;
const quote = buildQuoteContext(symbol, eventTs, control);
const clustered = focusSet.has(symbol);
const placement = pickPrimaryPlacement(
quote.state.driftBps,
session.regime,
seq + i
);
const placement = pickPrimaryPlacement(quote.state.driftBps, session.regime, seq + i);
const exchange = EXCHANGES[(seq + symbol.charCodeAt(0) + i) % EXCHANGES.length]!;
const baseSize =
throughput.litSizeBase +
@ -255,13 +243,7 @@ export const createSyntheticEquitiesAdapter = (
if (handlers.onQuote) {
quoteSeq += 1;
void handlers.onQuote(
buildSyntheticQuote(
quoteSeq,
eventTs - 2,
symbol,
quote.bid,
quote.ask
)
buildSyntheticQuote(quoteSeq, eventTs - 2, symbol, quote.bid, quote.ask)
);
}

View file

@ -240,10 +240,7 @@ const run = async () => {
await ensureEquityQuotesTable(clickhouse);
});
const adapter = selectAdapter(
env.EQUITIES_INGEST_ADAPTER,
() => syntheticControl
);
const adapter = selectAdapter(env.EQUITIES_INGEST_ADAPTER, () => syntheticControl);
logger.info("ingest adapter selected", { adapter: adapter.name });
const allowPublish = buildThrottle(env.TESTING_MODE, env.TESTING_THROTTLE_MS);
const allowQuotePublish = buildThrottle(env.TESTING_MODE, env.TESTING_THROTTLE_MS);