@huskly/schwab-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,385 @@
1
+ import { differenceInDays, format, parse, startOfYear } from "date-fns";
2
+ const SCHWAB_API_BASE_URL = "https://api.schwabapi.com";
3
+ /**
4
+ * Schwab Market Data and Trading API client.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { SchwabClient } from '@huskly/schwab-client';
9
+ *
10
+ * const client = new SchwabClient('your-access-token');
11
+ * const quotes = await client.getQuotes(['AAPL', 'GOOGL']);
12
+ * ```
13
+ */
14
+ export class SchwabClient {
15
+ accessToken;
16
+ /**
17
+ * Creates a new SchwabClient instance.
18
+ * @param accessToken - A valid Schwab API access token
19
+ */
20
+ constructor(accessToken) {
21
+ this.accessToken = accessToken;
22
+ if (!accessToken) {
23
+ throw new Error("Access token is required");
24
+ }
25
+ }
26
+ today() {
27
+ return new Date();
28
+ }
29
+ getRiskFreeRate(_date) {
30
+ // For simplicity, return a fixed risk-free rate of 2%
31
+ return Promise.resolve(0.02);
32
+ }
33
+ async getQuotes(symbols) {
34
+ const symbolsStr = symbols.map(encodeURIComponent).join(",");
35
+ return await this.makeApiRequest(`/marketdata/v1/quotes?symbols=${symbolsStr}`);
36
+ }
37
+ async getPriceHistory({ symbol, days, startDate, endDate = Date.now(), }) {
38
+ // If days is not provided but startDate and endDate are, calculate days from the date range
39
+ const effectiveDays = days ?? (startDate ? differenceInDays(endDate, startDate) : 30);
40
+ // For requests > 132 trading days (~6 months), use periodType "year"
41
+ // Otherwise use periodType "month" with appropriate period
42
+ const useYear = effectiveDays > 132;
43
+ const periodType = useYear ? "year" : "month";
44
+ const period = useYear
45
+ ? 1
46
+ : effectiveDays <= 22
47
+ ? 1
48
+ : effectiveDays <= 44
49
+ ? 2
50
+ : effectiveDays <= 66
51
+ ? 3
52
+ : 6;
53
+ const params = new URLSearchParams({
54
+ symbol,
55
+ periodType,
56
+ period: String(period),
57
+ frequencyType: "daily",
58
+ frequency: "1",
59
+ endDate: String(endDate),
60
+ });
61
+ if (startDate) {
62
+ params.append("startDate", String(startDate));
63
+ }
64
+ const data = await this.makeApiRequest(`/marketdata/v1/pricehistory?${params.toString()}`);
65
+ if (data.empty) {
66
+ return [];
67
+ }
68
+ return data.candles.sort((a, b) => a.datetime - b.datetime);
69
+ }
70
+ async getVixLevel() {
71
+ const quotes = await this.getQuotes(["$VIX"]);
72
+ const vixQuote = quotes["$VIX"];
73
+ return vixQuote?.quote.mark ?? vixQuote?.quote.lastPrice;
74
+ }
75
+ // fromDate and toDate are in "YYYY-MM-DD" format
76
+ async getAvailableExpiries(symbol, contractType, fromDate, toDate) {
77
+ const data = await this.makeApiRequest(`/marketdata/v1/chains?symbol=${encodeURIComponent(symbol)}&contractType=${contractType}&fromDate=${fromDate}&toDate=${toDate}`);
78
+ if (!data.putExpDateMap) {
79
+ return [];
80
+ }
81
+ const expiries = Object.keys(data.putExpDateMap).map((key) => {
82
+ // Key format is "2024-01-19:30" (date:DTE)
83
+ const dateStr = key.split(":")[0] ?? key;
84
+ return parse(dateStr, "yyyy-MM-dd", new Date());
85
+ });
86
+ return expiries.sort((a, b) => a.getTime() - b.getTime());
87
+ }
88
+ async getOptionChain(symbol, expiry) {
89
+ const expiryStr = format(expiry, "yyyy-MM-dd");
90
+ const data = await this.makeApiRequest(`/marketdata/v1/chains?symbol=${encodeURIComponent(symbol)}&fromDate=${expiryStr}&toDate=${expiryStr}`);
91
+ const options = [];
92
+ const processExpDateMap = (expDateMap, isCall) => {
93
+ if (!expDateMap)
94
+ return;
95
+ for (const dateKey of Object.keys(expDateMap)) {
96
+ const strikeMap = expDateMap[dateKey];
97
+ if (!strikeMap)
98
+ continue;
99
+ for (const strikeKey of Object.keys(strikeMap)) {
100
+ const contracts = strikeMap[strikeKey];
101
+ if (!contracts)
102
+ continue;
103
+ for (const contract of contracts) {
104
+ const expirationDate = new Date(contract.expirationDate);
105
+ options.push({
106
+ symbol: contract.symbol,
107
+ expiry: expirationDate,
108
+ strike: contract.strikePrice,
109
+ isCall,
110
+ bid: contract.bid > 0 ? contract.bid : null,
111
+ ask: contract.ask > 0 ? contract.ask : null,
112
+ mid: contract.mark,
113
+ delta: contract.delta,
114
+ });
115
+ }
116
+ }
117
+ }
118
+ };
119
+ processExpDateMap(data.callExpDateMap, true);
120
+ processExpDateMap(data.putExpDateMap, false);
121
+ return options;
122
+ }
123
+ async getOptionQuote(args) {
124
+ const { symbol, expiry, strike, type } = args;
125
+ const isCall = type === "call";
126
+ const chain = await this.getOptionChain(symbol, expiry);
127
+ const match = chain.find((o) => o.strike === strike && o.isCall === isCall);
128
+ return match ?? null;
129
+ }
130
+ async getAccountEquity() {
131
+ // This assumes there is exactly one account connected, which is the one we want.
132
+ const [account] = await this.makeApiRequest("/trader/v1/accounts?fields=positions");
133
+ if (!account) {
134
+ throw new Error("No Schwab account found");
135
+ }
136
+ return account.securitiesAccount.currentBalances.liquidationValue;
137
+ }
138
+ async getAccountBalances() {
139
+ const [account] = await this.makeApiRequest("/trader/v1/accounts?fields=positions");
140
+ if (!account) {
141
+ throw new Error("No Schwab account found");
142
+ }
143
+ const balances = account.securitiesAccount.currentBalances;
144
+ return {
145
+ liquidationValue: balances.liquidationValue,
146
+ cashBalance: balances.cashBalance,
147
+ availableFunds: balances.availableFunds,
148
+ buyingPower: balances.buyingPower,
149
+ equity: balances.equity,
150
+ };
151
+ }
152
+ async getPositions(symbol) {
153
+ const accounts = await this.makeApiRequest("/trader/v1/accounts?fields=positions");
154
+ const allPositions = [];
155
+ for (const account of accounts) {
156
+ allPositions.push(...account.securitiesAccount.positions);
157
+ }
158
+ if (symbol) {
159
+ const upperSymbol = symbol.toUpperCase();
160
+ return allPositions.filter((pos) => {
161
+ const posSymbol = pos.instrument.symbol.toUpperCase();
162
+ const underlying = pos.instrument.underlyingSymbol?.toUpperCase();
163
+ return posSymbol.startsWith(upperSymbol) || underlying === upperSymbol;
164
+ });
165
+ }
166
+ return allPositions;
167
+ }
168
+ async getExistingSpreads(symbol) {
169
+ const accounts = await this.makeApiRequest("/trader/v1/accounts?fields=positions");
170
+ const spreads = [];
171
+ for (const account of accounts) {
172
+ const positions = account.securitiesAccount.positions;
173
+ const optionPositions = positions.filter((pos) => pos.instrument.assetType === "OPTION" && pos.instrument.underlyingSymbol === symbol);
174
+ // Group by expiry to find spreads
175
+ const byExpiry = new Map();
176
+ for (const pos of optionPositions) {
177
+ const optionSymbol = pos.instrument.symbol;
178
+ // Parse option symbol format: SPX 241220P05900000
179
+ // Symbol structure: underlying + expiry (YYMMDD) + P/C + strike
180
+ const match = /^(\w+)\s*(\d{6})([PC])(\d+)$/.exec(optionSymbol);
181
+ if (!match)
182
+ continue;
183
+ const expiryKey = match[2];
184
+ if (!expiryKey)
185
+ continue;
186
+ const existing = byExpiry.get(expiryKey) ?? [];
187
+ existing.push(pos);
188
+ byExpiry.set(expiryKey, existing);
189
+ }
190
+ // Find put spreads (short put + long put at lower strike)
191
+ for (const [expiryKey, expiryPositions] of byExpiry) {
192
+ const puts = expiryPositions.filter((p) => p.instrument.symbol.includes("P"));
193
+ const shortPuts = puts.filter((p) => p.shortQuantity > 0);
194
+ const longPuts = puts.filter((p) => p.longQuantity > 0);
195
+ for (const shortPut of shortPuts) {
196
+ const shortMatch = /(\d{6})P(\d+)$/.exec(shortPut.instrument.symbol);
197
+ if (!shortMatch?.[2])
198
+ continue;
199
+ const shortStrike = parseInt(shortMatch[2]) / 1000;
200
+ // Find corresponding long put at lower strike
201
+ for (const longPut of longPuts) {
202
+ const longMatch = /(\d{6})P(\d+)$/.exec(longPut.instrument.symbol);
203
+ if (!longMatch?.[2])
204
+ continue;
205
+ const longStrike = parseInt(longMatch[2]) / 1000;
206
+ if (longStrike < shortStrike) {
207
+ const quantity = Math.min(shortPut.shortQuantity, longPut.longQuantity);
208
+ const width = shortStrike - longStrike;
209
+ const credit = shortPut.averagePrice - longPut.averagePrice;
210
+ // Parse expiry date from YYMMDD format
211
+ const year = 2000 + parseInt(expiryKey.slice(0, 2));
212
+ const month = parseInt(expiryKey.slice(2, 4)) - 1;
213
+ const day = parseInt(expiryKey.slice(4, 6));
214
+ const expiry = new Date(year, month, day);
215
+ spreads.push({
216
+ underlying: symbol,
217
+ expiry,
218
+ shortStrike,
219
+ longStrike,
220
+ credit,
221
+ quantity,
222
+ theoreticalMaxLossPts: width - credit,
223
+ plannedLossPts: credit * 2, // stop at 2x credit
224
+ });
225
+ }
226
+ }
227
+ }
228
+ }
229
+ }
230
+ return spreads;
231
+ }
232
+ async fetchAccountNumbers() {
233
+ const accountNumbers = await this.makeApiRequest("/trader/v1/accounts/accountNumbers");
234
+ return accountNumbers;
235
+ }
236
+ async fetchTransactionHistory(startDate = startOfYear(this.today()), endDate = this.today()) {
237
+ const accountHashes = await this.fetchAccountNumbers();
238
+ const histories = await Promise.all(accountHashes.map(({ hashValue }) => this.fetchAccountTransactionHistory(hashValue, startDate, endDate)));
239
+ return accountHashes.map((account, index) => ({
240
+ accountNumber: account.accountNumber,
241
+ transactions: histories[index] ?? [],
242
+ }));
243
+ }
244
+ async fetchAccountTransactionHistory(accountHash, startDate = startOfYear(this.today()), endDate = this.today()) {
245
+ if (!accountHash) {
246
+ throw new Error("Account hash is required to fetch transaction history");
247
+ }
248
+ // Use toISOString() to properly convert local time to UTC with Z suffix
249
+ const formattedStartDate = startDate.toISOString();
250
+ const formattedEndDate = endDate.toISOString();
251
+ return await this.makeApiRequest(`/trader/v1/accounts/${accountHash}/transactions?startDate=${formattedStartDate}&endDate=${formattedEndDate}`);
252
+ }
253
+ async fetchOrders(options) {
254
+ const accountHashes = await this.fetchAccountNumbers();
255
+ const ordersPerAccount = await Promise.all(accountHashes.map(({ hashValue }) => this.fetchAccountOrders(hashValue, options)));
256
+ return accountHashes.map((account, index) => ({
257
+ accountNumber: account.accountNumber,
258
+ orders: ordersPerAccount[index] ?? [],
259
+ }));
260
+ }
261
+ async fetchAccountOrders(accountHash, options) {
262
+ if (!accountHash) {
263
+ throw new Error("Account hash is required to fetch orders");
264
+ }
265
+ // Use toISOString() to properly convert local time to UTC with Z suffix
266
+ const formattedFromTime = options.fromEnteredTime.toISOString();
267
+ const formattedToTime = options.toEnteredTime.toISOString();
268
+ const params = new URLSearchParams({
269
+ fromEnteredTime: formattedFromTime,
270
+ toEnteredTime: formattedToTime,
271
+ });
272
+ if (options.maxResults) {
273
+ params.append("maxResults", String(options.maxResults));
274
+ }
275
+ if (options.status) {
276
+ params.append("status", options.status);
277
+ }
278
+ return await this.makeApiRequest(`/trader/v1/accounts/${accountHash}/orders?${params.toString()}`);
279
+ }
280
+ /**
281
+ * Place an order for a specific account.
282
+ * Returns the order ID from the Location header on success.
283
+ */
284
+ async placeOrder(accountHash, order) {
285
+ if (!accountHash) {
286
+ throw new Error("Account hash is required to place an order");
287
+ }
288
+ const url = `${SCHWAB_API_BASE_URL}/trader/v1/accounts/${accountHash}/orders`;
289
+ const response = await fetch(url, {
290
+ method: "POST",
291
+ headers: {
292
+ Authorization: `Bearer ${this.accessToken}`,
293
+ "Content-Type": "application/json",
294
+ },
295
+ body: JSON.stringify(order),
296
+ });
297
+ if (!response.ok) {
298
+ const errorBody = await response.text();
299
+ throw new Error(`Failed to place order: ${String(response.status)} ${response.statusText} - ${errorBody}`);
300
+ }
301
+ // Schwab returns 201 Created with Location header containing the order URL
302
+ const locationHeader = response.headers.get("Location");
303
+ const orderId = locationHeader?.split("/").pop() ?? "unknown";
304
+ return { orderId };
305
+ }
306
+ async getUserPreference() {
307
+ return await this.makeApiRequest("/trader/v1/userPreference");
308
+ }
309
+ /**
310
+ * Search for instruments by symbol or description.
311
+ * @param symbol - The search term (symbol or description fragment)
312
+ * @param projection - The type of search to perform
313
+ * @returns Array of matching instruments
314
+ */
315
+ async searchInstruments(symbol, projection) {
316
+ const params = new URLSearchParams({
317
+ symbol: symbol,
318
+ projection: projection,
319
+ });
320
+ const response = await this.makeApiRequest(`/marketdata/v1/instruments?${params.toString()}`);
321
+ // The API returns instruments as an object keyed by symbol, convert to array
322
+ return Object.values(response.instruments ?? {});
323
+ }
324
+ /**
325
+ * Get top 10 movers for a specific index.
326
+ * @param symbolId - Index symbol ($DJI, $COMPX, $SPX, NYSE, NASDAQ, etc.)
327
+ * @param sort - Sort by VOLUME, TRADES, PERCENT_CHANGE_UP, or PERCENT_CHANGE_DOWN
328
+ * @param frequency - Frequency in minutes (0, 1, 5, 10, 30, 60). Default is 0.
329
+ * @returns List of top movers
330
+ */
331
+ async getMovers(symbolId, sort, frequency) {
332
+ const params = new URLSearchParams();
333
+ if (sort) {
334
+ params.append("sort", sort);
335
+ }
336
+ if (frequency !== undefined) {
337
+ params.append("frequency", String(frequency));
338
+ }
339
+ const queryString = params.toString();
340
+ const url = `/marketdata/v1/movers/${encodeURIComponent(symbolId)}${queryString ? `?${queryString}` : ""}`;
341
+ return await this.makeApiRequest(url);
342
+ }
343
+ headersToRecord(headers) {
344
+ const result = {};
345
+ if (!headers)
346
+ return result;
347
+ if (headers instanceof Headers) {
348
+ headers.forEach((value, key) => {
349
+ result[key] = value;
350
+ });
351
+ }
352
+ else if (Array.isArray(headers)) {
353
+ for (const [k, v] of headers) {
354
+ if (k && v) {
355
+ result[k] = v;
356
+ }
357
+ }
358
+ }
359
+ else {
360
+ Object.assign(result, headers);
361
+ }
362
+ return result;
363
+ }
364
+ async makeApiRequest(endpoint, options = {}) {
365
+ const existingHeaders = this.headersToRecord(options.headers);
366
+ const normalizedEndpoint = endpoint.startsWith("/") ? endpoint.slice(1) : endpoint;
367
+ const url = `${SCHWAB_API_BASE_URL}/${normalizedEndpoint}`;
368
+ const response = await fetch(url, {
369
+ ...options,
370
+ headers: {
371
+ ...existingHeaders,
372
+ Authorization: `Bearer ${this.accessToken}`,
373
+ },
374
+ });
375
+ if (!response.ok) {
376
+ if (response.status === 401) {
377
+ throw new Error("Unauthorized - access token may be expired or invalid");
378
+ }
379
+ throw new Error(`Failed to fetch ${endpoint}: ${response.statusText}`);
380
+ }
381
+ const responseBody = await response.json();
382
+ return responseBody;
383
+ }
384
+ }
385
+ //# sourceMappingURL=schwabClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schwabClient.js","sourceRoot":"","sources":["../src/schwabClient.ts"],"names":[],"mappings":"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"}