import type { PluginModule } from "../plugin-module"; import { parseTickerListInput, formatTickerListInput } from "../../../tickers/list"; import { createTickerSurfacePaneTemplate } from "../shared/ticker-surface"; import { AnalystResearchView } from "./analyst-pane"; import { CorporateActionsView } from "./corporate-actions-pane"; import { EquityDiagnosticView } from "./equity-diagnostic-pane"; import { RelativeValuationPane } from "./relative-valuation-pane"; import { relativeValuationHeadless } from "./relative-valuation-headless"; import { analystResearchHeadless } from "./analyst-headless"; import { eventsHeadless } from "./events-headless"; import { earningsEstimatesHeadless } from "./headless"; export { analystResearchHeadless } from "./analyst-headless"; export { eventsHeadless } from "./events-headless"; export { earningsEstimatesHeadless } from "./headless"; function EarningsEstimatesPane(props: { focused: boolean; width: number; height: number }) { return ( ); } export const researchModule: PluginModule = { setup(ctx) { ctx.registerTickerResearchTab({ id: "analyst-research", name: "Analyst", order: 32, component: AnalystResearchView, instruments: ["equity"], }); ctx.registerTickerResearchTab({ id: "equity-diagnostic", name: "Diagnostic", order: 33, component: EquityDiagnosticView, instruments: ["equity"], }); ctx.registerTickerResearchTab({ id: "corporate-actions", name: "Events", order: 34, component: CorporateActionsView, instruments: ["equity", "fund"], }); }, panes: [ { id: "analyst-research", name: "Analyst Research", icon: "A", component: AnalystResearchView, defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 90, height: 28 }, tableExport: true, }, { id: "equity-diagnostic", name: "Equity Diagnostic", icon: "D", component: EquityDiagnosticView, defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 96, height: 30 }, }, { id: "corporate-actions", name: "Corporate Actions", icon: "E", component: CorporateActionsView, defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 104, height: 24 }, tableExport: true, headless: eventsHeadless, }, { id: "relative-valuation", name: "Relative Valuation", icon: "R", component: RelativeValuationPane, headless: relativeValuationHeadless, defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 104, height: 24 }, tableExport: true, }, { id: "earnings-estimates", name: "Earnings Estimates", icon: "E", component: EarningsEstimatesPane, defaultPosition: "right", defaultMode: "floating", defaultFloatingSize: { width: 104, height: 22 }, tableExport: true, }, ], paneTemplates: [ { ...createTickerSurfacePaneTemplate({ id: "analyst-research-pane", paneId: "analyst-research", label: "Analyst Research", description: "Price targets, recommendations, and recent analyst actions.", keywords: ["analyst", "research", "ratings", "target", "anr"], shortcut: "ANR", publicShare: true, }), headless: analystResearchHeadless, }, createTickerSurfacePaneTemplate({ id: "equity-diagnostic-pane", paneId: "equity-diagnostic", label: "Equity Diagnostic", description: "Red flags, anomalies, green flags, and watch items for one company, with cited evidence.", keywords: ["diagnostic", "diag", "red flags", "anomalies", "green flags", "review", "evidence"], shortcut: "DIAG", publicShare: true, }), createTickerSurfacePaneTemplate({ id: "corporate-actions-pane", paneId: "corporate-actions", label: "Corporate Actions", description: "Dividends, splits, reported earnings, and analyst estimates.", keywords: ["events", "corporate", "actions", "dividend", "split", "earnings", "estimate", "revenue", "evt"], shortcut: "EVT", publicShare: true, }), { ...createTickerSurfacePaneTemplate({ id: "earnings-estimates-pane", paneId: "earnings-estimates", label: "Earnings Estimates", description: "EPS and revenue estimates with reported earnings.", keywords: ["earnings", "estimates", "ee", "analyst", "eps", "revenue", "events"], shortcut: "EE", publicShare: true, }), headless: earningsEstimatesHeadless, }, { id: "relative-valuation-pane", headless: relativeValuationHeadless, paneId: "relative-valuation", label: "Relative Valuation", description: "Compare valuation and operating metrics across peers.", keywords: ["relative", "valuation", "comps", "peers", "rv"], shortcut: { prefix: "RV", argPlaceholder: "tickers", argKind: "ticker-list" }, canCreate: (context, options) => !!(options?.symbols?.length || options?.arg || context.activeTicker), createInstance: (context, options) => { let symbols: string[]; try { symbols = options?.symbols?.length ? options.symbols : parseTickerListInput(options?.arg ?? context.activeTicker ?? "", 12); } catch { return null; } return { title: `RV ${formatTickerListInput(symbols)}`, placement: "floating", settings: { symbols, symbolsText: formatTickerListInput(symbols) }, }; }, }, ], };