Jaspers Hub

biseroff / alpaca

pluginReviewed★ 0↓ 3

Alpaca: Alpaca market data, account, positions, and order management, with watchlist, account, and order-blotter views.

3.9 KB
1import { definePlugin, defineView } from '@jaspers-ai/sdk'
2import { z } from 'zod'
3import { cancelOrder, placeOrder } from './actions'
4import { optionBars, optionChain, optionLatestQuote, optionLatestTrade, optionSnapshots, optionTrades } from './options'
5import { stockBars, stockLatestQuote, stockLatestTrade, stockQuotes, stockSnapshots, stockTrades } from './stocks'
6import { account, assets, orders, positions } from './trading'
7import { AccountPanel } from './views/AccountPanel'
8import { Blotter } from './views/Blotter'
9import { Watchlist } from './views/Watchlist'
10
11export default definePlugin({
12 id: 'alpaca',
13 secrets: {
14 key_id: { label: 'Alpaca API key ID (paper account; also used for market data)' },
15 secret_key: { label: 'Alpaca API secret key (paper account; also used for market data)' },
16 live_key_id: { label: 'Alpaca LIVE account API key ID (only for live_account: true)' },
17 live_secret_key: { label: 'Alpaca LIVE account API secret key (only for live_account: true)' },
18 },
19 sources: {
20 'stock-bars': stockBars,
21 'stock-quotes': stockQuotes,
22 'stock-trades': stockTrades,
23 'stock-latest-quote': stockLatestQuote,
24 'stock-latest-trade': stockLatestTrade,
25 'stock-snapshots': stockSnapshots,
26 'option-bars': optionBars,
27 'option-trades': optionTrades,
28 'option-latest-quote': optionLatestQuote,
29 'option-latest-trade': optionLatestTrade,
30 'option-snapshots': optionSnapshots,
31 'option-chain': optionChain,
32 account,
33 positions,
34 orders,
35 assets,
36 'place-order': placeOrder,
37 'cancel-order': cancelOrder,
38 },
39 views: {
40 watchlist: defineView(Watchlist, {
41 title: 'Alpaca watchlist',
42 state: z.object({
43 symbols: z.array(z.string()).max(100).default(['AAPL', 'MSFT', 'NVDA']).describe('Stock symbols to show.'),
44 feed: z.enum(['iex', 'sip', 'delayed_sip']).default('iex').describe('Data feed.'),
45 }),
46 output: z.object({
47 symbols: z.array(z.string()),
48 count: z.number(),
49 rows: z.array(z.object({ symbol: z.string(), last: z.number().nullable(), change_pct: z.number().nullable() })),
50 }),
51 instructions:
52 'Latest Alpaca snapshots (last, bid, ask, change, change %, volume) for state.symbols, refreshed every 15 s. Set state.symbols and state.feed (iex free, sip paid).',
53 renders: [stockSnapshots],
54 summarize: (state, output) => `Alpaca watchlist: ${output.count ?? 0} of ${state.symbols?.length ?? 0} symbols`,
55 }),
56 account: defineView(AccountPanel, {
57 title: 'Alpaca account',
58 state: z.object({ live_account: z.boolean().default(false).describe('Show the LIVE account instead of paper.') }),
59 output: z.object({
60 mode: z.string(),
61 equity: z.number().nullable(),
62 cash: z.number().nullable(),
63 buying_power: z.number().nullable(),
64 day_pl: z.number().nullable(),
65 positions: z.number(),
66 }),
67 instructions:
68 'The Alpaca account summary and its positions, paper by default. Set state.live_account to true only when the user asks for the live account.',
69 renders: [account, positions],
70 summarize: (_state, output) => `Alpaca ${output.mode ?? 'paper'}: equity ${output.equity ?? '–'}, ${output.positions ?? 0} positions`,
71 }),
72 orders: defineView(Blotter, {
73 title: 'Alpaca orders',
74 state: z.object({
75 status: z.enum(['open', 'closed', 'all']).default('all'),
76 limit: z.number().int().min(1).max(500).default(50),
77 live_account: z.boolean().default(false).describe('Show the LIVE account instead of paper.'),
78 }),
79 output: z.object({ status: z.string(), count: z.number(), open: z.number() }),
80 instructions:
81 'An Alpaca order blotter, paper by default. Set state.status (open|closed|all) and state.limit. Its cancel buttons cancel only on the user\'s click and confirmation.',
82 renders: [orders],
83 summarize: (state, output) => `Alpaca orders (${state.status ?? 'all'}): ${output.count ?? 0}, ${output.open ?? 0} open`,
84 }),
85 },
86})