Fix contract-focused options tape hydration
This commit is contained in:
parent
73e25ddf70
commit
b73e62bdba
8 changed files with 657 additions and 171 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { describe, expect, it } from "bun:test";
|
||||
import type { ClickHouseClient } from "@islandflow/storage";
|
||||
import {
|
||||
buildOptionSnapshotFilters,
|
||||
HOT_LIVE_REDIS_KEYS,
|
||||
LiveStateManager,
|
||||
isLiveItemFresh,
|
||||
|
|
@ -450,6 +451,74 @@ describe("LiveStateManager", () => {
|
|||
expect(isLiveItemFresh("options", snapshot.items[0], now)).toBe(false);
|
||||
});
|
||||
|
||||
it("builds raw contract-only snapshot filters for focused option subscriptions", () => {
|
||||
expect(
|
||||
buildOptionSnapshotFilters({
|
||||
channel: "options",
|
||||
filters: {
|
||||
view: "signal",
|
||||
minNotional: 500_000,
|
||||
nbboSides: ["A"],
|
||||
optionTypes: ["call"],
|
||||
securityTypes: ["stock"]
|
||||
},
|
||||
underlying_ids: ["AAPL"],
|
||||
option_contract_id: "AAPL-2025-01-17-200-C"
|
||||
})
|
||||
).toEqual({
|
||||
view: "raw",
|
||||
optionContractId: "AAPL-2025-01-17-200-C"
|
||||
});
|
||||
});
|
||||
|
||||
it("returns raw contract rows for focused option snapshots even when broad filters would reject them", async () => {
|
||||
const manager = new LiveStateManager(
|
||||
makeClickHouse((query) => {
|
||||
expect(query).toContain("option_contract_id = 'AAPL-2025-01-17-200-C'");
|
||||
expect(query).not.toContain("signal_pass = 1");
|
||||
expect(query).not.toContain("notional >=");
|
||||
expect(query).not.toContain("nbbo_side IN");
|
||||
expect(query).not.toContain("option_type IN");
|
||||
return [
|
||||
{
|
||||
source_ts: 1_000,
|
||||
ingest_ts: 1_001,
|
||||
seq: 1,
|
||||
trace_id: "opt-raw",
|
||||
ts: 1_000,
|
||||
option_contract_id: "AAPL-2025-01-17-200-C",
|
||||
underlying_id: "AAPL",
|
||||
option_type: "put",
|
||||
nbbo_side: "B",
|
||||
notional: 50_000,
|
||||
signal_pass: false,
|
||||
price: 1,
|
||||
size: 5,
|
||||
exchange: "X"
|
||||
}
|
||||
];
|
||||
}),
|
||||
null
|
||||
);
|
||||
|
||||
const snapshot = await manager.getSnapshot({
|
||||
channel: "options",
|
||||
filters: {
|
||||
view: "signal",
|
||||
minNotional: 500_000,
|
||||
nbboSides: ["A"],
|
||||
optionTypes: ["call"],
|
||||
securityTypes: ["stock"]
|
||||
},
|
||||
underlying_ids: ["AAPL"],
|
||||
option_contract_id: "AAPL-2025-01-17-200-C"
|
||||
});
|
||||
|
||||
expect((snapshot.items as Array<{ trace_id: string }>).map((item) => item.trace_id)).toEqual([
|
||||
"opt-raw"
|
||||
]);
|
||||
});
|
||||
|
||||
it("seeds scoped equity snapshots from clickhouse rows older than 24h", async () => {
|
||||
const now = Date.now();
|
||||
const staleTs = now - 25 * 60 * 60 * 1000;
|
||||
|
|
|
|||
59
services/api/tests/option-queries.test.ts
Normal file
59
services/api/tests/option-queries.test.ts
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import { describe, expect, it } from "bun:test";
|
||||
import { parseOptionPrintQuery } from "../src/option-queries";
|
||||
|
||||
describe("parseOptionPrintQuery", () => {
|
||||
it("keeps broad option flow filters for non-contract requests", () => {
|
||||
const url = new URL(
|
||||
"http://localhost/prints/options?view=signal&security=stock&side=A&type=call&min_notional=500000&underlying_ids=AAPL,MSFT"
|
||||
);
|
||||
|
||||
expect(parseOptionPrintQuery(url)).toEqual({
|
||||
scope: {
|
||||
underlyingIds: ["AAPL", "MSFT"],
|
||||
optionContractId: undefined
|
||||
},
|
||||
flowFilters: {
|
||||
view: "signal",
|
||||
securityTypes: ["stock"],
|
||||
nbboSides: ["A"],
|
||||
optionTypes: ["call"],
|
||||
minNotional: 500000
|
||||
},
|
||||
storageFilters: {
|
||||
view: "signal",
|
||||
security: "stock",
|
||||
nbboSides: ["A"],
|
||||
optionTypes: ["call"],
|
||||
minNotional: 500000,
|
||||
underlyingIds: ["AAPL", "MSFT"],
|
||||
optionContractId: undefined
|
||||
},
|
||||
isContractDrilldown: false
|
||||
});
|
||||
});
|
||||
|
||||
it("switches contract requests to raw contract-only storage filters", () => {
|
||||
const url = new URL(
|
||||
"http://localhost/replay/options?view=signal&security=stock&side=A&type=call&min_notional=500000&underlying_id=AAPL&option_contract_id=AAPL-2025-01-17-200-C"
|
||||
);
|
||||
|
||||
expect(parseOptionPrintQuery(url)).toEqual({
|
||||
scope: {
|
||||
underlyingIds: ["AAPL"],
|
||||
optionContractId: "AAPL-2025-01-17-200-C"
|
||||
},
|
||||
flowFilters: {
|
||||
view: "signal",
|
||||
securityTypes: ["stock"],
|
||||
nbboSides: ["A"],
|
||||
optionTypes: ["call"],
|
||||
minNotional: 500000
|
||||
},
|
||||
storageFilters: {
|
||||
view: "raw",
|
||||
optionContractId: "AAPL-2025-01-17-200-C"
|
||||
},
|
||||
isContractDrilldown: true
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue