Jaspers Hub

jaspers / tradingview

pluginOfficialReviewed★ 0↓ 9

TradingView Chart: Shows TradingView's advanced chart widget in a frame, driven by panel state (symbol, interval, studies), reporting back the last quote.

2.4 KB
1import { definePlugin, defineView } from '@jaspers-ai/sdk'
2import { z } from 'zod'
3import { ChartView } from './ChartView'
4import { INTERVALS, MAX_COMPARE, MAX_STUDIES, RANGES, STUDIES, STYLES, summarize, WIDGET_ORIGIN } from './chart'
5import { INSTRUCTIONS } from './instructions'
6
7// TradingView's advanced chart widget as a view. TradingView draws it, with its own data, on its
8// own page in a frame, so there are no sources and no backend here: the state says which chart, and
9// the output is that and the quote the widget posts back. frames is what lets the view frame it.
10
11const StateSchema = z.object({
12 symbol: z
13 .string()
14 .min(1)
15 .describe(
16 'EXCHANGE:TICKER, like NASDAQ:AAPL, AMEX:SPY, BINANCE:BTCUSDT, FX:EURUSD. A bare US ticker works too, and so do the index, futures, commodity, and crypto names (S&P 500, SPX, NASDAQ 100, Dow, Russell 2000, VIX, DXY, US 10Y, gold, oil, ES, NQ, bitcoin), which resolve to the symbol TradingView charts them under.',
17 ),
18 interval: z.enum(INTERVALS).default('D').describe('Bar size: 1 to 240 minutes, D, W, or M.'),
19 range: z.enum(RANGES).nullable().optional().describe('How much history shows. When set, the widget picks the bar size for it; null clears it.'),
20 style: z.enum(STYLES).default('candles'),
21 studies: z.array(z.enum(STUDIES)).max(MAX_STUDIES).default([]),
22 compare: z
23 .array(z.string().min(1))
24 .max(MAX_COMPARE)
25 .nullable()
26 .optional()
27 .describe('Up to three symbols drawn over the main one in its pane, named the same way; null clears them.'),
28 extendedHours: z.boolean().nullable().optional().describe('Pre- and post-market bars, where the exchange has them; null or false is regular hours.'),
29})
30
31const QuoteSchema = z.object({
32 name: z.string(),
33 exchange: z.string().optional(),
34 description: z.string().optional(),
35 last: z.number(),
36 change: z.number().optional(),
37 changePercent: z.number().optional(),
38 volume: z.number().optional(),
39})
40
41const OutputSchema = z.object({
42 symbol: z.string(),
43 interval: z.enum(INTERVALS),
44 range: z.enum(RANGES).optional(),
45 style: z.enum(STYLES),
46 studies: z.array(z.enum(STUDIES)),
47 compare: z.array(z.string()).optional(),
48 extendedHours: z.boolean().optional(),
49 quote: QuoteSchema.optional(),
50})
51
52export default definePlugin({
53 id: 'tradingview',
54 frames: [WIDGET_ORIGIN],
55 views: {
56 chart: defineView(ChartView, {
57 title: 'Chart',
58 state: StateSchema,
59 output: OutputSchema,
60 instructions: INSTRUCTIONS,
61 summarize,
62 }),
63 },
64})