Benzinga Market Data: Fetches Benzinga news, analyst ratings, earnings, guidance, dividends, splits, IPO, and economic calendars via API, with a news list view.
| 1 | import { defineSource } from '@jaspers-ai/sdk' |
| 2 | import { z } from 'zod' |
| 3 | import { HOST, benzingaGet, calendarParams, calendarRows, num, str } from './client' |
| 4 | |
| 5 | const tickers = z.string().optional().describe('Comma-separated tickers, like AAPL,MSFT.') |
| 6 | const page = z.number().int().min(0).default(0).describe('Page number, from 0.') |
| 7 | const pagesize = z.number().int().min(1).max(1000).default(100).describe('Rows per page, up to 1000.') |
| 8 | |
| 9 | /** Newest date and time first. */ |
| 10 | const 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 | |
| 13 | export 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 | |
| 56 | export 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 | |
| 91 | export 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 | }) |