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.')
8
9/** Newest date and time first. */
10const newestFirst = (a: { date: string | null; time: string | null }, b: { date: string | null; time: string | null }) =>
11 `${b.date ?? ''}${b.time ?? ''}`.localeCompare(`${a.date ?? ''}${a.time ?? ''}`)
12
13export const ratings = defineSource({
14 description:
15 'Benzinga analyst ratings: upgrades, downgrades, initiations, price target changes. Default the last 30 days, newest first. Rows: date, time, ticker, name, analyst (firm), analyst_name, action_company, action_pt, rating_current, rating_prior, pt_current, pt_prior, importance, url.',
16 hosts: [HOST],
17 input: z.object({
18 tickers,
19 date_from: z.string().optional().describe('Start date YYYY-MM-DD. Default 30 days ago.'),
20 date_to: z.string().optional().describe('End date YYYY-MM-DD. Default today.'),
21 action: z
22 .string()
23 .optional()
24 .describe('Filter on action_company: Upgrades, Downgrades, Maintains, Initiates Coverage On, Reiterates, Terminates Coverage On, and the like.'),
25 importance: z.number().int().min(0).max(5).optional().describe('Minimum importance, 0 to 5.'),
26 page,
27 pagesize,
28 }),
29 async run(args, ctx) {
30 const body = await benzingaGet(ctx, 'ratings', '/api/v2.1/calendar/ratings', {
31 ...calendarParams(args, 30, 0),
32 'parameters[action]': args.action,
33 'parameters[importance]': args.importance,
34 })
35 return calendarRows(body, 'ratings')
36 .map((r) => ({
37 date: str(r.date),
38 time: str(r.time),
39 ticker: str(r.ticker),
40 name: str(r.name),
41 analyst: str(r.analyst),
42 analyst_name: str(r.analyst_name),
43 action_company: str(r.action_company),
44 action_pt: str(r.action_pt),
45 rating_current: str(r.rating_current),
46 rating_prior: str(r.rating_prior),
47 pt_current: num(r.pt_current),
48 pt_prior: num(r.pt_prior),
49 importance: num(r.importance),
50 url: str(r.url) ?? str(r.url_news),
51 }))
52 .sort(newestFirst)
53 },
54})
55
56export const earnings = defineSource({
57 description:
58 'Benzinga earnings calendar. Default 7 days back to 14 ahead. Rows: date, time, ticker, name, period, period_year, eps_est, eps, eps_prior, eps_surprise, revenue_est, revenue, revenue_prior, revenue_surprise, importance.',
59 hosts: [HOST],
60 input: z.object({
61 tickers,
62 date_from: z.string().optional().describe('Start date YYYY-MM-DD. Default 7 days ago.'),
63 date_to: z.string().optional().describe('End date YYYY-MM-DD. Default 14 days ahead.'),
64 page,
65 pagesize,
66 }),
67 async run(args, ctx) {
68 const body = await benzingaGet(ctx, 'earnings', '/api/v2.1/calendar/earnings', calendarParams(args, 7, 14))
69 return calendarRows(body, 'earnings')
70 .map((r) => ({
71 date: str(r.date),
72 time: str(r.time),
73 ticker: str(r.ticker),
74 name: str(r.name),
75 period: str(r.period),
76 period_year: num(r.period_year),
77 eps_est: num(r.eps_est),
78 eps: num(r.eps),
79 eps_prior: num(r.eps_prior),
80 eps_surprise: num(r.eps_surprise),
81 revenue_est: num(r.revenue_est),
82 revenue: num(r.revenue),
83 revenue_prior: num(r.revenue_prior),
84 revenue_surprise: num(r.revenue_surprise),
85 importance: num(r.importance),
86 }))
87 .sort(newestFirst)
88 },
89})
90
91export const guidance = defineSource({
92 description:
93 'Benzinga company guidance, newest first. Default the last 90 days. Rows: date, time, ticker, name, period, period_year, prelim, eps_guidance_min/max, eps_guidance_prior_min/max, eps_guidance_est, revenue_guidance_min/max, revenue_guidance_prior_min/max, revenue_guidance_est, importance.',
94 hosts: [HOST],
95 input: z.object({
96 tickers,
97 date_from: z.string().optional().describe('Start date YYYY-MM-DD. Default 90 days ago.'),
98 date_to: z.string().optional().describe('End date YYYY-MM-DD. Default today.'),
99 page,
100 pagesize,
101 }),
102 async run(args, ctx) {
103 const body = await benzingaGet(ctx, 'guidance', '/api/v2.1/calendar/guidance', calendarParams(args, 90, 0))
104 return calendarRows(body, 'guidance')
105 .map((r) => ({
106 date: str(r.date),
107 time: str(r.time),
108 ticker: str(r.ticker),
109 name: str(r.name),
110 period: str(r.period),
111 period_year: num(r.period_year),
112 prelim: str(r.prelim),
113 eps_guidance_min: num(r.eps_guidance_min),
114 eps_guidance_max: num(r.eps_guidance_max),
115 eps_guidance_prior_min: num(r.eps_guidance_prior_min),
116 eps_guidance_prior_max: num(r.eps_guidance_prior_max),
117 eps_guidance_est: num(r.eps_guidance_est),
118 revenue_guidance_min: num(r.revenue_guidance_min),
119 revenue_guidance_max: num(r.revenue_guidance_max),
120 revenue_guidance_prior_min: num(r.revenue_guidance_prior_min),
121 revenue_guidance_prior_max: num(r.revenue_guidance_prior_max),
122 revenue_guidance_est: num(r.revenue_guidance_est),
123 importance: num(r.importance),
124 }))
125 .sort(newestFirst)
126 },
127})