Jaspers Hub

biseroff / benzinga

pluginReviewed★ 0↓ 2

Benzinga Market Data: Fetches Benzinga news, analyst ratings, earnings, guidance, dividends, splits, IPO, and economic calendars via API, with a news list view.

5.3 KB
1import { defineSource } from '@jaspers-ai/sdk'
2import { z } from 'zod'
3import { HOST, benzingaGet, calendarParams, calendarRows, num, str } from './client'
4
5const tickers = z.string().optional().describe('Comma-separated tickers, like AAPL,MSFT.')
6const page = z.number().int().min(0).default(0).describe('Page number, from 0.')
7const pagesize = z.number().int().min(1).max(1000).default(100).describe('Rows per page, up to 1000.')
8const range = (back: number, ahead: number) => ({
9 date_from: z.string().optional().describe(`Start date YYYY-MM-DD. Default ${back} days ago.`),
10 date_to: z.string().optional().describe(`End date YYYY-MM-DD. Default ${ahead} days ahead.`),
11})
12const byKey = <T,>(key: (row: T) => string) => (a: T, b: T) => key(b).localeCompare(key(a))
13
14export const dividends = defineSource({
15 description:
16 'Benzinga dividends calendar, latest ex-date first. Default 30 days back to 30 ahead. Rows: ticker, name, ex_date, payable_date, record_date, declaration_date, dividend, dividend_prior, frequency (payments a year), yield, dividend_type, currency.',
17 hosts: [HOST],
18 input: z.object({ tickers, ...range(30, 30), page, pagesize }),
19 async run(args, ctx) {
20 const body = await benzingaGet(ctx, 'dividends', '/api/v2.1/calendar/dividends', calendarParams(args, 30, 30))
21 return calendarRows(body, 'dividends')
22 .map((r) => ({
23 ticker: str(r.ticker),
24 name: str(r.name),
25 ex_date: str(r.ex_dividend_date),
26 payable_date: str(r.payable_date),
27 record_date: str(r.record_date),
28 declaration_date: str(r.date),
29 dividend: num(r.dividend),
30 dividend_prior: num(r.dividend_prior),
31 frequency: num(r.frequency),
32 yield: num(r.dividend_yield),
33 dividend_type: str(r.dividend_type),
34 currency: str(r.currency),
35 }))
36 .sort(byKey((r) => r.ex_date ?? ''))
37 },
38})
39
40export const splits = defineSource({
41 description:
42 'Benzinga stock splits calendar, newest first. Default 90 days back to 30 ahead. Rows: date (announced), ticker, exchange, ratio, ex_date, record_date, distribution_date, optionable, importance.',
43 hosts: [HOST],
44 input: z.object({ tickers, ...range(90, 30), page, pagesize }),
45 async run(args, ctx) {
46 const body = await benzingaGet(ctx, 'splits', '/api/v2.1/calendar/splits', calendarParams(args, 90, 30))
47 return calendarRows(body, 'splits')
48 .map((r) => ({
49 date: str(r.date),
50 ticker: str(r.ticker),
51 exchange: str(r.exchange),
52 ratio: str(r.ratio),
53 ex_date: str(r.date_ex),
54 record_date: str(r.date_recorded),
55 distribution_date: str(r.date_distribution),
56 optionable: r.optionable === true || r.optionable === 'true',
57 importance: num(r.importance),
58 }))
59 .sort(byKey((r) => r.date ?? ''))
60 },
61})
62
63export const ipos = defineSource({
64 description:
65 'Benzinga IPO calendar, newest first. Default 14 days back to 30 ahead. Rows: date, time, ticker, name, exchange, pricing_date, price_min, price_max, price_open, deal_status, offering_shares, offering_value, lead_underwriters, insider_lockup_date.',
66 hosts: [HOST],
67 input: z.object({ tickers, ...range(14, 30), page, pagesize }),
68 async run(args, ctx) {
69 const body = await benzingaGet(ctx, 'ipos', '/api/v2.1/calendar/ipos', calendarParams(args, 14, 30))
70 return calendarRows(body, 'ipos')
71 .map((r) => ({
72 date: str(r.date),
73 time: str(r.time),
74 ticker: str(r.ticker),
75 name: str(r.name),
76 exchange: str(r.exchange),
77 pricing_date: str(r.pricing_date),
78 price_min: num(r.price_min),
79 price_max: num(r.price_max),
80 price_open: num(r.price_open),
81 deal_status: str(r.deal_status),
82 offering_shares: num(r.offering_shares),
83 offering_value: num(r.offering_value),
84 lead_underwriters: Array.isArray(r.lead_underwriters) ? r.lead_underwriters.join(', ') : str(r.lead_underwriters),
85 insider_lockup_date: str(r.insider_lockup_date),
86 }))
87 .sort(byKey((r) => `${r.date ?? ''}${r.time ?? ''}`))
88 },
89})
90
91export const economics = defineSource({
92 description:
93 'Benzinga economic calendar, newest first. Default 3 days back to 7 ahead. Rows: date, time, country, event_name, event_period, period_year, actual, consensus, prior (as published, with units), importance.',
94 hosts: [HOST],
95 input: z.object({
96 ...range(3, 7),
97 country: z.string().optional().describe('Three-letter country code, like USA, GBR, EUR.'),
98 importance: z.number().int().min(0).max(5).optional().describe('Minimum importance, 0 to 5.'),
99 page,
100 pagesize,
101 }),
102 async run(args, ctx) {
103 const body = await benzingaGet(ctx, 'economics', '/api/v2.1/calendar/economics', {
104 ...calendarParams({ ...args, tickers: undefined }, 3, 7),
105 'parameters[country]': args.country?.toUpperCase(),
106 'parameters[importance]': args.importance,
107 })
108 return calendarRows(body, 'economics')
109 .map((r) => ({
110 date: str(r.date),
111 time: str(r.time),
112 country: str(r.country),
113 event_name: str(r.event_name),
114 event_period: str(r.event_period),
115 period_year: num(r.period_year),
116 actual: str(r.actual),
117 consensus: str(r.consensus),
118 prior: str(r.prior),
119 importance: num(r.importance),
120 }))
121 .sort(byKey((r) => `${r.date ?? ''}${r.time ?? ''}`))
122 },
123})