import { defineSource } from '@jaspers-ai/sdk' import { z } from 'zod' import { HOST, benzingaGet, calendarParams, calendarRows, num, str } from './client' const tickers = z.string().optional().describe('Comma-separated tickers, like AAPL,MSFT.') const page = z.number().int().min(0).default(0).describe('Page number, from 0.') const pagesize = z.number().int().min(1).max(1000).default(100).describe('Rows per page, up to 1000.') const range = (back: number, ahead: number) => ({ date_from: z.string().optional().describe(`Start date YYYY-MM-DD. Default ${back} days ago.`), date_to: z.string().optional().describe(`End date YYYY-MM-DD. Default ${ahead} days ahead.`), }) const byKey = (key: (row: T) => string) => (a: T, b: T) => key(b).localeCompare(key(a)) export const dividends = defineSource({ description: '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.', hosts: [HOST], input: z.object({ tickers, ...range(30, 30), page, pagesize }), async run(args, ctx) { const body = await benzingaGet(ctx, 'dividends', '/api/v2.1/calendar/dividends', calendarParams(args, 30, 30)) return calendarRows(body, 'dividends') .map((r) => ({ ticker: str(r.ticker), name: str(r.name), ex_date: str(r.ex_dividend_date), payable_date: str(r.payable_date), record_date: str(r.record_date), declaration_date: str(r.date), dividend: num(r.dividend), dividend_prior: num(r.dividend_prior), frequency: num(r.frequency), yield: num(r.dividend_yield), dividend_type: str(r.dividend_type), currency: str(r.currency), })) .sort(byKey((r) => r.ex_date ?? '')) }, }) export const splits = defineSource({ description: '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.', hosts: [HOST], input: z.object({ tickers, ...range(90, 30), page, pagesize }), async run(args, ctx) { const body = await benzingaGet(ctx, 'splits', '/api/v2.1/calendar/splits', calendarParams(args, 90, 30)) return calendarRows(body, 'splits') .map((r) => ({ date: str(r.date), ticker: str(r.ticker), exchange: str(r.exchange), ratio: str(r.ratio), ex_date: str(r.date_ex), record_date: str(r.date_recorded), distribution_date: str(r.date_distribution), optionable: r.optionable === true || r.optionable === 'true', importance: num(r.importance), })) .sort(byKey((r) => r.date ?? '')) }, }) export const ipos = defineSource({ description: '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.', hosts: [HOST], input: z.object({ tickers, ...range(14, 30), page, pagesize }), async run(args, ctx) { const body = await benzingaGet(ctx, 'ipos', '/api/v2.1/calendar/ipos', calendarParams(args, 14, 30)) return calendarRows(body, 'ipos') .map((r) => ({ date: str(r.date), time: str(r.time), ticker: str(r.ticker), name: str(r.name), exchange: str(r.exchange), pricing_date: str(r.pricing_date), price_min: num(r.price_min), price_max: num(r.price_max), price_open: num(r.price_open), deal_status: str(r.deal_status), offering_shares: num(r.offering_shares), offering_value: num(r.offering_value), lead_underwriters: Array.isArray(r.lead_underwriters) ? r.lead_underwriters.join(', ') : str(r.lead_underwriters), insider_lockup_date: str(r.insider_lockup_date), })) .sort(byKey((r) => `${r.date ?? ''}${r.time ?? ''}`)) }, }) export const economics = defineSource({ description: '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.', hosts: [HOST], input: z.object({ ...range(3, 7), country: z.string().optional().describe('Three-letter country code, like USA, GBR, EUR.'), importance: z.number().int().min(0).max(5).optional().describe('Minimum importance, 0 to 5.'), page, pagesize, }), async run(args, ctx) { const body = await benzingaGet(ctx, 'economics', '/api/v2.1/calendar/economics', { ...calendarParams({ ...args, tickers: undefined }, 3, 7), 'parameters[country]': args.country?.toUpperCase(), 'parameters[importance]': args.importance, }) return calendarRows(body, 'economics') .map((r) => ({ date: str(r.date), time: str(r.time), country: str(r.country), event_name: str(r.event_name), event_period: str(r.event_period), period_year: num(r.period_year), actual: str(r.actual), consensus: str(r.consensus), prior: str(r.prior), importance: num(r.importance), })) .sort(byKey((r) => `${r.date ?? ''}${r.time ?? ''}`)) }, })