add alpaca news wire across ingest api and web
This commit is contained in:
parent
62aae70878
commit
906fe411c9
31 changed files with 1407 additions and 50 deletions
|
|
@ -262,3 +262,26 @@ export const InferredDarkEventSchema = EventMetaSchema.merge(
|
|||
);
|
||||
|
||||
export type InferredDarkEvent = z.infer<typeof InferredDarkEventSchema>;
|
||||
|
||||
export const NewsSymbolResolutionSchema = z.enum(["provider", "derived", "mixed", "none"]);
|
||||
|
||||
export type NewsSymbolResolution = z.infer<typeof NewsSymbolResolutionSchema>;
|
||||
|
||||
export const NewsStorySchema = EventMetaSchema.merge(
|
||||
z.object({
|
||||
story_id: z.number().int().nonnegative(),
|
||||
provider: z.string().min(1),
|
||||
source: z.string().min(1),
|
||||
headline: z.string().min(1),
|
||||
summary: z.string(),
|
||||
content_html: z.string(),
|
||||
url: z.string().url().or(z.literal("")),
|
||||
published_ts: z.number().int().nonnegative(),
|
||||
updated_ts: z.number().int().nonnegative(),
|
||||
provider_symbols: z.array(z.string().min(1)),
|
||||
resolved_symbols: z.array(z.string().min(1)),
|
||||
symbol_resolution: NewsSymbolResolutionSchema
|
||||
})
|
||||
);
|
||||
|
||||
export type NewsStory = z.infer<typeof NewsStorySchema>;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {
|
|||
EquityQuoteSchema,
|
||||
FlowPacketSchema,
|
||||
InferredDarkEventSchema,
|
||||
NewsStorySchema,
|
||||
OptionNBBOSchema,
|
||||
OptionPrintSchema,
|
||||
SmartMoneyEventSchema
|
||||
|
|
@ -34,7 +35,8 @@ export const LiveGenericChannelSchema = z.enum([
|
|||
"smart-money",
|
||||
"classifier-hits",
|
||||
"alerts",
|
||||
"inferred-dark"
|
||||
"inferred-dark",
|
||||
"news"
|
||||
]);
|
||||
|
||||
export const LiveChannelSchema = z.enum([
|
||||
|
|
@ -48,6 +50,7 @@ export const LiveChannelSchema = z.enum([
|
|||
"classifier-hits",
|
||||
"alerts",
|
||||
"inferred-dark",
|
||||
"news",
|
||||
"equity-candles",
|
||||
"equity-overlay"
|
||||
]);
|
||||
|
|
@ -91,7 +94,7 @@ export const LiveSubscriptionSchema = z.discriminatedUnion("channel", [
|
|||
snapshot_limit: z.number().int().positive().optional()
|
||||
}),
|
||||
z.object({
|
||||
channel: z.enum(["nbbo", "equity-quotes", "equity-joins", "classifier-hits", "alerts", "inferred-dark"]),
|
||||
channel: z.enum(["nbbo", "equity-quotes", "equity-joins", "classifier-hits", "alerts", "inferred-dark", "news"]),
|
||||
snapshot_limit: z.number().int().positive().optional()
|
||||
}),
|
||||
z.object({
|
||||
|
|
@ -123,6 +126,7 @@ const livePayloadSchemas = {
|
|||
"classifier-hits": ClassifierHitEventSchema,
|
||||
alerts: AlertEventSchema,
|
||||
"inferred-dark": InferredDarkEventSchema,
|
||||
news: NewsStorySchema,
|
||||
"equity-candles": EquityCandleSchema,
|
||||
"equity-overlay": EquityPrintSchema
|
||||
} as const;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import {
|
|||
describe("live protocol types", () => {
|
||||
it("builds stable keys for generic and parameterized subscriptions", () => {
|
||||
expect(getSubscriptionKey({ channel: "flow" })).toBe("flow|{}");
|
||||
expect(getSubscriptionKey({ channel: "news" })).toBe("news");
|
||||
expect(
|
||||
getSubscriptionKey({
|
||||
channel: "options",
|
||||
|
|
@ -53,12 +54,13 @@ describe("live protocol types", () => {
|
|||
op: "subscribe",
|
||||
subscriptions: [
|
||||
{ channel: "flow", filters: { nbboSides: ["AA", "A"], minNotional: 50000 } },
|
||||
{ channel: "news", snapshot_limit: 100 },
|
||||
{ channel: "equity-candles", underlying_id: "SPY", interval_ms: 60000 }
|
||||
]
|
||||
});
|
||||
|
||||
expect(parsed.op).toBe("subscribe");
|
||||
expect(parsed.subscriptions).toHaveLength(2);
|
||||
expect(parsed.subscriptions).toHaveLength(3);
|
||||
});
|
||||
|
||||
it("validates snapshot and event server messages", () => {
|
||||
|
|
@ -74,18 +76,24 @@ describe("live protocol types", () => {
|
|||
});
|
||||
const event = LiveServerMessageSchema.parse({
|
||||
op: "event",
|
||||
subscription: { channel: "equity-overlay", underlying_id: "SPY" },
|
||||
subscription: { channel: "news" },
|
||||
item: {
|
||||
source_ts: 100,
|
||||
ingest_ts: 101,
|
||||
seq: 1,
|
||||
trace_id: "eq-1",
|
||||
ts: 100,
|
||||
underlying_id: "SPY",
|
||||
price: 500,
|
||||
size: 10,
|
||||
exchange: "X",
|
||||
offExchangeFlag: true
|
||||
trace_id: "alpaca:1",
|
||||
story_id: 1,
|
||||
provider: "alpaca",
|
||||
source: "Benzinga",
|
||||
headline: "TSLA rises",
|
||||
summary: "",
|
||||
content_html: "<p>TSLA rises</p>",
|
||||
url: "https://example.com/story",
|
||||
published_ts: 100,
|
||||
updated_ts: 100,
|
||||
provider_symbols: ["TSLA"],
|
||||
resolved_symbols: ["TSLA"],
|
||||
symbol_resolution: "provider"
|
||||
},
|
||||
watermark: cursor
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue