Jaspers Hub

biseroff / massive

pluginReviewed★ 0↓ 3

Massive Market Data (Polygon.io): Market data plugin wrapping the Polygon.io/Massive REST API: bars, snapshots, options, news, financials, indicators, and four chart/watchlist views.

2.1 KB
1import { defineSource } from '@jaspers-ai/sdk'
2import { z } from 'zod'
3import { HOSTS, baseField, list, upper, type Row } from './client'
4
5// Fundamentals from SEC filings: one row per period, every income statement, balance sheet, cash flow,
6// and comprehensive income line as a column like income_statement_revenues.
7
8export const financials = defineSource({
9 description:
10 'Financial statements for a ticker, newest period first: one row per period (fiscal year, period, dates, filing date) with every income statement, balance sheet, and cash flow line as a column, like income_statement_revenues, balance_sheet_assets, cash_flow_statement_net_cash_flow_from_operating_activities.',
11 hosts: HOSTS,
12 input: z.object({
13 ticker: z.string().min(1).describe('The ticker, like AAPL.'),
14 timeframe: z.enum(['annual', 'quarterly', 'ttm']).default('quarterly').describe('annual, quarterly, or ttm (trailing twelve months).'),
15 limit: z.number().int().min(1).max(100).default(8).describe('How many periods.'),
16 base: baseField,
17 }),
18 async run(args, ctx) {
19 const ticker = upper(args.ticker)
20 const res = await list(
21 ctx,
22 args.base,
23 '/vX/reference/financials',
24 { ticker, timeframe: args.timeframe, order: 'desc', sort: 'period_of_report_date', limit: Math.min(args.limit, 100) },
25 args.limit,
26 )
27 const rows = res.rows.map((p) => {
28 const row: Row = {
29 ticker,
30 company_name: p.company_name ?? null,
31 fiscal_year: p.fiscal_year ?? null,
32 fiscal_period: p.fiscal_period ?? null,
33 timeframe: p.timeframe ?? null,
34 start_date: p.start_date ?? null,
35 end_date: p.end_date ?? null,
36 filing_date: p.filing_date ?? null,
37 }
38 // Each section is { line: { value, unit, label, order } }: keep the values, one column a line.
39 for (const [section, lines] of Object.entries((p.financials ?? {}) as Record<string, any>))
40 for (const [line, item] of Object.entries((lines ?? {}) as Record<string, any>))
41 row[`${section}_${line}`] = typeof item?.value === 'number' ? item.value : null
42 return row
43 })
44 return { rows, more: res.more }
45 },
46})