Add equities prints range endpoint

Adds GET /prints/equities/range for fetching underlying-scoped equity prints over a requested time window, used by chart overlays.
This commit is contained in:
dirtydishes 2026-01-20 11:05:40 -05:00
parent 7fc9f5cf66
commit 52f7ad82c6

View file

@ -51,6 +51,7 @@ import {
fetchEquityCandlesRange, fetchEquityCandlesRange,
fetchRecentOptionNBBO, fetchRecentOptionNBBO,
fetchEquityPrintsAfter, fetchEquityPrintsAfter,
fetchEquityPrintsRange,
fetchEquityPrintJoinsAfter, fetchEquityPrintJoinsAfter,
fetchEquityQuotesAfter, fetchEquityQuotesAfter,
fetchInferredDarkAfter, fetchInferredDarkAfter,
@ -143,6 +144,13 @@ const candleReplaySchema = replayParamsSchema.extend({
interval_ms: z.coerce.number().int().positive() interval_ms: z.coerce.number().int().positive()
}); });
const equityPrintRangeSchema = z.object({
underlying_id: z.string().min(1),
start_ts: z.coerce.number().int().nonnegative(),
end_ts: z.coerce.number().int().nonnegative(),
limit: limitSchema.optional()
});
type Channel = type Channel =
| "options" | "options"
| "options-nbbo" | "options-nbbo"
@ -223,6 +231,24 @@ const parseBooleanParam = (value: string | null | undefined): boolean => {
return ["1", "true", "yes", "on"].includes(normalized); return ["1", "true", "yes", "on"].includes(normalized);
}; };
const parseEquityPrintRangeParams = (
url: URL
): { underlyingId: string; startTs: number; endTs: number; limit: number } => {
const params = equityPrintRangeSchema.parse({
underlying_id: url.searchParams.get("underlying_id") ?? undefined,
start_ts: url.searchParams.get("start_ts") ?? undefined,
end_ts: url.searchParams.get("end_ts") ?? undefined,
limit: url.searchParams.get("limit") ?? undefined
});
return {
underlyingId: params.underlying_id,
startTs: params.start_ts,
endTs: params.end_ts,
limit: params.limit ?? env.REST_DEFAULT_LIMIT
};
};
const parseCandleParams = ( const parseCandleParams = (
url: URL url: URL
): { ): {
@ -796,6 +822,22 @@ const run = async () => {
return jsonResponse({ data }); return jsonResponse({ data });
} }
if (req.method === "GET" && url.pathname === "/prints/equities/range") {
try {
const { underlyingId, startTs, endTs, limit } = parseEquityPrintRangeParams(url);
const data = await fetchEquityPrintsRange(clickhouse, underlyingId, startTs, endTs, limit);
return jsonResponse({ data });
} catch (error) {
return jsonResponse(
{
error: "invalid equity range query",
detail: error instanceof Error ? error.message : String(error)
},
400
);
}
}
if (req.method === "GET" && url.pathname === "/quotes/equities") { if (req.method === "GET" && url.pathname === "/quotes/equities") {
const limit = parseLimit(url.searchParams.get("limit")); const limit = parseLimit(url.searchParams.get("limit"));
const data = await fetchRecentEquityQuotes(clickhouse, limit); const data = await fetchRecentEquityQuotes(clickhouse, limit);